diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..4955e3a --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,9 @@ +The MIT License (MIT) + +Copyright (c) 2023 + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index e0fb81c..9523a73 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,12 @@ # LiveViewEvents +![Elixir CI](https://github.com/DockYard/live_view_events/actions/workflows/elixir-ci.yml/badge.svg) + LiveViewEvents provides a set of tools to send events between components. ## Installation -If [available in Hex](https://hex.pm/docs/publish), the package can be installed -by adding `live_view_events` to your list of dependencies in `mix.exs`: +Add `live_view_events` to your list of dependencies in `mix.exs` like: ```elixir def deps do @@ -15,11 +16,109 @@ def deps do end ``` -Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) -and published on [HexDocs](https://hexdocs.pm). Once published, the docs can -be found at . - ## Usage -TBD +Add `use LiveViewEvents` whenever you want to use any of the features of the libraries. + +### Sending events to LiveView components + +You can send events to LiveView components by using `notify_to/2` or `notify_to/3` (the only +difference being that the latter sends some extra params). These functions accept a target as +first argument and a message name as second. Targets can be any of: + + - `:self` to send to `self()`. + - A PID. + - A tuple of the form `{Module, "id"}` to send a message to a `LiveView.Component` in the same process. + - A tuple of the form `{pid, Module, "id"}` to send a message to a `LiveView.Component` in a different process. + +You an handle these messages on the `handle_info/2` callback on +your LiveView components. For being able to do so, you need to +use the `handle_info_or_assign/2` macro on the `update/3` callback of your component. + +## Example + + +In our view, we are going to have two components. The first one is a `Sender` +that can send an event to whatever is being passed. Let's dig into the +implementation: + +```elixir +defmodule MyAppWeb.Components.Sender do + use MyAppWeb, :live_component + use LiveViewEvents + + def mount(socket) do + socket = assign(socket, :notify_to, :self) + + {:ok, socket} + end + + def render(assigns) do + ~H[] + end + + def handle_event("clicked", _params, socket) do + notify_to(socket.assigns.notify_to, :sender_event, :rand.uniform(100)) + {:noreply, socket} + end +end +``` + +This component will send a `:sender_event` message to whatever we pass to the `notify_to` +attribute. It sends a random number between 0 and up to 100 as parameter. + +Let's dig into the receiver: + +```elixir +defmodule MyAppWeb.Components.Receiver do + use MyAppWeb, :live_component + use LiveViewEvents + + def mount(socket) do + socket = assign(socket, :messages, []) + + {:ok, socket} + end + + def update(assigns, socket) do + socket = handle_info_or_assign(socket, assigns) + + {:ok, socket} + end + + def render(assigns), + do: ~H[] + + def handle_info({:sender_event, num}, socket) do + {:noreply, update(socket, :messages, &[num | &1])} + end +end +``` + +This component will receive messages and handle them in `handle_info/2` because +it is using `handle_info_or_assign/2` in their `LiveComponent.update/2`. +It will add the received messages to `socket.assigns.messages` and display +them. As the reader can see, it is pattern matching against `:sender_event` messages. +When `notify_to/3` is used, the message sent is a tuple containing the event name +as first element, and the params as second the second element. + +Finally, let's take a look at what the live view template would need to look like +for this to work: + +```heex +
+ <.live_component + module={MyAppWeb.Components.Sender} + id="sender" + notify_to={{MyAppWeb.Components.Receiver, "receiver"}} + /> + <.live_component module={MyAppWeb.Components.Receiver} id="receiver" /> +
+``` +In this template, we set `notify_to` to the tuple `{MyAppWeb.Components.Receiver, "receiver"}`. +The first element of the tuple is the live component module and the second is the id. +Optionally, the tuple can contain an extra first element that needs to be a PID. Though +this might not be useful in the application code (there are way better ways to send events +between processes), it is quite useful when testing. When testing a `LiveView` +it creates a new process for it. Its PID can be accessed through `view.pid`. \ No newline at end of file diff --git a/lib/live_view_events.ex b/lib/live_view_events.ex index 1efcf0a..facbc76 100644 --- a/lib/live_view_events.ex +++ b/lib/live_view_events.ex @@ -1,6 +1,9 @@ defmodule LiveViewEvents do @moduledoc """ - Documentation for `LiveViewEvents`. + Add `use LiveViewEvents` to the module you want to use any + of the features of `LiveViewEvents` in. + + For more info about sending and receiving events, see `LiveViewEvents.Notify`. """ defmacro __using__(_opts) do diff --git a/lib/live_view_events/notify.ex b/lib/live_view_events/notify.ex index 9ae452f..aa4ef81 100644 --- a/lib/live_view_events/notify.ex +++ b/lib/live_view_events/notify.ex @@ -1,5 +1,88 @@ defmodule LiveViewEvents.Notify do - @moduledoc false + @moduledoc """ + Functions to send messages in the server including to live components + and handle them. + + ## Example + + In our view, we are going to have two components. The first one is a `Sender` + that can send an event to whatever is being passed. Let's dig into the + implementation: + + defmodule MyAppWeb.Components.Sender do + use MyAppWeb, :live_component + use LiveViewEvents + + def mount(socket) do + socket = assign(socket, :notify_to, :self) + + {:ok, socket} + end + + def render(assigns) do + ~H[] + end + + def handle_event("clicked", _params, socket) do + notify_to(socket.assigns.notify_to, :sender_event, :rand.uniform(100)) + {:noreply, socket} + end + end + + This component will send a `:sender_event` message to whatever we pass to the `notify_to` + attribute. It sends a random number between 0 and up to 100 as parameter. + + Let's dig into the receiver: + + defmodule MyAppWeb.Components.Receiver do + use MyAppWeb, :live_component + use LiveViewEvents + + def mount(socket) do + socket = assign(socket, :messages, []) + + {:ok, socket} + end + + def update(assigns, socket) do + socket = handle_info_or_assign(socket, assigns) + + {:ok, socket} + end + + def render(assigns), do: ~H[] + + def handle_info({:sender_event, num}, socket) do + {:noreply, update(socket, :messages, &[num | &1])} + end + end + + This component will receive messages and handle them in `handle_info/2` because + it is using `handle_info_or_assign/2` in their [`LiveComponent.update/2`](`c:Phoenix.LiveComponent.update/2`). + It will add the received messages to `socket.assigns.messages` and display + them. As the reader can see, it is pattern matching against `:sender_event` messages. + When `notify_to/3` is used, the message sent is a tuple containing the event name + as first element, and the params as second the second element. + + Finally, let's take a look at what the live view template would need to look like + for this to work: + +
+ <.live_component + module={MyAppWeb.Components.Sender} + id="sender" + notify_to={{MyAppWeb.Components.Receiver, "receiver"}} + /> + <.live_component module={MyAppWeb.Components.Receiver} id="receiver" /> +
+ + In this template, we set `notify_to` to the tuple `{MyAppWeb.Components.Receiver, "receiver"}`. + The first element of the tuple is the live component module and the second is the id. + Optionally, the tuple can contain an extra first element that needs to be a PID. Though + this might not be useful in the application code (there are way better ways to send events + between processes), it is quite useful when testing. When testing a [`LiveView`](`Phoenix.LiveView`), + it creates a new process for it. Its PID can be accessed through `view.pid`. + """ @assign_name_for_event "__live_view_events__assign_event__" @@ -22,14 +105,15 @@ defmodule LiveViewEvents.Notify do ## Why using `c:Phoenix.LiveView.handle_info/2` in components? In one word: consistency. Messages coming from the client are - handled by `c:Phoenix.LiveView.handle_event/3` or by - `c:Phoenix.LiveComponent.handle_event/3`. For messages sent from - the server are currently being handled by `c:Phoenix.LiveView.handle_info/2` - in live views, with not official way to do this but the hack this - library is based on. - - The hack is basically send an update with `Phoenix.LiveView.send_update/3` - and handle it in `c:Phoenix.LiveComponent.update/2` + handled by [LiveView.handle_event/3](`c:Phoenix.LiveView.handle_event/3`) + in live views or by [`LiveComponent.handle_event/3`](`c:Phoenix.LiveComponent.handle_event/3`) + in live components. + Messages sent from the server are currently being handled by + [`LiveView.handle_info/2`](`c:Phoenix.LiveView.handle_info/2`) in live views, + with no official way to do this but the __hack__ this library is based on. + + The hack is basically send an update with [`LiveView.send_update/3`](`Phoenix.LiveView.send_update/3`) + and handle it in [`LiveComponent.update/2`](`c:Phoenix.LiveComponent.update/2`). """ defmacro handle_info_or_assign(socket, assigns) do quote do @@ -67,7 +151,8 @@ defmodule LiveViewEvents.Notify do - `:self` to send to `self()`. - A PID. - - A tuple of the form `{Module, "id"}` to send a message to a LiveView component. + - A tuple of the form `{Module, "id"}` to send a message to a [`LiveView.Component`](`Phoenix.LiveView.Component`) in the same process. + - A tuple of the form `{pid, Module, "id"}` to send a message to a [`LiveView.Component`](`Phoenix.LiveView.Component`) in a different process. """ def notify_to(:self, message), do: notify_to(self(), message) def notify_to(pid, message) when is_pid(pid), do: send(pid, message) diff --git a/mix.exs b/mix.exs index edddf95..64f2b40 100644 --- a/mix.exs +++ b/mix.exs @@ -1,13 +1,19 @@ defmodule LiveViewEvents.MixProject do use Mix.Project + @source_url "https://github.com/DockYard/live_view_events" + @version "0.1.0" + def project do [ app: :live_view_events, - version: "0.1.0", + version: @version, elixir: "~> 1.14", start_permanent: Mix.env() == :prod, - deps: deps() + deps: deps(), + docs: docs(), + license: "MIT", + package: package() ] end @@ -18,6 +24,26 @@ defmodule LiveViewEvents.MixProject do ] end + def docs do + [ + extras: [{:"README.md", [title: "Overview"]}], + main: "readme", + source_url: @source_url, + source_ref: "v#{@version}" + ] + end + + def package do + [ + maintainers: ["Sergio Arbeo"], + licenses: ["MIT"], + links: %{"GitHub" => @source_url}, + files: ~w(lib LICENSE.md mix.exs README.md), + description: + "A library to unify and simplify sending messages between components and views in the server for Phoenix LiveView." + ] + end + # Run "mix help deps" to learn about dependencies. defp deps do [ diff --git a/test_app/.gitignore b/test_app/.gitignore index 89f67c1..04fec43 100644 --- a/test_app/.gitignore +++ b/test_app/.gitignore @@ -25,3 +25,13 @@ erl_crash.dump # Ignore package tarball (built via "mix hex.build"). test_app-*.tar +# Ignore assets that are produced by build tools. +/priv/static/assets/ + +# Ignore digested assets cache. +/priv/static/cache_manifest.json + +# In case you use Node.js/npm, you want to ignore these. +npm-debug.log +/assets/node_modules/ + diff --git a/test_app/assets/css/app.css b/test_app/assets/css/app.css new file mode 100644 index 0000000..378c8f9 --- /dev/null +++ b/test_app/assets/css/app.css @@ -0,0 +1,5 @@ +@import "tailwindcss/base"; +@import "tailwindcss/components"; +@import "tailwindcss/utilities"; + +/* This file is for your main application CSS */ diff --git a/test_app/assets/js/app.js b/test_app/assets/js/app.js new file mode 100644 index 0000000..df0cdd9 --- /dev/null +++ b/test_app/assets/js/app.js @@ -0,0 +1,41 @@ +// If you want to use Phoenix channels, run `mix help phx.gen.channel` +// to get started and then uncomment the line below. +// import "./user_socket.js" + +// You can include dependencies in two ways. +// +// The simplest option is to put them in assets/vendor and +// import them using relative paths: +// +// import "../vendor/some-package.js" +// +// Alternatively, you can `npm install some-package --prefix assets` and import +// them using a path starting with the package name: +// +// import "some-package" +// + +// Include phoenix_html to handle method=PUT/DELETE in forms and buttons. +import "phoenix_html" +// Establish Phoenix Socket and LiveView configuration. +import {Socket} from "phoenix" +import {LiveSocket} from "phoenix_live_view" +import topbar from "../vendor/topbar" + +let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content") +let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}}) + +// Show progress bar on live navigation and form submits +topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"}) +window.addEventListener("phx:page-loading-start", _info => topbar.show(300)) +window.addEventListener("phx:page-loading-stop", _info => topbar.hide()) + +// connect if there are any LiveViews on the page +liveSocket.connect() + +// expose liveSocket on window for web console debug logs and latency simulation: +// >> liveSocket.enableDebug() +// >> liveSocket.enableLatencySim(1000) // enabled for duration of browser session +// >> liveSocket.disableLatencySim() +window.liveSocket = liveSocket + diff --git a/test_app/assets/tailwind.config.js b/test_app/assets/tailwind.config.js new file mode 100644 index 0000000..856af57 --- /dev/null +++ b/test_app/assets/tailwind.config.js @@ -0,0 +1,68 @@ +// See the Tailwind configuration guide for advanced usage +// https://tailwindcss.com/docs/configuration + +const plugin = require("tailwindcss/plugin") +const fs = require("fs") +const path = require("path") + +module.exports = { + content: [ + "./js/**/*.js", + "../lib/*_web.ex", + "../lib/*_web/**/*.*ex" + ], + theme: { + extend: { + colors: { + brand: "#FD4F00", + } + }, + }, + plugins: [ + require("@tailwindcss/forms"), + // Allows prefixing tailwind classes with LiveView classes to add rules + // only when LiveView classes are applied, for example: + // + //
+ // + plugin(({addVariant}) => addVariant("phx-no-feedback", [".phx-no-feedback&", ".phx-no-feedback &"])), + plugin(({addVariant}) => addVariant("phx-click-loading", [".phx-click-loading&", ".phx-click-loading &"])), + plugin(({addVariant}) => addVariant("phx-submit-loading", [".phx-submit-loading&", ".phx-submit-loading &"])), + plugin(({addVariant}) => addVariant("phx-change-loading", [".phx-change-loading&", ".phx-change-loading &"])), + + // Embeds Heroicons (https://heroicons.com) into your app.css bundle + // See your `CoreComponents.icon/1` for more information. + // + plugin(function({matchComponents, theme}) { + let iconsDir = path.join(__dirname, "./vendor/heroicons/optimized") + let values = {} + let icons = [ + ["", "/24/outline"], + ["-solid", "/24/solid"], + ["-mini", "/20/solid"] + ] + icons.forEach(([suffix, dir]) => { + fs.readdirSync(path.join(iconsDir, dir)).map(file => { + let name = path.basename(file, ".svg") + suffix + values[name] = {name, fullPath: path.join(iconsDir, dir, file)} + }) + }) + matchComponents({ + "hero": ({name, fullPath}) => { + let content = fs.readFileSync(fullPath).toString().replace(/\r?\n|\r/g, "") + return { + [`--hero-${name}`]: `url('data:image/svg+xml;utf8,${content}')`, + "-webkit-mask": `var(--hero-${name})`, + "mask": `var(--hero-${name})`, + "mask-repeat": "no-repeat", + "background-color": "currentColor", + "vertical-align": "middle", + "display": "inline-block", + "width": theme("spacing.5"), + "height": theme("spacing.5") + } + } + }, {values}) + }) + ] +} diff --git a/test_app/assets/vendor/heroicons/LICENSE.md b/test_app/assets/vendor/heroicons/LICENSE.md new file mode 100644 index 0000000..1ac3e40 --- /dev/null +++ b/test_app/assets/vendor/heroicons/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Refactoring UI Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/test_app/assets/vendor/heroicons/UPGRADE.md b/test_app/assets/vendor/heroicons/UPGRADE.md new file mode 100644 index 0000000..5a140b9 --- /dev/null +++ b/test_app/assets/vendor/heroicons/UPGRADE.md @@ -0,0 +1,6 @@ +You are running heroicons v2.0.16. To upgrade in place, you can run the following command, +where your `HERO_VSN` export is your desired version: + + export HERO_VSN="2.0.16" ; \ + curl -L "https://github.com/tailwindlabs/heroicons/archive/refs/tags/v${HERO_VSN}.tar.gz" | \ + tar -xvz --strip-components=1 heroicons-${HERO_VSN}/optimized diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/academic-cap.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/academic-cap.svg new file mode 100644 index 0000000..bb980e6 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/academic-cap.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/adjustments-horizontal.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/adjustments-horizontal.svg new file mode 100644 index 0000000..13f9251 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/adjustments-horizontal.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/adjustments-vertical.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/adjustments-vertical.svg new file mode 100644 index 0000000..6f75b6c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/adjustments-vertical.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/archive-box-arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/archive-box-arrow-down.svg new file mode 100644 index 0000000..5ccef9d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/archive-box-arrow-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/archive-box-x-mark.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/archive-box-x-mark.svg new file mode 100644 index 0000000..73acbef --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/archive-box-x-mark.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/archive-box.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/archive-box.svg new file mode 100644 index 0000000..2205ae8 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/archive-box.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down-circle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down-circle.svg new file mode 100644 index 0000000..bb21a89 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down-left.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down-left.svg new file mode 100644 index 0000000..f0c3624 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down-on-square-stack.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down-on-square-stack.svg new file mode 100644 index 0000000..d9c4db0 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down-on-square-stack.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down-on-square.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down-on-square.svg new file mode 100644 index 0000000..4e8ee0f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down-on-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down-right.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down-right.svg new file mode 100644 index 0000000..65cdada --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down-tray.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down-tray.svg new file mode 100644 index 0000000..5c3589d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down-tray.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down.svg new file mode 100644 index 0000000..8d577b1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-left-circle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-left-circle.svg new file mode 100644 index 0000000..8cce243 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-left-circle.svg @@ -0,0 +1,10 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-left-on-rectangle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-left-on-rectangle.svg new file mode 100644 index 0000000..74d0699 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-left-on-rectangle.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-left.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-left.svg new file mode 100644 index 0000000..c7efd30 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-long-down.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-long-down.svg new file mode 100644 index 0000000..d263061 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-long-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-long-left.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-long-left.svg new file mode 100644 index 0000000..297553c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-long-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-long-right.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-long-right.svg new file mode 100644 index 0000000..eea945e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-long-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-long-up.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-long-up.svg new file mode 100644 index 0000000..193ff97 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-long-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-path-rounded-square.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-path-rounded-square.svg new file mode 100644 index 0000000..7d3deb5 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-path-rounded-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-path.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-path.svg new file mode 100644 index 0000000..1a31b4c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-path.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-right-circle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-right-circle.svg new file mode 100644 index 0000000..4178da9 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-right-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-right-on-rectangle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-right-on-rectangle.svg new file mode 100644 index 0000000..27c4dff --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-right-on-rectangle.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-right.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-right.svg new file mode 100644 index 0000000..95cc517 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-small-down.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-small-down.svg new file mode 100644 index 0000000..b986c6c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-small-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-small-left.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-small-left.svg new file mode 100644 index 0000000..0cb7e71 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-small-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-small-right.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-small-right.svg new file mode 100644 index 0000000..16beb5e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-small-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-small-up.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-small-up.svg new file mode 100644 index 0000000..7fda0e5 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-small-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-top-right-on-square.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-top-right-on-square.svg new file mode 100644 index 0000000..c93df54 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-top-right-on-square.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-trending-down.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-trending-down.svg new file mode 100644 index 0000000..5ec7c03 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-trending-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-trending-up.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-trending-up.svg new file mode 100644 index 0000000..67af2cc --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-trending-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up-circle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up-circle.svg new file mode 100644 index 0000000..21d87f2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up-left.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up-left.svg new file mode 100644 index 0000000..fb50038 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up-on-square-stack.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up-on-square-stack.svg new file mode 100644 index 0000000..0df0ed2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up-on-square-stack.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up-on-square.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up-on-square.svg new file mode 100644 index 0000000..01f18a8 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up-on-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up-right.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up-right.svg new file mode 100644 index 0000000..4841916 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up-tray.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up-tray.svg new file mode 100644 index 0000000..832afe5 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up-tray.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up.svg new file mode 100644 index 0000000..24b12b7 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-uturn-down.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-uturn-down.svg new file mode 100644 index 0000000..6839676 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-uturn-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-uturn-left.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-uturn-left.svg new file mode 100644 index 0000000..6691aa4 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-uturn-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-uturn-right.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-uturn-right.svg new file mode 100644 index 0000000..9a6e23b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-uturn-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-uturn-up.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-uturn-up.svg new file mode 100644 index 0000000..8e65bf8 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrow-uturn-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrows-pointing-in.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrows-pointing-in.svg new file mode 100644 index 0000000..6275807 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrows-pointing-in.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrows-pointing-out.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrows-pointing-out.svg new file mode 100644 index 0000000..14e1bcd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrows-pointing-out.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrows-right-left.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrows-right-left.svg new file mode 100644 index 0000000..87616d3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrows-right-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/arrows-up-down.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/arrows-up-down.svg new file mode 100644 index 0000000..b9c43d9 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/arrows-up-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/at-symbol.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/at-symbol.svg new file mode 100644 index 0000000..a9e960d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/at-symbol.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/backspace.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/backspace.svg new file mode 100644 index 0000000..d3c1686 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/backspace.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/backward.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/backward.svg new file mode 100644 index 0000000..8d341b2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/backward.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/banknotes.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/banknotes.svg new file mode 100644 index 0000000..979c586 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/banknotes.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/bars-2.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/bars-2.svg new file mode 100644 index 0000000..4ce1e19 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/bars-2.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/bars-3-bottom-left.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/bars-3-bottom-left.svg new file mode 100644 index 0000000..ebf785d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/bars-3-bottom-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/bars-3-bottom-right.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/bars-3-bottom-right.svg new file mode 100644 index 0000000..af69c3d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/bars-3-bottom-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/bars-3-center-left.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/bars-3-center-left.svg new file mode 100644 index 0000000..ee8a526 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/bars-3-center-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/bars-3.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/bars-3.svg new file mode 100644 index 0000000..d164cfd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/bars-3.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/bars-4.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/bars-4.svg new file mode 100644 index 0000000..8e3f650 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/bars-4.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/bars-arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/bars-arrow-down.svg new file mode 100644 index 0000000..fd8f98d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/bars-arrow-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/bars-arrow-up.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/bars-arrow-up.svg new file mode 100644 index 0000000..ba77dbe --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/bars-arrow-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/battery-0.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/battery-0.svg new file mode 100644 index 0000000..2320f7e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/battery-0.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/battery-100.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/battery-100.svg new file mode 100644 index 0000000..e04408f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/battery-100.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/battery-50.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/battery-50.svg new file mode 100644 index 0000000..e5e8498 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/battery-50.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/beaker.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/beaker.svg new file mode 100644 index 0000000..025c46b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/beaker.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/bell-alert.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/bell-alert.svg new file mode 100644 index 0000000..c84dc7c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/bell-alert.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/bell-slash.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/bell-slash.svg new file mode 100644 index 0000000..a4296ac --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/bell-slash.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/bell-snooze.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/bell-snooze.svg new file mode 100644 index 0000000..ad4f8c5 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/bell-snooze.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/bell.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/bell.svg new file mode 100644 index 0000000..2a81bba --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/bell.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/bolt-slash.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/bolt-slash.svg new file mode 100644 index 0000000..e4c2499 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/bolt-slash.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/bolt.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/bolt.svg new file mode 100644 index 0000000..53f4fb9 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/bolt.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/book-open.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/book-open.svg new file mode 100644 index 0000000..99cf0d4 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/book-open.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/bookmark-slash.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/bookmark-slash.svg new file mode 100644 index 0000000..1442fd4 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/bookmark-slash.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/bookmark-square.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/bookmark-square.svg new file mode 100644 index 0000000..849c425 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/bookmark-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/bookmark.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/bookmark.svg new file mode 100644 index 0000000..a3e68de --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/bookmark.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/briefcase.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/briefcase.svg new file mode 100644 index 0000000..275f4b3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/briefcase.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/bug-ant.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/bug-ant.svg new file mode 100644 index 0000000..bc86615 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/bug-ant.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/building-library.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/building-library.svg new file mode 100644 index 0000000..610bce7 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/building-library.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/building-office-2.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/building-office-2.svg new file mode 100644 index 0000000..b25c33d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/building-office-2.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/building-office.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/building-office.svg new file mode 100644 index 0000000..8fb3fab --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/building-office.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/building-storefront.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/building-storefront.svg new file mode 100644 index 0000000..0d7da7c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/building-storefront.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/cake.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/cake.svg new file mode 100644 index 0000000..c58d3b9 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/cake.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/calculator.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/calculator.svg new file mode 100644 index 0000000..cc26160 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/calculator.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/calendar-days.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/calendar-days.svg new file mode 100644 index 0000000..ded2318 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/calendar-days.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/calendar.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/calendar.svg new file mode 100644 index 0000000..dea374d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/calendar.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/camera.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/camera.svg new file mode 100644 index 0000000..17356ae --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/camera.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/chart-bar-square.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/chart-bar-square.svg new file mode 100644 index 0000000..6d5b976 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/chart-bar-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/chart-bar.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/chart-bar.svg new file mode 100644 index 0000000..c496112 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/chart-bar.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/chart-pie.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/chart-pie.svg new file mode 100644 index 0000000..37d18c9 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/chart-pie.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-bottom-center-text.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-bottom-center-text.svg new file mode 100644 index 0000000..fee91be --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-bottom-center-text.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-bottom-center.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-bottom-center.svg new file mode 100644 index 0000000..24de840 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-bottom-center.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-left-ellipsis.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-left-ellipsis.svg new file mode 100644 index 0000000..7e2b06c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-left-ellipsis.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-left-right.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-left-right.svg new file mode 100644 index 0000000..fceca7f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-left-right.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-left.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-left.svg new file mode 100644 index 0000000..cd706f9 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-oval-left-ellipsis.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-oval-left-ellipsis.svg new file mode 100644 index 0000000..88d9c32 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-oval-left-ellipsis.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-oval-left.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-oval-left.svg new file mode 100644 index 0000000..f3b3883 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/chat-bubble-oval-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/check-badge.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/check-badge.svg new file mode 100644 index 0000000..b13190c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/check-badge.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/check-circle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/check-circle.svg new file mode 100644 index 0000000..dbbc905 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/check-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/check.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/check.svg new file mode 100644 index 0000000..d1956aa --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/check.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-double-down.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-double-down.svg new file mode 100644 index 0000000..3c65193 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-double-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-double-left.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-double-left.svg new file mode 100644 index 0000000..a41e615 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-double-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-double-right.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-double-right.svg new file mode 100644 index 0000000..d78c932 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-double-right.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-double-up.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-double-up.svg new file mode 100644 index 0000000..f7ac668 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-double-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-down.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-down.svg new file mode 100644 index 0000000..6b63dfb --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-left.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-left.svg new file mode 100644 index 0000000..b484a40 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-right.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-right.svg new file mode 100644 index 0000000..9ce3745 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-up-down.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-up-down.svg new file mode 100644 index 0000000..2499bb1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-up-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-up.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-up.svg new file mode 100644 index 0000000..8aaaa1f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/chevron-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/circle-stack.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/circle-stack.svg new file mode 100644 index 0000000..fae2090 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/circle-stack.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/clipboard-document-check.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/clipboard-document-check.svg new file mode 100644 index 0000000..2447012 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/clipboard-document-check.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/clipboard-document-list.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/clipboard-document-list.svg new file mode 100644 index 0000000..a78b24c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/clipboard-document-list.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/clipboard-document.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/clipboard-document.svg new file mode 100644 index 0000000..f29a433 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/clipboard-document.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/clipboard.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/clipboard.svg new file mode 100644 index 0000000..3b2a7ff --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/clipboard.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/clock.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/clock.svg new file mode 100644 index 0000000..d72dd62 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/clock.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/cloud-arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/cloud-arrow-down.svg new file mode 100644 index 0000000..cb32c04 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/cloud-arrow-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/cloud-arrow-up.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/cloud-arrow-up.svg new file mode 100644 index 0000000..06b2c4a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/cloud-arrow-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/cloud.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/cloud.svg new file mode 100644 index 0000000..c5eb0c8 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/cloud.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/code-bracket-square.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/code-bracket-square.svg new file mode 100644 index 0000000..e4e3530 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/code-bracket-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/code-bracket.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/code-bracket.svg new file mode 100644 index 0000000..4adfd32 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/code-bracket.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/cog-6-tooth.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/cog-6-tooth.svg new file mode 100644 index 0000000..435032f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/cog-6-tooth.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/cog-8-tooth.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/cog-8-tooth.svg new file mode 100644 index 0000000..0450feb --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/cog-8-tooth.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/cog.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/cog.svg new file mode 100644 index 0000000..10f43b5 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/cog.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/command-line.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/command-line.svg new file mode 100644 index 0000000..59cf34c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/command-line.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/computer-desktop.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/computer-desktop.svg new file mode 100644 index 0000000..4eeac1b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/computer-desktop.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/cpu-chip.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/cpu-chip.svg new file mode 100644 index 0000000..f7c49b4 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/cpu-chip.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/credit-card.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/credit-card.svg new file mode 100644 index 0000000..d650fea --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/credit-card.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/cube-transparent.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/cube-transparent.svg new file mode 100644 index 0000000..bfe9dae --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/cube-transparent.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/cube.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/cube.svg new file mode 100644 index 0000000..c3436ed --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/cube.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/currency-bangladeshi.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/currency-bangladeshi.svg new file mode 100644 index 0000000..2a27260 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/currency-bangladeshi.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/currency-dollar.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/currency-dollar.svg new file mode 100644 index 0000000..1b00de7 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/currency-dollar.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/currency-euro.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/currency-euro.svg new file mode 100644 index 0000000..43fda8e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/currency-euro.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/currency-pound.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/currency-pound.svg new file mode 100644 index 0000000..9bc57fe --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/currency-pound.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/currency-rupee.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/currency-rupee.svg new file mode 100644 index 0000000..67da528 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/currency-rupee.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/currency-yen.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/currency-yen.svg new file mode 100644 index 0000000..68fca06 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/currency-yen.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/cursor-arrow-rays.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/cursor-arrow-rays.svg new file mode 100644 index 0000000..d2d36a7 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/cursor-arrow-rays.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/cursor-arrow-ripple.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/cursor-arrow-ripple.svg new file mode 100644 index 0000000..89ccfda --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/cursor-arrow-ripple.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/device-phone-mobile.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/device-phone-mobile.svg new file mode 100644 index 0000000..68fac4f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/device-phone-mobile.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/device-tablet.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/device-tablet.svg new file mode 100644 index 0000000..2490e1f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/device-tablet.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/document-arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/document-arrow-down.svg new file mode 100644 index 0000000..a51461d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/document-arrow-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/document-arrow-up.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/document-arrow-up.svg new file mode 100644 index 0000000..d55aacd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/document-arrow-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/document-chart-bar.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/document-chart-bar.svg new file mode 100644 index 0000000..8d5f60a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/document-chart-bar.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/document-check.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/document-check.svg new file mode 100644 index 0000000..b28da14 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/document-check.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/document-duplicate.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/document-duplicate.svg new file mode 100644 index 0000000..64768cf --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/document-duplicate.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/document-magnifying-glass.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/document-magnifying-glass.svg new file mode 100644 index 0000000..0dc8eba --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/document-magnifying-glass.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/document-minus.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/document-minus.svg new file mode 100644 index 0000000..bf7af06 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/document-minus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/document-plus.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/document-plus.svg new file mode 100644 index 0000000..133cc82 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/document-plus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/document-text.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/document-text.svg new file mode 100644 index 0000000..f7d91ba --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/document-text.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/document.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/document.svg new file mode 100644 index 0000000..aa7070c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/document.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/ellipsis-horizontal-circle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/ellipsis-horizontal-circle.svg new file mode 100644 index 0000000..799cf88 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/ellipsis-horizontal-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/ellipsis-horizontal.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/ellipsis-horizontal.svg new file mode 100644 index 0000000..a82211c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/ellipsis-horizontal.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/ellipsis-vertical.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/ellipsis-vertical.svg new file mode 100644 index 0000000..ac9c83f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/ellipsis-vertical.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/envelope-open.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/envelope-open.svg new file mode 100644 index 0000000..a60035b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/envelope-open.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/envelope.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/envelope.svg new file mode 100644 index 0000000..b582b8f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/envelope.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/exclamation-circle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/exclamation-circle.svg new file mode 100644 index 0000000..3cf5b59 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/exclamation-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/exclamation-triangle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/exclamation-triangle.svg new file mode 100644 index 0000000..a6cc02f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/exclamation-triangle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/eye-dropper.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/eye-dropper.svg new file mode 100644 index 0000000..cce0833 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/eye-dropper.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/eye-slash.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/eye-slash.svg new file mode 100644 index 0000000..cc2e222 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/eye-slash.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/eye.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/eye.svg new file mode 100644 index 0000000..b17cec9 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/eye.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/face-frown.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/face-frown.svg new file mode 100644 index 0000000..8cbb3b3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/face-frown.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/face-smile.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/face-smile.svg new file mode 100644 index 0000000..434c83e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/face-smile.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/film.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/film.svg new file mode 100644 index 0000000..9573445 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/film.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/finger-print.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/finger-print.svg new file mode 100644 index 0000000..409d67e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/finger-print.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/fire.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/fire.svg new file mode 100644 index 0000000..88fb85e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/fire.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/flag.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/flag.svg new file mode 100644 index 0000000..b790f05 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/flag.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/folder-arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/folder-arrow-down.svg new file mode 100644 index 0000000..4c2a915 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/folder-arrow-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/folder-minus.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/folder-minus.svg new file mode 100644 index 0000000..248388b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/folder-minus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/folder-open.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/folder-open.svg new file mode 100644 index 0000000..79d245e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/folder-open.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/folder-plus.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/folder-plus.svg new file mode 100644 index 0000000..0780a54 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/folder-plus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/folder.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/folder.svg new file mode 100644 index 0000000..c92e0ff --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/folder.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/forward.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/forward.svg new file mode 100644 index 0000000..11fd161 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/forward.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/funnel.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/funnel.svg new file mode 100644 index 0000000..af3078f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/funnel.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/gif.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/gif.svg new file mode 100644 index 0000000..ff1cd38 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/gif.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/gift-top.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/gift-top.svg new file mode 100644 index 0000000..d650d04 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/gift-top.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/gift.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/gift.svg new file mode 100644 index 0000000..90362ab --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/gift.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/globe-alt.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/globe-alt.svg new file mode 100644 index 0000000..c8ff599 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/globe-alt.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/globe-americas.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/globe-americas.svg new file mode 100644 index 0000000..7de8723 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/globe-americas.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/globe-asia-australia.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/globe-asia-australia.svg new file mode 100644 index 0000000..b3da4dd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/globe-asia-australia.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/globe-europe-africa.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/globe-europe-africa.svg new file mode 100644 index 0000000..92db1e1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/globe-europe-africa.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/hand-raised.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/hand-raised.svg new file mode 100644 index 0000000..caa27db --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/hand-raised.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/hand-thumb-down.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/hand-thumb-down.svg new file mode 100644 index 0000000..06ffbe0 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/hand-thumb-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/hand-thumb-up.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/hand-thumb-up.svg new file mode 100644 index 0000000..3d67d98 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/hand-thumb-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/hashtag.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/hashtag.svg new file mode 100644 index 0000000..29c9f10 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/hashtag.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/heart.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/heart.svg new file mode 100644 index 0000000..96e63d9 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/heart.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/home-modern.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/home-modern.svg new file mode 100644 index 0000000..95033a3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/home-modern.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/home.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/home.svg new file mode 100644 index 0000000..ae2acdc --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/home.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/identification.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/identification.svg new file mode 100644 index 0000000..7a8338c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/identification.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/inbox-arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/inbox-arrow-down.svg new file mode 100644 index 0000000..37f464e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/inbox-arrow-down.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/inbox-stack.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/inbox-stack.svg new file mode 100644 index 0000000..b8f22d1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/inbox-stack.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/inbox.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/inbox.svg new file mode 100644 index 0000000..87ae30d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/inbox.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/information-circle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/information-circle.svg new file mode 100644 index 0000000..25ac644 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/information-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/key.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/key.svg new file mode 100644 index 0000000..97e8ad8 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/key.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/language.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/language.svg new file mode 100644 index 0000000..e7524be --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/language.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/lifebuoy.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/lifebuoy.svg new file mode 100644 index 0000000..79134c1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/lifebuoy.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/light-bulb.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/light-bulb.svg new file mode 100644 index 0000000..415e374 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/light-bulb.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/link.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/link.svg new file mode 100644 index 0000000..e820413 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/link.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/list-bullet.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/list-bullet.svg new file mode 100644 index 0000000..3637934 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/list-bullet.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/lock-closed.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/lock-closed.svg new file mode 100644 index 0000000..e7e1dc1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/lock-closed.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/lock-open.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/lock-open.svg new file mode 100644 index 0000000..2ac4b14 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/lock-open.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/magnifying-glass-circle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/magnifying-glass-circle.svg new file mode 100644 index 0000000..e025769 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/magnifying-glass-circle.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/magnifying-glass-minus.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/magnifying-glass-minus.svg new file mode 100644 index 0000000..a8fb7a2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/magnifying-glass-minus.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/magnifying-glass-plus.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/magnifying-glass-plus.svg new file mode 100644 index 0000000..e55fc4c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/magnifying-glass-plus.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/magnifying-glass.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/magnifying-glass.svg new file mode 100644 index 0000000..d90520a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/magnifying-glass.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/map-pin.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/map-pin.svg new file mode 100644 index 0000000..7adc8a9 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/map-pin.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/map.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/map.svg new file mode 100644 index 0000000..7e25c7b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/map.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/megaphone.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/megaphone.svg new file mode 100644 index 0000000..cf73785 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/megaphone.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/microphone.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/microphone.svg new file mode 100644 index 0000000..635ded0 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/microphone.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/minus-circle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/minus-circle.svg new file mode 100644 index 0000000..5c361e2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/minus-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/minus-small.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/minus-small.svg new file mode 100644 index 0000000..4e041d3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/minus-small.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/minus.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/minus.svg new file mode 100644 index 0000000..6d8dd24 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/minus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/moon.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/moon.svg new file mode 100644 index 0000000..b592110 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/moon.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/musical-note.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/musical-note.svg new file mode 100644 index 0000000..c7f0aa8 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/musical-note.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/newspaper.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/newspaper.svg new file mode 100644 index 0000000..be785e3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/newspaper.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/no-symbol.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/no-symbol.svg new file mode 100644 index 0000000..8463da2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/no-symbol.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/paint-brush.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/paint-brush.svg new file mode 100644 index 0000000..c2db8c0 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/paint-brush.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/paper-airplane.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/paper-airplane.svg new file mode 100644 index 0000000..35315ad --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/paper-airplane.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/paper-clip.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/paper-clip.svg new file mode 100644 index 0000000..b38155e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/paper-clip.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/pause-circle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/pause-circle.svg new file mode 100644 index 0000000..732530a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/pause-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/pause.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/pause.svg new file mode 100644 index 0000000..b6544ba --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/pause.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/pencil-square.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/pencil-square.svg new file mode 100644 index 0000000..129ee44 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/pencil-square.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/pencil.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/pencil.svg new file mode 100644 index 0000000..fa50498 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/pencil.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/phone-arrow-down-left.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/phone-arrow-down-left.svg new file mode 100644 index 0000000..feeb636 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/phone-arrow-down-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/phone-arrow-up-right.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/phone-arrow-up-right.svg new file mode 100644 index 0000000..e1d9331 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/phone-arrow-up-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/phone-x-mark.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/phone-x-mark.svg new file mode 100644 index 0000000..6f1fd36 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/phone-x-mark.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/phone.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/phone.svg new file mode 100644 index 0000000..5fd57fc --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/phone.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/photo.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/photo.svg new file mode 100644 index 0000000..db063d3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/photo.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/play-circle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/play-circle.svg new file mode 100644 index 0000000..d1587b7 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/play-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/play-pause.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/play-pause.svg new file mode 100644 index 0000000..cdfa63b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/play-pause.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/play.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/play.svg new file mode 100644 index 0000000..2cd53e1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/play.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/plus-circle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/plus-circle.svg new file mode 100644 index 0000000..3925a14 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/plus-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/plus-small.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/plus-small.svg new file mode 100644 index 0000000..eb22598 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/plus-small.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/plus.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/plus.svg new file mode 100644 index 0000000..218ab93 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/plus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/power.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/power.svg new file mode 100644 index 0000000..1603820 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/power.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/presentation-chart-bar.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/presentation-chart-bar.svg new file mode 100644 index 0000000..e1a4242 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/presentation-chart-bar.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/presentation-chart-line.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/presentation-chart-line.svg new file mode 100644 index 0000000..2e9281f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/presentation-chart-line.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/printer.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/printer.svg new file mode 100644 index 0000000..81d93dc --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/printer.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/puzzle-piece.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/puzzle-piece.svg new file mode 100644 index 0000000..e5329e5 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/puzzle-piece.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/qr-code.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/qr-code.svg new file mode 100644 index 0000000..d5daf2a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/qr-code.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/question-mark-circle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/question-mark-circle.svg new file mode 100644 index 0000000..893dab5 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/question-mark-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/queue-list.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/queue-list.svg new file mode 100644 index 0000000..91f5b57 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/queue-list.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/radio.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/radio.svg new file mode 100644 index 0000000..9a12c8b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/radio.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/receipt-percent.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/receipt-percent.svg new file mode 100644 index 0000000..1a8f254 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/receipt-percent.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/receipt-refund.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/receipt-refund.svg new file mode 100644 index 0000000..a134c56 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/receipt-refund.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/rectangle-group.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/rectangle-group.svg new file mode 100644 index 0000000..599d5f4 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/rectangle-group.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/rectangle-stack.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/rectangle-stack.svg new file mode 100644 index 0000000..94b5654 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/rectangle-stack.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/rocket-launch.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/rocket-launch.svg new file mode 100644 index 0000000..b97e89e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/rocket-launch.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/rss.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/rss.svg new file mode 100644 index 0000000..538ae9a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/rss.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/scale.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/scale.svg new file mode 100644 index 0000000..60b0ed9 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/scale.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/scissors.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/scissors.svg new file mode 100644 index 0000000..3122658 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/scissors.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/server-stack.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/server-stack.svg new file mode 100644 index 0000000..2247dbe --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/server-stack.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/server.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/server.svg new file mode 100644 index 0000000..6c8899b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/server.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/share.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/share.svg new file mode 100644 index 0000000..e5aafee --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/share.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/shield-check.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/shield-check.svg new file mode 100644 index 0000000..a8572d4 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/shield-check.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/shield-exclamation.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/shield-exclamation.svg new file mode 100644 index 0000000..8562de4 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/shield-exclamation.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/shopping-bag.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/shopping-bag.svg new file mode 100644 index 0000000..e70c815 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/shopping-bag.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/shopping-cart.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/shopping-cart.svg new file mode 100644 index 0000000..855a631 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/shopping-cart.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/signal-slash.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/signal-slash.svg new file mode 100644 index 0000000..822179a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/signal-slash.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/signal.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/signal.svg new file mode 100644 index 0000000..7539204 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/signal.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/sparkles.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/sparkles.svg new file mode 100644 index 0000000..a247c94 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/sparkles.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/speaker-wave.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/speaker-wave.svg new file mode 100644 index 0000000..2e6b3e0 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/speaker-wave.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/speaker-x-mark.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/speaker-x-mark.svg new file mode 100644 index 0000000..0c39f61 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/speaker-x-mark.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/square-2-stack.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/square-2-stack.svg new file mode 100644 index 0000000..177d43a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/square-2-stack.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/square-3-stack-3d.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/square-3-stack-3d.svg new file mode 100644 index 0000000..7d6b44f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/square-3-stack-3d.svg @@ -0,0 +1,5 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/squares-2x2.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/squares-2x2.svg new file mode 100644 index 0000000..47c1817 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/squares-2x2.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/squares-plus.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/squares-plus.svg new file mode 100644 index 0000000..019eb37 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/squares-plus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/star.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/star.svg new file mode 100644 index 0000000..a870365 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/star.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/stop-circle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/stop-circle.svg new file mode 100644 index 0000000..9167a64 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/stop-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/stop.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/stop.svg new file mode 100644 index 0000000..b0e40db --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/stop.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/sun.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/sun.svg new file mode 100644 index 0000000..449e36c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/sun.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/swatch.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/swatch.svg new file mode 100644 index 0000000..1089548 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/swatch.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/table-cells.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/table-cells.svg new file mode 100644 index 0000000..aa8eacd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/table-cells.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/tag.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/tag.svg new file mode 100644 index 0000000..d6c9c8b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/tag.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/ticket.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/ticket.svg new file mode 100644 index 0000000..7d04b01 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/ticket.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/trash.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/trash.svg new file mode 100644 index 0000000..16bd5c6 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/trash.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/trophy.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/trophy.svg new file mode 100644 index 0000000..e2ebdaf --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/trophy.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/truck.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/truck.svg new file mode 100644 index 0000000..a50085a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/truck.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/tv.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/tv.svg new file mode 100644 index 0000000..b0c7209 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/tv.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/user-circle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/user-circle.svg new file mode 100644 index 0000000..abd6c98 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/user-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/user-group.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/user-group.svg new file mode 100644 index 0000000..dc83736 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/user-group.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/user-minus.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/user-minus.svg new file mode 100644 index 0000000..b092b77 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/user-minus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/user-plus.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/user-plus.svg new file mode 100644 index 0000000..afd5965 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/user-plus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/user.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/user.svg new file mode 100644 index 0000000..4d9b2ee --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/user.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/users.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/users.svg new file mode 100644 index 0000000..43526a6 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/users.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/variable.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/variable.svg new file mode 100644 index 0000000..3460817 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/variable.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/video-camera-slash.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/video-camera-slash.svg new file mode 100644 index 0000000..95b9413 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/video-camera-slash.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/video-camera.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/video-camera.svg new file mode 100644 index 0000000..4d22f16 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/video-camera.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/view-columns.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/view-columns.svg new file mode 100644 index 0000000..1111492 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/view-columns.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/viewfinder-circle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/viewfinder-circle.svg new file mode 100644 index 0000000..5cfe9fb --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/viewfinder-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/wallet.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/wallet.svg new file mode 100644 index 0000000..6ce8050 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/wallet.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/wifi.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/wifi.svg new file mode 100644 index 0000000..f3c7118 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/wifi.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/window.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/window.svg new file mode 100644 index 0000000..9110a2b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/window.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/wrench-screwdriver.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/wrench-screwdriver.svg new file mode 100644 index 0000000..2ad879f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/wrench-screwdriver.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/wrench.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/wrench.svg new file mode 100644 index 0000000..2643e00 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/wrench.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/x-circle.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/x-circle.svg new file mode 100644 index 0000000..a660014 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/x-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/20/solid/x-mark.svg b/test_app/assets/vendor/heroicons/optimized/20/solid/x-mark.svg new file mode 100644 index 0000000..0635bac --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/20/solid/x-mark.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/academic-cap.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/academic-cap.svg new file mode 100644 index 0000000..fc18107 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/academic-cap.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/adjustments-horizontal.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/adjustments-horizontal.svg new file mode 100644 index 0000000..e859e5d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/adjustments-horizontal.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/adjustments-vertical.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/adjustments-vertical.svg new file mode 100644 index 0000000..6153809 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/adjustments-vertical.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/archive-box-arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/archive-box-arrow-down.svg new file mode 100644 index 0000000..1a0a830 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/archive-box-arrow-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/archive-box-x-mark.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/archive-box-x-mark.svg new file mode 100644 index 0000000..49bd087 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/archive-box-x-mark.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/archive-box.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/archive-box.svg new file mode 100644 index 0000000..704f353 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/archive-box.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down-circle.svg new file mode 100644 index 0000000..248b0e8 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down-left.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down-left.svg new file mode 100644 index 0000000..262b5ff --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down-on-square-stack.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down-on-square-stack.svg new file mode 100644 index 0000000..42a5b84 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down-on-square-stack.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down-on-square.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down-on-square.svg new file mode 100644 index 0000000..da1b827 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down-on-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down-right.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down-right.svg new file mode 100644 index 0000000..9cc7a30 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down-tray.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down-tray.svg new file mode 100644 index 0000000..a77546c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down-tray.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down.svg new file mode 100644 index 0000000..b5b04fd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-left-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-left-circle.svg new file mode 100644 index 0000000..849cc5f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-left-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-left-on-rectangle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-left-on-rectangle.svg new file mode 100644 index 0000000..0d6a3cc --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-left-on-rectangle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-left.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-left.svg new file mode 100644 index 0000000..49f15d4 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-long-down.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-long-down.svg new file mode 100644 index 0000000..eb7a92b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-long-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-long-left.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-long-left.svg new file mode 100644 index 0000000..d3e9005 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-long-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-long-right.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-long-right.svg new file mode 100644 index 0000000..413d6b5 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-long-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-long-up.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-long-up.svg new file mode 100644 index 0000000..fb029f4 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-long-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-path-rounded-square.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-path-rounded-square.svg new file mode 100644 index 0000000..0cfe39e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-path-rounded-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-path.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-path.svg new file mode 100644 index 0000000..7da4fd2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-path.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-right-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-right-circle.svg new file mode 100644 index 0000000..e7bcb80 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-right-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-right-on-rectangle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-right-on-rectangle.svg new file mode 100644 index 0000000..2b49bec --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-right-on-rectangle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-right.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-right.svg new file mode 100644 index 0000000..8527a52 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-small-down.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-small-down.svg new file mode 100644 index 0000000..1f1a210 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-small-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-small-left.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-small-left.svg new file mode 100644 index 0000000..778cb17 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-small-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-small-right.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-small-right.svg new file mode 100644 index 0000000..1b5fc64 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-small-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-small-up.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-small-up.svg new file mode 100644 index 0000000..4ed197e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-small-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-top-right-on-square.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-top-right-on-square.svg new file mode 100644 index 0000000..c4a9239 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-top-right-on-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-trending-down.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-trending-down.svg new file mode 100644 index 0000000..aebbb18 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-trending-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-trending-up.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-trending-up.svg new file mode 100644 index 0000000..868f3d3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-trending-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up-circle.svg new file mode 100644 index 0000000..51340d6 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up-left.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up-left.svg new file mode 100644 index 0000000..ba4e54e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up-on-square-stack.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up-on-square-stack.svg new file mode 100644 index 0000000..0d4d823 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up-on-square-stack.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up-on-square.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up-on-square.svg new file mode 100644 index 0000000..2c38ea0 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up-on-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up-right.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up-right.svg new file mode 100644 index 0000000..0b7a372 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up-tray.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up-tray.svg new file mode 100644 index 0000000..448b853 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up-tray.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up.svg new file mode 100644 index 0000000..e269624 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-uturn-down.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-uturn-down.svg new file mode 100644 index 0000000..51f9929 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-uturn-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-uturn-left.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-uturn-left.svg new file mode 100644 index 0000000..b8f240e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-uturn-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-uturn-right.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-uturn-right.svg new file mode 100644 index 0000000..ece5091 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-uturn-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-uturn-up.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-uturn-up.svg new file mode 100644 index 0000000..b76c54b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrow-uturn-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrows-pointing-in.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrows-pointing-in.svg new file mode 100644 index 0000000..0a8872d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrows-pointing-in.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrows-pointing-out.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrows-pointing-out.svg new file mode 100644 index 0000000..936ac45 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrows-pointing-out.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrows-right-left.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrows-right-left.svg new file mode 100644 index 0000000..18890f3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrows-right-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/arrows-up-down.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/arrows-up-down.svg new file mode 100644 index 0000000..da4cdf3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/arrows-up-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/at-symbol.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/at-symbol.svg new file mode 100644 index 0000000..fe2f644 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/at-symbol.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/backspace.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/backspace.svg new file mode 100644 index 0000000..f76c5df --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/backspace.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/backward.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/backward.svg new file mode 100644 index 0000000..fb1da49 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/backward.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/banknotes.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/banknotes.svg new file mode 100644 index 0000000..0603b0d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/banknotes.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/bars-2.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/bars-2.svg new file mode 100644 index 0000000..9c49ca2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/bars-2.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/bars-3-bottom-left.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/bars-3-bottom-left.svg new file mode 100644 index 0000000..e23bbc3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/bars-3-bottom-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/bars-3-bottom-right.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/bars-3-bottom-right.svg new file mode 100644 index 0000000..a0f683d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/bars-3-bottom-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/bars-3-center-left.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/bars-3-center-left.svg new file mode 100644 index 0000000..a8e83e1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/bars-3-center-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/bars-3.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/bars-3.svg new file mode 100644 index 0000000..a7cf320 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/bars-3.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/bars-4.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/bars-4.svg new file mode 100644 index 0000000..f34bddf --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/bars-4.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/bars-arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/bars-arrow-down.svg new file mode 100644 index 0000000..200fd3a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/bars-arrow-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/bars-arrow-up.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/bars-arrow-up.svg new file mode 100644 index 0000000..d88bf4e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/bars-arrow-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/battery-0.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/battery-0.svg new file mode 100644 index 0000000..fd2aa9d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/battery-0.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/battery-100.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/battery-100.svg new file mode 100644 index 0000000..ba012c6 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/battery-100.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/battery-50.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/battery-50.svg new file mode 100644 index 0000000..f6f9838 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/battery-50.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/beaker.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/beaker.svg new file mode 100644 index 0000000..2d143fd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/beaker.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/bell-alert.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/bell-alert.svg new file mode 100644 index 0000000..c4af427 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/bell-alert.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/bell-slash.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/bell-slash.svg new file mode 100644 index 0000000..2df7520 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/bell-slash.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/bell-snooze.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/bell-snooze.svg new file mode 100644 index 0000000..117de29 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/bell-snooze.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/bell.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/bell.svg new file mode 100644 index 0000000..63ab153 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/bell.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/bolt-slash.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/bolt-slash.svg new file mode 100644 index 0000000..13af346 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/bolt-slash.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/bolt.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/bolt.svg new file mode 100644 index 0000000..5e629fe --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/bolt.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/book-open.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/book-open.svg new file mode 100644 index 0000000..a4153b6 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/book-open.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/bookmark-slash.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/bookmark-slash.svg new file mode 100644 index 0000000..f3ae625 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/bookmark-slash.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/bookmark-square.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/bookmark-square.svg new file mode 100644 index 0000000..00e5cc3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/bookmark-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/bookmark.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/bookmark.svg new file mode 100644 index 0000000..6d06e4f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/bookmark.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/briefcase.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/briefcase.svg new file mode 100644 index 0000000..adab6ff --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/briefcase.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/bug-ant.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/bug-ant.svg new file mode 100644 index 0000000..ac04fad --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/bug-ant.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/building-library.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/building-library.svg new file mode 100644 index 0000000..4e2e1da --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/building-library.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/building-office-2.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/building-office-2.svg new file mode 100644 index 0000000..45e063c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/building-office-2.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/building-office.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/building-office.svg new file mode 100644 index 0000000..0efd982 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/building-office.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/building-storefront.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/building-storefront.svg new file mode 100644 index 0000000..31fca55 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/building-storefront.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/cake.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/cake.svg new file mode 100644 index 0000000..a603e90 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/cake.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/calculator.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/calculator.svg new file mode 100644 index 0000000..d97740e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/calculator.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/calendar-days.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/calendar-days.svg new file mode 100644 index 0000000..64b5f8f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/calendar-days.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/calendar.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/calendar.svg new file mode 100644 index 0000000..5e44911 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/calendar.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/camera.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/camera.svg new file mode 100644 index 0000000..b8bdae3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/camera.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/chart-bar-square.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/chart-bar-square.svg new file mode 100644 index 0000000..d7fa42c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/chart-bar-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/chart-bar.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/chart-bar.svg new file mode 100644 index 0000000..27f20fa --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/chart-bar.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/chart-pie.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/chart-pie.svg new file mode 100644 index 0000000..fa51c16 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/chart-pie.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-bottom-center-text.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-bottom-center-text.svg new file mode 100644 index 0000000..4bc306e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-bottom-center-text.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-bottom-center.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-bottom-center.svg new file mode 100644 index 0000000..d59d02a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-bottom-center.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-left-ellipsis.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-left-ellipsis.svg new file mode 100644 index 0000000..9a0ec73 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-left-ellipsis.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-left-right.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-left-right.svg new file mode 100644 index 0000000..4d366b8 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-left-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-left.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-left.svg new file mode 100644 index 0000000..a41bf1e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-oval-left-ellipsis.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-oval-left-ellipsis.svg new file mode 100644 index 0000000..83d1751 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-oval-left-ellipsis.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-oval-left.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-oval-left.svg new file mode 100644 index 0000000..d0d0d89 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/chat-bubble-oval-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/check-badge.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/check-badge.svg new file mode 100644 index 0000000..8d6b79a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/check-badge.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/check-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/check-circle.svg new file mode 100644 index 0000000..d4471d6 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/check-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/check.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/check.svg new file mode 100644 index 0000000..7644e30 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/check.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-double-down.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-double-down.svg new file mode 100644 index 0000000..d7e9370 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-double-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-double-left.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-double-left.svg new file mode 100644 index 0000000..95834af --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-double-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-double-right.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-double-right.svg new file mode 100644 index 0000000..37a809d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-double-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-double-up.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-double-up.svg new file mode 100644 index 0000000..5182691 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-double-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-down.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-down.svg new file mode 100644 index 0000000..b38efa5 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-left.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-left.svg new file mode 100644 index 0000000..73fe99a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-right.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-right.svg new file mode 100644 index 0000000..1e31bfd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-up-down.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-up-down.svg new file mode 100644 index 0000000..27b1d4f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-up-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-up.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-up.svg new file mode 100644 index 0000000..713a6f1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/chevron-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/circle-stack.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/circle-stack.svg new file mode 100644 index 0000000..b8fb769 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/circle-stack.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/clipboard-document-check.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/clipboard-document-check.svg new file mode 100644 index 0000000..7bb03a1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/clipboard-document-check.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/clipboard-document-list.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/clipboard-document-list.svg new file mode 100644 index 0000000..4670777 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/clipboard-document-list.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/clipboard-document.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/clipboard-document.svg new file mode 100644 index 0000000..783a333 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/clipboard-document.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/clipboard.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/clipboard.svg new file mode 100644 index 0000000..ad9b943 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/clipboard.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/clock.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/clock.svg new file mode 100644 index 0000000..337196c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/clock.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/cloud-arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/cloud-arrow-down.svg new file mode 100644 index 0000000..7074791 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/cloud-arrow-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/cloud-arrow-up.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/cloud-arrow-up.svg new file mode 100644 index 0000000..8b45081 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/cloud-arrow-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/cloud.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/cloud.svg new file mode 100644 index 0000000..55fd725 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/cloud.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/code-bracket-square.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/code-bracket-square.svg new file mode 100644 index 0000000..8308024 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/code-bracket-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/code-bracket.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/code-bracket.svg new file mode 100644 index 0000000..3361add --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/code-bracket.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/cog-6-tooth.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/cog-6-tooth.svg new file mode 100644 index 0000000..d585645 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/cog-6-tooth.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/cog-8-tooth.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/cog-8-tooth.svg new file mode 100644 index 0000000..28f85f4 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/cog-8-tooth.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/cog.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/cog.svg new file mode 100644 index 0000000..f2bad9f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/cog.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/command-line.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/command-line.svg new file mode 100644 index 0000000..baaf362 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/command-line.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/computer-desktop.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/computer-desktop.svg new file mode 100644 index 0000000..fb9a6e0 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/computer-desktop.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/cpu-chip.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/cpu-chip.svg new file mode 100644 index 0000000..cabc435 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/cpu-chip.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/credit-card.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/credit-card.svg new file mode 100644 index 0000000..3c0c917 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/credit-card.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/cube-transparent.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/cube-transparent.svg new file mode 100644 index 0000000..5a8adac --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/cube-transparent.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/cube.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/cube.svg new file mode 100644 index 0000000..70b0091 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/cube.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/currency-bangladeshi.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/currency-bangladeshi.svg new file mode 100644 index 0000000..7f2fca3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/currency-bangladeshi.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/currency-dollar.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/currency-dollar.svg new file mode 100644 index 0000000..d376f4c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/currency-dollar.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/currency-euro.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/currency-euro.svg new file mode 100644 index 0000000..8b9dd2e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/currency-euro.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/currency-pound.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/currency-pound.svg new file mode 100644 index 0000000..8e7c52d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/currency-pound.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/currency-rupee.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/currency-rupee.svg new file mode 100644 index 0000000..078bf05 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/currency-rupee.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/currency-yen.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/currency-yen.svg new file mode 100644 index 0000000..254011a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/currency-yen.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/cursor-arrow-rays.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/cursor-arrow-rays.svg new file mode 100644 index 0000000..c29d0fd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/cursor-arrow-rays.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/cursor-arrow-ripple.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/cursor-arrow-ripple.svg new file mode 100644 index 0000000..500a04c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/cursor-arrow-ripple.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/device-phone-mobile.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/device-phone-mobile.svg new file mode 100644 index 0000000..1caf911 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/device-phone-mobile.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/device-tablet.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/device-tablet.svg new file mode 100644 index 0000000..7090ecb --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/device-tablet.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/document-arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/document-arrow-down.svg new file mode 100644 index 0000000..04f6e65 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/document-arrow-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/document-arrow-up.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/document-arrow-up.svg new file mode 100644 index 0000000..c0ca80f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/document-arrow-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/document-chart-bar.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/document-chart-bar.svg new file mode 100644 index 0000000..2ffa3fe --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/document-chart-bar.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/document-check.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/document-check.svg new file mode 100644 index 0000000..5ea7d9c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/document-check.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/document-duplicate.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/document-duplicate.svg new file mode 100644 index 0000000..acc6464 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/document-duplicate.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/document-magnifying-glass.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/document-magnifying-glass.svg new file mode 100644 index 0000000..f94eff6 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/document-magnifying-glass.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/document-minus.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/document-minus.svg new file mode 100644 index 0000000..173cb1f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/document-minus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/document-plus.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/document-plus.svg new file mode 100644 index 0000000..9ec31ad --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/document-plus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/document-text.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/document-text.svg new file mode 100644 index 0000000..cd77136 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/document-text.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/document.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/document.svg new file mode 100644 index 0000000..863a8aa --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/document.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/ellipsis-horizontal-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/ellipsis-horizontal-circle.svg new file mode 100644 index 0000000..09aac53 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/ellipsis-horizontal-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/ellipsis-horizontal.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/ellipsis-horizontal.svg new file mode 100644 index 0000000..7541be5 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/ellipsis-horizontal.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/ellipsis-vertical.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/ellipsis-vertical.svg new file mode 100644 index 0000000..4676cf3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/ellipsis-vertical.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/envelope-open.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/envelope-open.svg new file mode 100644 index 0000000..ff9dccd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/envelope-open.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/envelope.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/envelope.svg new file mode 100644 index 0000000..ae8ff72 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/envelope.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/exclamation-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/exclamation-circle.svg new file mode 100644 index 0000000..25ef36f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/exclamation-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/exclamation-triangle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/exclamation-triangle.svg new file mode 100644 index 0000000..c9742f1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/exclamation-triangle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/eye-dropper.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/eye-dropper.svg new file mode 100644 index 0000000..c7263e1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/eye-dropper.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/eye-slash.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/eye-slash.svg new file mode 100644 index 0000000..072c9f2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/eye-slash.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/eye.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/eye.svg new file mode 100644 index 0000000..2a54d63 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/eye.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/face-frown.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/face-frown.svg new file mode 100644 index 0000000..ba0cab3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/face-frown.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/face-smile.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/face-smile.svg new file mode 100644 index 0000000..5246524 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/face-smile.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/film.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/film.svg new file mode 100644 index 0000000..d76e594 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/film.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/finger-print.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/finger-print.svg new file mode 100644 index 0000000..0c1eeb2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/finger-print.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/fire.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/fire.svg new file mode 100644 index 0000000..54c9748 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/fire.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/flag.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/flag.svg new file mode 100644 index 0000000..dff4126 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/flag.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/folder-arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/folder-arrow-down.svg new file mode 100644 index 0000000..96290cd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/folder-arrow-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/folder-minus.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/folder-minus.svg new file mode 100644 index 0000000..824cb0e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/folder-minus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/folder-open.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/folder-open.svg new file mode 100644 index 0000000..0721502 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/folder-open.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/folder-plus.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/folder-plus.svg new file mode 100644 index 0000000..3df62d2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/folder-plus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/folder.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/folder.svg new file mode 100644 index 0000000..3054819 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/folder.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/forward.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/forward.svg new file mode 100644 index 0000000..cc80dc9 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/forward.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/funnel.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/funnel.svg new file mode 100644 index 0000000..338fa52 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/funnel.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/gif.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/gif.svg new file mode 100644 index 0000000..ba8a186 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/gif.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/gift-top.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/gift-top.svg new file mode 100644 index 0000000..055b6d2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/gift-top.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/gift.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/gift.svg new file mode 100644 index 0000000..5445815 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/gift.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/globe-alt.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/globe-alt.svg new file mode 100644 index 0000000..a605be0 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/globe-alt.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/globe-americas.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/globe-americas.svg new file mode 100644 index 0000000..5d1a5cb --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/globe-americas.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/globe-asia-australia.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/globe-asia-australia.svg new file mode 100644 index 0000000..f4898fa --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/globe-asia-australia.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/globe-europe-africa.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/globe-europe-africa.svg new file mode 100644 index 0000000..c8f797d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/globe-europe-africa.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/hand-raised.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/hand-raised.svg new file mode 100644 index 0000000..859f1ab --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/hand-raised.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/hand-thumb-down.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/hand-thumb-down.svg new file mode 100644 index 0000000..c588a53 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/hand-thumb-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/hand-thumb-up.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/hand-thumb-up.svg new file mode 100644 index 0000000..66ca9c3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/hand-thumb-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/hashtag.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/hashtag.svg new file mode 100644 index 0000000..3ae1060 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/hashtag.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/heart.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/heart.svg new file mode 100644 index 0000000..1084768 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/heart.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/home-modern.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/home-modern.svg new file mode 100644 index 0000000..20f4e2c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/home-modern.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/home.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/home.svg new file mode 100644 index 0000000..9543375 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/home.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/identification.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/identification.svg new file mode 100644 index 0000000..bfd302a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/identification.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/inbox-arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/inbox-arrow-down.svg new file mode 100644 index 0000000..db6ebda --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/inbox-arrow-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/inbox-stack.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/inbox-stack.svg new file mode 100644 index 0000000..6c1e55c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/inbox-stack.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/inbox.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/inbox.svg new file mode 100644 index 0000000..56b35cb --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/inbox.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/information-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/information-circle.svg new file mode 100644 index 0000000..c7fa9d7 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/information-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/key.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/key.svg new file mode 100644 index 0000000..e9684cd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/key.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/language.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/language.svg new file mode 100644 index 0000000..0c606ef --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/language.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/lifebuoy.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/lifebuoy.svg new file mode 100644 index 0000000..1660e99 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/lifebuoy.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/light-bulb.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/light-bulb.svg new file mode 100644 index 0000000..e3f2d9a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/light-bulb.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/link.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/link.svg new file mode 100644 index 0000000..916a703 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/link.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/list-bullet.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/list-bullet.svg new file mode 100644 index 0000000..1474573 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/list-bullet.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/lock-closed.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/lock-closed.svg new file mode 100644 index 0000000..08b23c9 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/lock-closed.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/lock-open.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/lock-open.svg new file mode 100644 index 0000000..c5595dd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/lock-open.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/magnifying-glass-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/magnifying-glass-circle.svg new file mode 100644 index 0000000..e71f8bf --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/magnifying-glass-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/magnifying-glass-minus.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/magnifying-glass-minus.svg new file mode 100644 index 0000000..6bd11c1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/magnifying-glass-minus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/magnifying-glass-plus.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/magnifying-glass-plus.svg new file mode 100644 index 0000000..5dab7de --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/magnifying-glass-plus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/magnifying-glass.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/magnifying-glass.svg new file mode 100644 index 0000000..7cff88f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/magnifying-glass.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/map-pin.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/map-pin.svg new file mode 100644 index 0000000..1f272f4 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/map-pin.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/map.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/map.svg new file mode 100644 index 0000000..f96c988 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/map.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/megaphone.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/megaphone.svg new file mode 100644 index 0000000..ec19508 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/megaphone.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/microphone.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/microphone.svg new file mode 100644 index 0000000..670b34f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/microphone.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/minus-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/minus-circle.svg new file mode 100644 index 0000000..b9630fc --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/minus-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/minus-small.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/minus-small.svg new file mode 100644 index 0000000..3e1a8b7 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/minus-small.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/minus.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/minus.svg new file mode 100644 index 0000000..781994c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/minus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/moon.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/moon.svg new file mode 100644 index 0000000..91501fd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/moon.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/musical-note.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/musical-note.svg new file mode 100644 index 0000000..c0667fc --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/musical-note.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/newspaper.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/newspaper.svg new file mode 100644 index 0000000..0a4ac57 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/newspaper.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/no-symbol.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/no-symbol.svg new file mode 100644 index 0000000..19b0bd0 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/no-symbol.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/paint-brush.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/paint-brush.svg new file mode 100644 index 0000000..b66098f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/paint-brush.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/paper-airplane.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/paper-airplane.svg new file mode 100644 index 0000000..32da43e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/paper-airplane.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/paper-clip.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/paper-clip.svg new file mode 100644 index 0000000..1d78d81 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/paper-clip.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/pause-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/pause-circle.svg new file mode 100644 index 0000000..a9a9e93 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/pause-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/pause.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/pause.svg new file mode 100644 index 0000000..9843f7b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/pause.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/pencil-square.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/pencil-square.svg new file mode 100644 index 0000000..3de435b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/pencil-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/pencil.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/pencil.svg new file mode 100644 index 0000000..0c8759a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/pencil.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/phone-arrow-down-left.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/phone-arrow-down-left.svg new file mode 100644 index 0000000..b1b2e61 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/phone-arrow-down-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/phone-arrow-up-right.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/phone-arrow-up-right.svg new file mode 100644 index 0000000..faaf659 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/phone-arrow-up-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/phone-x-mark.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/phone-x-mark.svg new file mode 100644 index 0000000..0b8de6d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/phone-x-mark.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/phone.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/phone.svg new file mode 100644 index 0000000..6f73149 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/phone.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/photo.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/photo.svg new file mode 100644 index 0000000..6982a11 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/photo.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/play-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/play-circle.svg new file mode 100644 index 0000000..3a2fa63 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/play-circle.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/play-pause.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/play-pause.svg new file mode 100644 index 0000000..4ce4e55 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/play-pause.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/play.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/play.svg new file mode 100644 index 0000000..c0ae6de --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/play.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/plus-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/plus-circle.svg new file mode 100644 index 0000000..4da4d1f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/plus-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/plus-small.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/plus-small.svg new file mode 100644 index 0000000..991ed59 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/plus-small.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/plus.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/plus.svg new file mode 100644 index 0000000..0480817 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/plus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/power.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/power.svg new file mode 100644 index 0000000..c4b2706 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/power.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/presentation-chart-bar.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/presentation-chart-bar.svg new file mode 100644 index 0000000..87d8a6d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/presentation-chart-bar.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/presentation-chart-line.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/presentation-chart-line.svg new file mode 100644 index 0000000..2262e1f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/presentation-chart-line.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/printer.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/printer.svg new file mode 100644 index 0000000..6f7c5fa --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/printer.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/puzzle-piece.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/puzzle-piece.svg new file mode 100644 index 0000000..13aa1a5 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/puzzle-piece.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/qr-code.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/qr-code.svg new file mode 100644 index 0000000..662a4bd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/qr-code.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/question-mark-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/question-mark-circle.svg new file mode 100644 index 0000000..9fb2542 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/question-mark-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/queue-list.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/queue-list.svg new file mode 100644 index 0000000..91c3f11 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/queue-list.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/radio.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/radio.svg new file mode 100644 index 0000000..f9c177a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/radio.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/receipt-percent.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/receipt-percent.svg new file mode 100644 index 0000000..2d19255 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/receipt-percent.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/receipt-refund.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/receipt-refund.svg new file mode 100644 index 0000000..dc569fc --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/receipt-refund.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/rectangle-group.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/rectangle-group.svg new file mode 100644 index 0000000..b184964 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/rectangle-group.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/rectangle-stack.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/rectangle-stack.svg new file mode 100644 index 0000000..e1c0272 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/rectangle-stack.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/rocket-launch.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/rocket-launch.svg new file mode 100644 index 0000000..6400ee8 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/rocket-launch.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/rss.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/rss.svg new file mode 100644 index 0000000..1c36b21 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/rss.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/scale.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/scale.svg new file mode 100644 index 0000000..500e3c6 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/scale.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/scissors.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/scissors.svg new file mode 100644 index 0000000..a23dc81 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/scissors.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/server-stack.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/server-stack.svg new file mode 100644 index 0000000..3b7fe32 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/server-stack.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/server.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/server.svg new file mode 100644 index 0000000..c1675f3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/server.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/share.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/share.svg new file mode 100644 index 0000000..125b6d1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/share.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/shield-check.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/shield-check.svg new file mode 100644 index 0000000..f9fa2b9 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/shield-check.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/shield-exclamation.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/shield-exclamation.svg new file mode 100644 index 0000000..b52a2ff --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/shield-exclamation.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/shopping-bag.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/shopping-bag.svg new file mode 100644 index 0000000..f5a51bd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/shopping-bag.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/shopping-cart.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/shopping-cart.svg new file mode 100644 index 0000000..661477b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/shopping-cart.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/signal-slash.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/signal-slash.svg new file mode 100644 index 0000000..62992c3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/signal-slash.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/signal.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/signal.svg new file mode 100644 index 0000000..56114d3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/signal.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/sparkles.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/sparkles.svg new file mode 100644 index 0000000..5a78b09 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/sparkles.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/speaker-wave.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/speaker-wave.svg new file mode 100644 index 0000000..1b6dde7 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/speaker-wave.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/speaker-x-mark.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/speaker-x-mark.svg new file mode 100644 index 0000000..427e21e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/speaker-x-mark.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/square-2-stack.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/square-2-stack.svg new file mode 100644 index 0000000..bc5e253 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/square-2-stack.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/square-3-stack-3d.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/square-3-stack-3d.svg new file mode 100644 index 0000000..8af2704 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/square-3-stack-3d.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/squares-2x2.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/squares-2x2.svg new file mode 100644 index 0000000..601366d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/squares-2x2.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/squares-plus.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/squares-plus.svg new file mode 100644 index 0000000..b8033c1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/squares-plus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/star.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/star.svg new file mode 100644 index 0000000..98aa481 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/star.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/stop-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/stop-circle.svg new file mode 100644 index 0000000..b570e8e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/stop-circle.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/stop.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/stop.svg new file mode 100644 index 0000000..4ee917a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/stop.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/sun.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/sun.svg new file mode 100644 index 0000000..5667cb3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/sun.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/swatch.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/swatch.svg new file mode 100644 index 0000000..5b136eb --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/swatch.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/table-cells.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/table-cells.svg new file mode 100644 index 0000000..cb37937 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/table-cells.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/tag.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/tag.svg new file mode 100644 index 0000000..9620545 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/tag.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/ticket.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/ticket.svg new file mode 100644 index 0000000..da2d69e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/ticket.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/trash.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/trash.svg new file mode 100644 index 0000000..0d32d58 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/trash.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/trophy.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/trophy.svg new file mode 100644 index 0000000..f846e52 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/trophy.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/truck.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/truck.svg new file mode 100644 index 0000000..6e1ea69 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/truck.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/tv.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/tv.svg new file mode 100644 index 0000000..7b8a706 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/tv.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/user-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/user-circle.svg new file mode 100644 index 0000000..a177f26 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/user-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/user-group.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/user-group.svg new file mode 100644 index 0000000..4e7089b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/user-group.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/user-minus.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/user-minus.svg new file mode 100644 index 0000000..703478e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/user-minus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/user-plus.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/user-plus.svg new file mode 100644 index 0000000..24533d1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/user-plus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/user.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/user.svg new file mode 100644 index 0000000..e9b6c20 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/user.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/users.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/users.svg new file mode 100644 index 0000000..87304a0 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/users.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/variable.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/variable.svg new file mode 100644 index 0000000..81fab04 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/variable.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/video-camera-slash.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/video-camera-slash.svg new file mode 100644 index 0000000..d1de13e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/video-camera-slash.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/video-camera.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/video-camera.svg new file mode 100644 index 0000000..aae1a19 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/video-camera.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/view-columns.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/view-columns.svg new file mode 100644 index 0000000..22a668e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/view-columns.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/viewfinder-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/viewfinder-circle.svg new file mode 100644 index 0000000..0583eef --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/viewfinder-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/wallet.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/wallet.svg new file mode 100644 index 0000000..8f19d64 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/wallet.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/wifi.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/wifi.svg new file mode 100644 index 0000000..084b3e1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/wifi.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/window.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/window.svg new file mode 100644 index 0000000..4ffea71 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/window.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/wrench-screwdriver.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/wrench-screwdriver.svg new file mode 100644 index 0000000..1023ae9 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/wrench-screwdriver.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/wrench.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/wrench.svg new file mode 100644 index 0000000..de3a6e2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/wrench.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/x-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/x-circle.svg new file mode 100644 index 0000000..294ba20 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/x-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/outline/x-mark.svg b/test_app/assets/vendor/heroicons/optimized/24/outline/x-mark.svg new file mode 100644 index 0000000..a6d9eb7 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/outline/x-mark.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/academic-cap.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/academic-cap.svg new file mode 100644 index 0000000..2a13ef2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/academic-cap.svg @@ -0,0 +1,5 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/adjustments-horizontal.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/adjustments-horizontal.svg new file mode 100644 index 0000000..ed9b950 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/adjustments-horizontal.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/adjustments-vertical.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/adjustments-vertical.svg new file mode 100644 index 0000000..fc4b90c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/adjustments-vertical.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/archive-box-arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/archive-box-arrow-down.svg new file mode 100644 index 0000000..5999b72 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/archive-box-arrow-down.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/archive-box-x-mark.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/archive-box-x-mark.svg new file mode 100644 index 0000000..e7dd0d6 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/archive-box-x-mark.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/archive-box.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/archive-box.svg new file mode 100644 index 0000000..74e0471 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/archive-box.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down-circle.svg new file mode 100644 index 0000000..c85a4ff --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down-left.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down-left.svg new file mode 100644 index 0000000..5cd0d4d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down-on-square-stack.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down-on-square-stack.svg new file mode 100644 index 0000000..d2ef0b3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down-on-square-stack.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down-on-square.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down-on-square.svg new file mode 100644 index 0000000..35eab41 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down-on-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down-right.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down-right.svg new file mode 100644 index 0000000..8c60942 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down-tray.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down-tray.svg new file mode 100644 index 0000000..a18c62d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down-tray.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down.svg new file mode 100644 index 0000000..5cb396b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-left-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-left-circle.svg new file mode 100644 index 0000000..a937f8e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-left-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-left-on-rectangle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-left-on-rectangle.svg new file mode 100644 index 0000000..972a85e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-left-on-rectangle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-left.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-left.svg new file mode 100644 index 0000000..51bef70 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-long-down.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-long-down.svg new file mode 100644 index 0000000..891774e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-long-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-long-left.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-long-left.svg new file mode 100644 index 0000000..aa12c0c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-long-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-long-right.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-long-right.svg new file mode 100644 index 0000000..0bcb6a0 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-long-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-long-up.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-long-up.svg new file mode 100644 index 0000000..b36d8e0 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-long-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-path-rounded-square.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-path-rounded-square.svg new file mode 100644 index 0000000..0808a57 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-path-rounded-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-path.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-path.svg new file mode 100644 index 0000000..48a71fd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-path.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-right-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-right-circle.svg new file mode 100644 index 0000000..424f75a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-right-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-right-on-rectangle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-right-on-rectangle.svg new file mode 100644 index 0000000..73a7a7e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-right-on-rectangle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-right.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-right.svg new file mode 100644 index 0000000..1b1bbd1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-small-down.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-small-down.svg new file mode 100644 index 0000000..790993f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-small-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-small-left.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-small-left.svg new file mode 100644 index 0000000..231b1b2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-small-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-small-right.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-small-right.svg new file mode 100644 index 0000000..5d91261 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-small-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-small-up.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-small-up.svg new file mode 100644 index 0000000..33b31cf --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-small-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-top-right-on-square.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-top-right-on-square.svg new file mode 100644 index 0000000..ac1bc37 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-top-right-on-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-trending-down.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-trending-down.svg new file mode 100644 index 0000000..f46b609 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-trending-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-trending-up.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-trending-up.svg new file mode 100644 index 0000000..f2ece6e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-trending-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up-circle.svg new file mode 100644 index 0000000..0a9999f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up-left.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up-left.svg new file mode 100644 index 0000000..b6f9c2e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up-on-square-stack.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up-on-square-stack.svg new file mode 100644 index 0000000..b661da7 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up-on-square-stack.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up-on-square.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up-on-square.svg new file mode 100644 index 0000000..cba893e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up-on-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up-right.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up-right.svg new file mode 100644 index 0000000..7554631 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up-tray.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up-tray.svg new file mode 100644 index 0000000..19093f6 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up-tray.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up.svg new file mode 100644 index 0000000..16f6c79 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-uturn-down.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-uturn-down.svg new file mode 100644 index 0000000..6975024 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-uturn-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-uturn-left.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-uturn-left.svg new file mode 100644 index 0000000..f0b679a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-uturn-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-uturn-right.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-uturn-right.svg new file mode 100644 index 0000000..2da0f98 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-uturn-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-uturn-up.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-uturn-up.svg new file mode 100644 index 0000000..8cfe23d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrow-uturn-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrows-pointing-in.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrows-pointing-in.svg new file mode 100644 index 0000000..604920f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrows-pointing-in.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrows-pointing-out.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrows-pointing-out.svg new file mode 100644 index 0000000..2399662 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrows-pointing-out.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrows-right-left.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrows-right-left.svg new file mode 100644 index 0000000..93fb7f1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrows-right-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/arrows-up-down.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/arrows-up-down.svg new file mode 100644 index 0000000..356e9ca --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/arrows-up-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/at-symbol.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/at-symbol.svg new file mode 100644 index 0000000..a02c654 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/at-symbol.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/backspace.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/backspace.svg new file mode 100644 index 0000000..e5a79c2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/backspace.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/backward.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/backward.svg new file mode 100644 index 0000000..bdf2a01 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/backward.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/banknotes.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/banknotes.svg new file mode 100644 index 0000000..1cc1803 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/banknotes.svg @@ -0,0 +1,5 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/bars-2.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/bars-2.svg new file mode 100644 index 0000000..6ee47ab --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/bars-2.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/bars-3-bottom-left.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/bars-3-bottom-left.svg new file mode 100644 index 0000000..a804c11 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/bars-3-bottom-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/bars-3-bottom-right.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/bars-3-bottom-right.svg new file mode 100644 index 0000000..2fd11ad --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/bars-3-bottom-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/bars-3-center-left.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/bars-3-center-left.svg new file mode 100644 index 0000000..9a2c170 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/bars-3-center-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/bars-3.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/bars-3.svg new file mode 100644 index 0000000..85584e8 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/bars-3.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/bars-4.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/bars-4.svg new file mode 100644 index 0000000..e3591d1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/bars-4.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/bars-arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/bars-arrow-down.svg new file mode 100644 index 0000000..10140b8 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/bars-arrow-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/bars-arrow-up.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/bars-arrow-up.svg new file mode 100644 index 0000000..4b3d4a7 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/bars-arrow-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/battery-0.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/battery-0.svg new file mode 100644 index 0000000..f03a737 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/battery-0.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/battery-100.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/battery-100.svg new file mode 100644 index 0000000..62e4ec9 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/battery-100.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/battery-50.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/battery-50.svg new file mode 100644 index 0000000..63344d7 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/battery-50.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/beaker.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/beaker.svg new file mode 100644 index 0000000..e0b73cc --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/beaker.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/bell-alert.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/bell-alert.svg new file mode 100644 index 0000000..f280b00 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/bell-alert.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/bell-slash.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/bell-slash.svg new file mode 100644 index 0000000..0ef076c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/bell-slash.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/bell-snooze.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/bell-snooze.svg new file mode 100644 index 0000000..cf93ae0 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/bell-snooze.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/bell.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/bell.svg new file mode 100644 index 0000000..818496e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/bell.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/bolt-slash.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/bolt-slash.svg new file mode 100644 index 0000000..59d24f7 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/bolt-slash.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/bolt.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/bolt.svg new file mode 100644 index 0000000..596c47a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/bolt.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/book-open.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/book-open.svg new file mode 100644 index 0000000..2e0a181 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/book-open.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/bookmark-slash.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/bookmark-slash.svg new file mode 100644 index 0000000..8435a02 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/bookmark-slash.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/bookmark-square.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/bookmark-square.svg new file mode 100644 index 0000000..a4d3ca5 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/bookmark-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/bookmark.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/bookmark.svg new file mode 100644 index 0000000..e9f3fb7 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/bookmark.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/briefcase.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/briefcase.svg new file mode 100644 index 0000000..a66af56 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/briefcase.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/bug-ant.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/bug-ant.svg new file mode 100644 index 0000000..3c16cbc --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/bug-ant.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/building-library.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/building-library.svg new file mode 100644 index 0000000..90f8640 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/building-library.svg @@ -0,0 +1,5 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/building-office-2.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/building-office-2.svg new file mode 100644 index 0000000..240eedb --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/building-office-2.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/building-office.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/building-office.svg new file mode 100644 index 0000000..9883e33 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/building-office.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/building-storefront.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/building-storefront.svg new file mode 100644 index 0000000..f3b54ba --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/building-storefront.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/cake.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/cake.svg new file mode 100644 index 0000000..f13b308 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/cake.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/calculator.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/calculator.svg new file mode 100644 index 0000000..e058510 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/calculator.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/calendar-days.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/calendar-days.svg new file mode 100644 index 0000000..0df9b16 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/calendar-days.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/calendar.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/calendar.svg new file mode 100644 index 0000000..27e208c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/calendar.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/camera.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/camera.svg new file mode 100644 index 0000000..e58165d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/camera.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/chart-bar-square.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/chart-bar-square.svg new file mode 100644 index 0000000..d4af840 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/chart-bar-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/chart-bar.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/chart-bar.svg new file mode 100644 index 0000000..abe5349 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/chart-bar.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/chart-pie.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/chart-pie.svg new file mode 100644 index 0000000..5aea729 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/chart-pie.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-bottom-center-text.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-bottom-center-text.svg new file mode 100644 index 0000000..bff24c4 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-bottom-center-text.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-bottom-center.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-bottom-center.svg new file mode 100644 index 0000000..eab7a41 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-bottom-center.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-left-ellipsis.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-left-ellipsis.svg new file mode 100644 index 0000000..1ee6159 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-left-ellipsis.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-left-right.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-left-right.svg new file mode 100644 index 0000000..80ad26d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-left-right.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-left.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-left.svg new file mode 100644 index 0000000..3dd81b7 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-oval-left-ellipsis.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-oval-left-ellipsis.svg new file mode 100644 index 0000000..815c6d7 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-oval-left-ellipsis.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-oval-left.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-oval-left.svg new file mode 100644 index 0000000..473b921 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/chat-bubble-oval-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/check-badge.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/check-badge.svg new file mode 100644 index 0000000..058b329 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/check-badge.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/check-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/check-circle.svg new file mode 100644 index 0000000..2b90831 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/check-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/check.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/check.svg new file mode 100644 index 0000000..2a6bc17 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/check.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-double-down.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-double-down.svg new file mode 100644 index 0000000..ddbe304 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-double-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-double-left.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-double-left.svg new file mode 100644 index 0000000..5c6539d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-double-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-double-right.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-double-right.svg new file mode 100644 index 0000000..7e25238 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-double-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-double-up.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-double-up.svg new file mode 100644 index 0000000..029e687 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-double-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-down.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-down.svg new file mode 100644 index 0000000..4f9ce7e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-left.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-left.svg new file mode 100644 index 0000000..2d89e8b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-left.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-right.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-right.svg new file mode 100644 index 0000000..36e4859 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-right.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-up-down.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-up-down.svg new file mode 100644 index 0000000..58edbc3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-up-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-up.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-up.svg new file mode 100644 index 0000000..9abe9cd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/chevron-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/circle-stack.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/circle-stack.svg new file mode 100644 index 0000000..5a49d80 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/circle-stack.svg @@ -0,0 +1,6 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/clipboard-document-check.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/clipboard-document-check.svg new file mode 100644 index 0000000..21ec021 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/clipboard-document-check.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/clipboard-document-list.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/clipboard-document-list.svg new file mode 100644 index 0000000..d60bed5 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/clipboard-document-list.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/clipboard-document.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/clipboard-document.svg new file mode 100644 index 0000000..d70b708 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/clipboard-document.svg @@ -0,0 +1,5 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/clipboard.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/clipboard.svg new file mode 100644 index 0000000..c09970f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/clipboard.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/clock.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/clock.svg new file mode 100644 index 0000000..1d6fb4a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/clock.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/cloud-arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/cloud-arrow-down.svg new file mode 100644 index 0000000..d6cf7c5 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/cloud-arrow-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/cloud-arrow-up.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/cloud-arrow-up.svg new file mode 100644 index 0000000..7e0dcee --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/cloud-arrow-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/cloud.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/cloud.svg new file mode 100644 index 0000000..95d0c73 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/cloud.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/code-bracket-square.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/code-bracket-square.svg new file mode 100644 index 0000000..103f73b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/code-bracket-square.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/code-bracket.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/code-bracket.svg new file mode 100644 index 0000000..9f331ef --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/code-bracket.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/cog-6-tooth.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/cog-6-tooth.svg new file mode 100644 index 0000000..ba6fca5 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/cog-6-tooth.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/cog-8-tooth.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/cog-8-tooth.svg new file mode 100644 index 0000000..9b9b1a6 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/cog-8-tooth.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/cog.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/cog.svg new file mode 100644 index 0000000..e854f73 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/cog.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/command-line.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/command-line.svg new file mode 100644 index 0000000..e2a0af8 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/command-line.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/computer-desktop.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/computer-desktop.svg new file mode 100644 index 0000000..5b7f2ef --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/computer-desktop.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/cpu-chip.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/cpu-chip.svg new file mode 100644 index 0000000..e20f6fb --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/cpu-chip.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/credit-card.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/credit-card.svg new file mode 100644 index 0000000..fe4dc14 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/credit-card.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/cube-transparent.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/cube-transparent.svg new file mode 100644 index 0000000..5577f26 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/cube-transparent.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/cube.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/cube.svg new file mode 100644 index 0000000..b0029f2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/cube.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/currency-bangladeshi.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/currency-bangladeshi.svg new file mode 100644 index 0000000..ca13c68 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/currency-bangladeshi.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/currency-dollar.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/currency-dollar.svg new file mode 100644 index 0000000..e0155df --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/currency-dollar.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/currency-euro.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/currency-euro.svg new file mode 100644 index 0000000..2926c25 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/currency-euro.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/currency-pound.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/currency-pound.svg new file mode 100644 index 0000000..547f725 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/currency-pound.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/currency-rupee.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/currency-rupee.svg new file mode 100644 index 0000000..2ee9b46 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/currency-rupee.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/currency-yen.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/currency-yen.svg new file mode 100644 index 0000000..65ef9bc --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/currency-yen.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/cursor-arrow-rays.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/cursor-arrow-rays.svg new file mode 100644 index 0000000..c0e462b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/cursor-arrow-rays.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/cursor-arrow-ripple.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/cursor-arrow-ripple.svg new file mode 100644 index 0000000..867faa4 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/cursor-arrow-ripple.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/device-phone-mobile.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/device-phone-mobile.svg new file mode 100644 index 0000000..eec0738 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/device-phone-mobile.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/device-tablet.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/device-tablet.svg new file mode 100644 index 0000000..88e2cc8 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/device-tablet.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/document-arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/document-arrow-down.svg new file mode 100644 index 0000000..77ac19c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/document-arrow-down.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/document-arrow-up.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/document-arrow-up.svg new file mode 100644 index 0000000..bc26cb9 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/document-arrow-up.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/document-chart-bar.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/document-chart-bar.svg new file mode 100644 index 0000000..83d0eac --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/document-chart-bar.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/document-check.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/document-check.svg new file mode 100644 index 0000000..e827854 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/document-check.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/document-duplicate.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/document-duplicate.svg new file mode 100644 index 0000000..fa7375d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/document-duplicate.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/document-magnifying-glass.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/document-magnifying-glass.svg new file mode 100644 index 0000000..ab165f7 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/document-magnifying-glass.svg @@ -0,0 +1,5 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/document-minus.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/document-minus.svg new file mode 100644 index 0000000..265c6eb --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/document-minus.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/document-plus.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/document-plus.svg new file mode 100644 index 0000000..5e31459 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/document-plus.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/document-text.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/document-text.svg new file mode 100644 index 0000000..73b30cd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/document-text.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/document.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/document.svg new file mode 100644 index 0000000..a05f20f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/document.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/ellipsis-horizontal-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/ellipsis-horizontal-circle.svg new file mode 100644 index 0000000..6ec2b50 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/ellipsis-horizontal-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/ellipsis-horizontal.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/ellipsis-horizontal.svg new file mode 100644 index 0000000..ddb5a3f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/ellipsis-horizontal.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/ellipsis-vertical.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/ellipsis-vertical.svg new file mode 100644 index 0000000..792c0ae --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/ellipsis-vertical.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/envelope-open.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/envelope-open.svg new file mode 100644 index 0000000..e6bf97b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/envelope-open.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/envelope.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/envelope.svg new file mode 100644 index 0000000..702341b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/envelope.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/exclamation-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/exclamation-circle.svg new file mode 100644 index 0000000..fdaadc0 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/exclamation-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/exclamation-triangle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/exclamation-triangle.svg new file mode 100644 index 0000000..627a712 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/exclamation-triangle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/eye-dropper.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/eye-dropper.svg new file mode 100644 index 0000000..15b16d0 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/eye-dropper.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/eye-slash.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/eye-slash.svg new file mode 100644 index 0000000..11ef99b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/eye-slash.svg @@ -0,0 +1,5 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/eye.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/eye.svg new file mode 100644 index 0000000..a648db3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/eye.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/face-frown.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/face-frown.svg new file mode 100644 index 0000000..7040d58 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/face-frown.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/face-smile.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/face-smile.svg new file mode 100644 index 0000000..d5e75a2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/face-smile.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/film.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/film.svg new file mode 100644 index 0000000..fbd26cc --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/film.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/finger-print.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/finger-print.svg new file mode 100644 index 0000000..68e72b4 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/finger-print.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/fire.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/fire.svg new file mode 100644 index 0000000..93b1b1f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/fire.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/flag.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/flag.svg new file mode 100644 index 0000000..8c67b01 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/flag.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/folder-arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/folder-arrow-down.svg new file mode 100644 index 0000000..5d963b4 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/folder-arrow-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/folder-minus.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/folder-minus.svg new file mode 100644 index 0000000..d0292b8 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/folder-minus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/folder-open.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/folder-open.svg new file mode 100644 index 0000000..b9d80ba --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/folder-open.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/folder-plus.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/folder-plus.svg new file mode 100644 index 0000000..efaf949 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/folder-plus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/folder.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/folder.svg new file mode 100644 index 0000000..a7847f8 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/folder.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/forward.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/forward.svg new file mode 100644 index 0000000..de90863 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/forward.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/funnel.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/funnel.svg new file mode 100644 index 0000000..fe5699f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/funnel.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/gif.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/gif.svg new file mode 100644 index 0000000..283e6e5 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/gif.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/gift-top.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/gift-top.svg new file mode 100644 index 0000000..4bd4e6f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/gift-top.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/gift.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/gift.svg new file mode 100644 index 0000000..2ca6c92 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/gift.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/globe-alt.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/globe-alt.svg new file mode 100644 index 0000000..0cbacae --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/globe-alt.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/globe-americas.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/globe-americas.svg new file mode 100644 index 0000000..5ae0d5d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/globe-americas.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/globe-asia-australia.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/globe-asia-australia.svg new file mode 100644 index 0000000..14249d6 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/globe-asia-australia.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/globe-europe-africa.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/globe-europe-africa.svg new file mode 100644 index 0000000..49a78fd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/globe-europe-africa.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/hand-raised.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/hand-raised.svg new file mode 100644 index 0000000..1717d51 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/hand-raised.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/hand-thumb-down.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/hand-thumb-down.svg new file mode 100644 index 0000000..7a2b9a6 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/hand-thumb-down.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/hand-thumb-up.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/hand-thumb-up.svg new file mode 100644 index 0000000..4942d2d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/hand-thumb-up.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/hashtag.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/hashtag.svg new file mode 100644 index 0000000..29e677d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/hashtag.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/heart.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/heart.svg new file mode 100644 index 0000000..b5f0d95 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/heart.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/home-modern.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/home-modern.svg new file mode 100644 index 0000000..488685a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/home-modern.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/home.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/home.svg new file mode 100644 index 0000000..ec0bae1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/home.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/identification.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/identification.svg new file mode 100644 index 0000000..829b24d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/identification.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/inbox-arrow-down.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/inbox-arrow-down.svg new file mode 100644 index 0000000..4fd220b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/inbox-arrow-down.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/inbox-stack.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/inbox-stack.svg new file mode 100644 index 0000000..fffab99 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/inbox-stack.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/inbox.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/inbox.svg new file mode 100644 index 0000000..b74380e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/inbox.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/information-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/information-circle.svg new file mode 100644 index 0000000..bd2723b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/information-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/key.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/key.svg new file mode 100644 index 0000000..6acee27 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/key.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/language.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/language.svg new file mode 100644 index 0000000..60d1aee --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/language.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/lifebuoy.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/lifebuoy.svg new file mode 100644 index 0000000..9ddc8d4 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/lifebuoy.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/light-bulb.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/light-bulb.svg new file mode 100644 index 0000000..ff49cb3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/light-bulb.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/link.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/link.svg new file mode 100644 index 0000000..a6dc093 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/link.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/list-bullet.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/list-bullet.svg new file mode 100644 index 0000000..7983877 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/list-bullet.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/lock-closed.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/lock-closed.svg new file mode 100644 index 0000000..8a5a6d7 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/lock-closed.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/lock-open.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/lock-open.svg new file mode 100644 index 0000000..4562f7e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/lock-open.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/magnifying-glass-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/magnifying-glass-circle.svg new file mode 100644 index 0000000..17a6f28 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/magnifying-glass-circle.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/magnifying-glass-minus.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/magnifying-glass-minus.svg new file mode 100644 index 0000000..06ae161 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/magnifying-glass-minus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/magnifying-glass-plus.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/magnifying-glass-plus.svg new file mode 100644 index 0000000..92040d0 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/magnifying-glass-plus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/magnifying-glass.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/magnifying-glass.svg new file mode 100644 index 0000000..b602e08 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/magnifying-glass.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/map-pin.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/map-pin.svg new file mode 100644 index 0000000..92e6785 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/map-pin.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/map.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/map.svg new file mode 100644 index 0000000..9d4f7dd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/map.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/megaphone.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/megaphone.svg new file mode 100644 index 0000000..b1f1e10 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/megaphone.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/microphone.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/microphone.svg new file mode 100644 index 0000000..a5f4cb6 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/microphone.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/minus-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/minus-circle.svg new file mode 100644 index 0000000..8c981ab --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/minus-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/minus-small.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/minus-small.svg new file mode 100644 index 0000000..782213e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/minus-small.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/minus.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/minus.svg new file mode 100644 index 0000000..1fa7117 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/minus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/moon.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/moon.svg new file mode 100644 index 0000000..97d5c5a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/moon.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/musical-note.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/musical-note.svg new file mode 100644 index 0000000..a9ab9b5 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/musical-note.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/newspaper.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/newspaper.svg new file mode 100644 index 0000000..d1f2c1e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/newspaper.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/no-symbol.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/no-symbol.svg new file mode 100644 index 0000000..42eb771 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/no-symbol.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/paint-brush.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/paint-brush.svg new file mode 100644 index 0000000..35fd5a6 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/paint-brush.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/paper-airplane.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/paper-airplane.svg new file mode 100644 index 0000000..9365a57 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/paper-airplane.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/paper-clip.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/paper-clip.svg new file mode 100644 index 0000000..0a0dcdd --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/paper-clip.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/pause-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/pause-circle.svg new file mode 100644 index 0000000..4fe4f2b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/pause-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/pause.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/pause.svg new file mode 100644 index 0000000..2e121ac --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/pause.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/pencil-square.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/pencil-square.svg new file mode 100644 index 0000000..5f4aaf8 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/pencil-square.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/pencil.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/pencil.svg new file mode 100644 index 0000000..78ec61a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/pencil.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/phone-arrow-down-left.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/phone-arrow-down-left.svg new file mode 100644 index 0000000..06f3ba0 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/phone-arrow-down-left.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/phone-arrow-up-right.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/phone-arrow-up-right.svg new file mode 100644 index 0000000..678c4f6 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/phone-arrow-up-right.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/phone-x-mark.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/phone-x-mark.svg new file mode 100644 index 0000000..a017a7d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/phone-x-mark.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/phone.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/phone.svg new file mode 100644 index 0000000..ca2a6bc --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/phone.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/photo.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/photo.svg new file mode 100644 index 0000000..57e023d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/photo.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/play-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/play-circle.svg new file mode 100644 index 0000000..752273a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/play-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/play-pause.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/play-pause.svg new file mode 100644 index 0000000..e5bb17c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/play-pause.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/play.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/play.svg new file mode 100644 index 0000000..da0e4e2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/play.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/plus-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/plus-circle.svg new file mode 100644 index 0000000..b45f965 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/plus-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/plus-small.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/plus-small.svg new file mode 100644 index 0000000..0c4b744 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/plus-small.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/plus.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/plus.svg new file mode 100644 index 0000000..85d3b14 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/plus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/power.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/power.svg new file mode 100644 index 0000000..2bf830f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/power.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/presentation-chart-bar.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/presentation-chart-bar.svg new file mode 100644 index 0000000..cb0bc9a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/presentation-chart-bar.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/presentation-chart-line.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/presentation-chart-line.svg new file mode 100644 index 0000000..54e10b2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/presentation-chart-line.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/printer.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/printer.svg new file mode 100644 index 0000000..4fce791 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/printer.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/puzzle-piece.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/puzzle-piece.svg new file mode 100644 index 0000000..4f85b37 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/puzzle-piece.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/qr-code.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/qr-code.svg new file mode 100644 index 0000000..7f676ca --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/qr-code.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/question-mark-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/question-mark-circle.svg new file mode 100644 index 0000000..2ae51be --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/question-mark-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/queue-list.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/queue-list.svg new file mode 100644 index 0000000..536fd88 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/queue-list.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/radio.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/radio.svg new file mode 100644 index 0000000..92ca514 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/radio.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/receipt-percent.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/receipt-percent.svg new file mode 100644 index 0000000..5eb6371 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/receipt-percent.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/receipt-refund.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/receipt-refund.svg new file mode 100644 index 0000000..6a1a154 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/receipt-refund.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/rectangle-group.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/rectangle-group.svg new file mode 100644 index 0000000..289d198 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/rectangle-group.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/rectangle-stack.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/rectangle-stack.svg new file mode 100644 index 0000000..82a1334 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/rectangle-stack.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/rocket-launch.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/rocket-launch.svg new file mode 100644 index 0000000..522fc64 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/rocket-launch.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/rss.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/rss.svg new file mode 100644 index 0000000..b9a8ab2 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/rss.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/scale.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/scale.svg new file mode 100644 index 0000000..b7e57c7 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/scale.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/scissors.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/scissors.svg new file mode 100644 index 0000000..9c971b3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/scissors.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/server-stack.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/server-stack.svg new file mode 100644 index 0000000..c0d3074 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/server-stack.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/server.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/server.svg new file mode 100644 index 0000000..55f9aed --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/server.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/share.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/share.svg new file mode 100644 index 0000000..8f45dfc --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/share.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/shield-check.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/shield-check.svg new file mode 100644 index 0000000..2596ace --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/shield-check.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/shield-exclamation.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/shield-exclamation.svg new file mode 100644 index 0000000..ce53fcc --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/shield-exclamation.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/shopping-bag.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/shopping-bag.svg new file mode 100644 index 0000000..e6503ee --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/shopping-bag.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/shopping-cart.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/shopping-cart.svg new file mode 100644 index 0000000..931a12f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/shopping-cart.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/signal-slash.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/signal-slash.svg new file mode 100644 index 0000000..21c65cb --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/signal-slash.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/signal.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/signal.svg new file mode 100644 index 0000000..9027aef --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/signal.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/sparkles.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/sparkles.svg new file mode 100644 index 0000000..0d8d0c1 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/sparkles.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/speaker-wave.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/speaker-wave.svg new file mode 100644 index 0000000..bd84477 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/speaker-wave.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/speaker-x-mark.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/speaker-x-mark.svg new file mode 100644 index 0000000..e71f1b6 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/speaker-x-mark.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/square-2-stack.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/square-2-stack.svg new file mode 100644 index 0000000..c3726a5 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/square-2-stack.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/square-3-stack-3d.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/square-3-stack-3d.svg new file mode 100644 index 0000000..8ed638d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/square-3-stack-3d.svg @@ -0,0 +1,5 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/squares-2x2.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/squares-2x2.svg new file mode 100644 index 0000000..475f6c3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/squares-2x2.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/squares-plus.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/squares-plus.svg new file mode 100644 index 0000000..88a2dda --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/squares-plus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/star.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/star.svg new file mode 100644 index 0000000..8509819 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/star.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/stop-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/stop-circle.svg new file mode 100644 index 0000000..8e57a2c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/stop-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/stop.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/stop.svg new file mode 100644 index 0000000..1bf426f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/stop.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/sun.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/sun.svg new file mode 100644 index 0000000..1b597fa --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/sun.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/swatch.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/swatch.svg new file mode 100644 index 0000000..9b26c03 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/swatch.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/table-cells.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/table-cells.svg new file mode 100644 index 0000000..151a30c --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/table-cells.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/tag.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/tag.svg new file mode 100644 index 0000000..efcd01b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/tag.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/ticket.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/ticket.svg new file mode 100644 index 0000000..e947c41 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/ticket.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/trash.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/trash.svg new file mode 100644 index 0000000..ed7bf43 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/trash.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/trophy.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/trophy.svg new file mode 100644 index 0000000..ed7ee15 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/trophy.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/truck.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/truck.svg new file mode 100644 index 0000000..c218da6 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/truck.svg @@ -0,0 +1,5 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/tv.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/tv.svg new file mode 100644 index 0000000..8f27026 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/tv.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/user-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/user-circle.svg new file mode 100644 index 0000000..978d0b8 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/user-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/user-group.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/user-group.svg new file mode 100644 index 0000000..7ae7600 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/user-group.svg @@ -0,0 +1,4 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/user-minus.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/user-minus.svg new file mode 100644 index 0000000..062a7c9 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/user-minus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/user-plus.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/user-plus.svg new file mode 100644 index 0000000..ef313fa --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/user-plus.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/user.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/user.svg new file mode 100644 index 0000000..207213d --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/user.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/users.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/users.svg new file mode 100644 index 0000000..2959115 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/users.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/variable.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/variable.svg new file mode 100644 index 0000000..5601cac --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/variable.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/video-camera-slash.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/video-camera-slash.svg new file mode 100644 index 0000000..2a344d5 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/video-camera-slash.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/video-camera.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/video-camera.svg new file mode 100644 index 0000000..55bf7b4 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/video-camera.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/view-columns.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/view-columns.svg new file mode 100644 index 0000000..f7295e3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/view-columns.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/viewfinder-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/viewfinder-circle.svg new file mode 100644 index 0000000..e04b727 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/viewfinder-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/wallet.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/wallet.svg new file mode 100644 index 0000000..001b38a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/wallet.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/wifi.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/wifi.svg new file mode 100644 index 0000000..eb4fd4e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/wifi.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/window.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/window.svg new file mode 100644 index 0000000..4de83b3 --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/window.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/wrench-screwdriver.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/wrench-screwdriver.svg new file mode 100644 index 0000000..b7e0e9e --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/wrench-screwdriver.svg @@ -0,0 +1,5 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/wrench.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/wrench.svg new file mode 100644 index 0000000..3b61d5b --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/wrench.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/x-circle.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/x-circle.svg new file mode 100644 index 0000000..913782a --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/x-circle.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/heroicons/optimized/24/solid/x-mark.svg b/test_app/assets/vendor/heroicons/optimized/24/solid/x-mark.svg new file mode 100644 index 0000000..e525a8f --- /dev/null +++ b/test_app/assets/vendor/heroicons/optimized/24/solid/x-mark.svg @@ -0,0 +1,3 @@ + diff --git a/test_app/assets/vendor/topbar.js b/test_app/assets/vendor/topbar.js new file mode 100644 index 0000000..4195727 --- /dev/null +++ b/test_app/assets/vendor/topbar.js @@ -0,0 +1,165 @@ +/** + * @license MIT + * topbar 2.0.0, 2023-02-04 + * https://buunguyen.github.io/topbar + * Copyright (c) 2021 Buu Nguyen + */ +(function (window, document) { + "use strict"; + + // https://gist.github.com/paulirish/1579671 + (function () { + var lastTime = 0; + var vendors = ["ms", "moz", "webkit", "o"]; + for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = + window[vendors[x] + "RequestAnimationFrame"]; + window.cancelAnimationFrame = + window[vendors[x] + "CancelAnimationFrame"] || + window[vendors[x] + "CancelRequestAnimationFrame"]; + } + if (!window.requestAnimationFrame) + window.requestAnimationFrame = function (callback, element) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16 - (currTime - lastTime)); + var id = window.setTimeout(function () { + callback(currTime + timeToCall); + }, timeToCall); + lastTime = currTime + timeToCall; + return id; + }; + if (!window.cancelAnimationFrame) + window.cancelAnimationFrame = function (id) { + clearTimeout(id); + }; + })(); + + var canvas, + currentProgress, + showing, + progressTimerId = null, + fadeTimerId = null, + delayTimerId = null, + addEvent = function (elem, type, handler) { + if (elem.addEventListener) elem.addEventListener(type, handler, false); + else if (elem.attachEvent) elem.attachEvent("on" + type, handler); + else elem["on" + type] = handler; + }, + options = { + autoRun: true, + barThickness: 3, + barColors: { + 0: "rgba(26, 188, 156, .9)", + ".25": "rgba(52, 152, 219, .9)", + ".50": "rgba(241, 196, 15, .9)", + ".75": "rgba(230, 126, 34, .9)", + "1.0": "rgba(211, 84, 0, .9)", + }, + shadowBlur: 10, + shadowColor: "rgba(0, 0, 0, .6)", + className: null, + }, + repaint = function () { + canvas.width = window.innerWidth; + canvas.height = options.barThickness * 5; // need space for shadow + + var ctx = canvas.getContext("2d"); + ctx.shadowBlur = options.shadowBlur; + ctx.shadowColor = options.shadowColor; + + var lineGradient = ctx.createLinearGradient(0, 0, canvas.width, 0); + for (var stop in options.barColors) + lineGradient.addColorStop(stop, options.barColors[stop]); + ctx.lineWidth = options.barThickness; + ctx.beginPath(); + ctx.moveTo(0, options.barThickness / 2); + ctx.lineTo( + Math.ceil(currentProgress * canvas.width), + options.barThickness / 2 + ); + ctx.strokeStyle = lineGradient; + ctx.stroke(); + }, + createCanvas = function () { + canvas = document.createElement("canvas"); + var style = canvas.style; + style.position = "fixed"; + style.top = style.left = style.right = style.margin = style.padding = 0; + style.zIndex = 100001; + style.display = "none"; + if (options.className) canvas.classList.add(options.className); + document.body.appendChild(canvas); + addEvent(window, "resize", repaint); + }, + topbar = { + config: function (opts) { + for (var key in opts) + if (options.hasOwnProperty(key)) options[key] = opts[key]; + }, + show: function (delay) { + if (showing) return; + if (delay) { + if (delayTimerId) return; + delayTimerId = setTimeout(() => topbar.show(), delay); + } else { + showing = true; + if (fadeTimerId !== null) window.cancelAnimationFrame(fadeTimerId); + if (!canvas) createCanvas(); + canvas.style.opacity = 1; + canvas.style.display = "block"; + topbar.progress(0); + if (options.autoRun) { + (function loop() { + progressTimerId = window.requestAnimationFrame(loop); + topbar.progress( + "+" + 0.05 * Math.pow(1 - Math.sqrt(currentProgress), 2) + ); + })(); + } + } + }, + progress: function (to) { + if (typeof to === "undefined") return currentProgress; + if (typeof to === "string") { + to = + (to.indexOf("+") >= 0 || to.indexOf("-") >= 0 + ? currentProgress + : 0) + parseFloat(to); + } + currentProgress = to > 1 ? 1 : to; + repaint(); + return currentProgress; + }, + hide: function () { + clearTimeout(delayTimerId); + delayTimerId = null; + if (!showing) return; + showing = false; + if (progressTimerId != null) { + window.cancelAnimationFrame(progressTimerId); + progressTimerId = null; + } + (function loop() { + if (topbar.progress("+.1") >= 1) { + canvas.style.opacity -= 0.05; + if (canvas.style.opacity <= 0.05) { + canvas.style.display = "none"; + fadeTimerId = null; + return; + } + } + fadeTimerId = window.requestAnimationFrame(loop); + })(); + }, + }; + + if (typeof module === "object" && typeof module.exports === "object") { + module.exports = topbar; + } else if (typeof define === "function" && define.amd) { + define(function () { + return topbar; + }); + } else { + this.topbar = topbar; + } +}.call(this, window, document)); diff --git a/test_app/config/config.exs b/test_app/config/config.exs index ee59105..3b49fd0 100644 --- a/test_app/config/config.exs +++ b/test_app/config/config.exs @@ -15,7 +15,29 @@ config :test_app, TestAppWeb.Endpoint, layout: false ], pubsub_server: TestApp.PubSub, - live_view: [signing_salt: "Yv51WWUs"] + live_view: [signing_salt: "nM329/CL"] + +# Configure esbuild (the version is required) +config :esbuild, + version: "0.17.11", + default: [ + args: + ~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/fonts/* --external:/images/*), + cd: Path.expand("../assets", __DIR__), + env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)} + ] + +# Configure tailwind (the version is required) +config :tailwind, + version: "3.3.2", + default: [ + args: ~w( + --config=tailwind.config.js + --input=css/app.css + --output=../priv/static/assets/app.css + ), + cd: Path.expand("../assets", __DIR__) + ] # Configures Elixir's Logger config :logger, :console, diff --git a/test_app/config/dev.exs b/test_app/config/dev.exs index ab4b449..4fadfae 100644 --- a/test_app/config/dev.exs +++ b/test_app/config/dev.exs @@ -13,8 +13,11 @@ config :test_app, TestAppWeb.Endpoint, check_origin: false, code_reloader: true, debug_errors: true, - secret_key_base: "/OOtixijCMkathudAQ6iWMDxAguNzdKOUBFOLZo/2h9IjzdYcX63RdVs4uvmdB3f", - watchers: [] + secret_key_base: "MVfVqvjONa3PIqwCiKp/rj4c/bjeUE7Mxljl1LOSHMCkCr8fuCxNvnkZIXC4wKhC", + watchers: [ + esbuild: {Esbuild, :install_and_run, [:default, ~w(--sourcemap=inline --watch)]}, + tailwind: {Tailwind, :install_and_run, [:default, ~w(--watch)]} + ] # ## SSL Support # @@ -44,6 +47,7 @@ config :test_app, TestAppWeb.Endpoint, live_reload: [ patterns: [ ~r"priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$", + ~r"priv/gettext/.*(po)$", ~r"lib/test_app_web/(controllers|live|components)/.*(ex|heex)$" ] ] diff --git a/test_app/config/prod.exs b/test_app/config/prod.exs index 1fe2d9e..4923c4d 100644 --- a/test_app/config/prod.exs +++ b/test_app/config/prod.exs @@ -1,5 +1,12 @@ import Config +# Note we also include the path to a cache manifest +# containing the digested version of static files. This +# manifest is generated by the `mix assets.deploy` task, +# which you should run after static files are built and +# before starting your production server. +config :test_app, TestAppWeb.Endpoint, cache_static_manifest: "priv/static/cache_manifest.json" + # Do not print debug messages in production config :logger, level: :info diff --git a/test_app/config/test.exs b/test_app/config/test.exs index b75a84e..6e55a53 100644 --- a/test_app/config/test.exs +++ b/test_app/config/test.exs @@ -4,7 +4,7 @@ import Config # you can enable the server option below. config :test_app, TestAppWeb.Endpoint, http: [ip: {127, 0, 0, 1}, port: 4002], - secret_key_base: "EdKwrnAZO/we479ohsBsJbnpaK+0LV2SONLY83a+FNvycfw2Rfp7C7WtVWSbrAZS", + secret_key_base: "X9+vRXpacKTuvdT9qeO0R9sVugBRbPumBqyOUCfohNTCFUz6OSTrplxm+dMsnExa", server: false # Print only warnings and errors during test diff --git a/test_app/lib/test_app_web/components/simple_tutorial/receiver.ex b/test_app/lib/test_app_web/components/simple_tutorial/receiver.ex new file mode 100644 index 0000000..8869532 --- /dev/null +++ b/test_app/lib/test_app_web/components/simple_tutorial/receiver.ex @@ -0,0 +1,24 @@ +defmodule TestAppWeb.Components.SimpleTutorial.Receiver do + use TestAppWeb, :live_component + use LiveViewEvents + + def mount(socket) do + socket = assign(socket, :messages, []) + + {:ok, socket} + end + + def update(assigns, socket) do + socket = handle_info_or_assign(socket, assigns) + + {:ok, socket} + end + + def render(assigns), do: ~H[] + + def handle_info({:sender_event, num}, socket) do + {:noreply, update(socket, :messages, &[num | &1])} + end +end diff --git a/test_app/lib/test_app_web/components/simple_tutorial/sender.ex b/test_app/lib/test_app_web/components/simple_tutorial/sender.ex new file mode 100644 index 0000000..88dde1c --- /dev/null +++ b/test_app/lib/test_app_web/components/simple_tutorial/sender.ex @@ -0,0 +1,30 @@ +defmodule TestAppWeb.Components.SimpleTutorial.Sender do + use TestAppWeb, :live_component + use LiveViewEvents + + def mount(socket) do + socket = assign(socket, :notify_to, :self) + + {:ok, socket} + end + + def render(assigns) do + ~H""" + + """ + end + + def handle_event("clicked", _params, socket) do + IO.inspect("clicked!!") + notify_to(socket.assigns.notify_to, :sender_event, :rand.uniform(100)) + + {:noreply, socket} + end + + def handle_event(message, _params, socket) do + IO.inspect(message, label: "Message received!") + {:noreply, socket} + end +end diff --git a/test_app/lib/test_app_web/live/simple_tutorial.ex b/test_app/lib/test_app_web/live/simple_tutorial.ex new file mode 100644 index 0000000..c62601a --- /dev/null +++ b/test_app/lib/test_app_web/live/simple_tutorial.ex @@ -0,0 +1,19 @@ +defmodule TestAppWeb.SimpleTutorialLive do + use TestAppWeb, :live_view + + alias TestAppWeb.Components.SimpleTutorial.Receiver + alias TestAppWeb.Components.SimpleTutorial.Sender + + def render(assigns) do + ~H""" +
+ <.live_component + module={Sender} + id="sender" + notify_to={{Receiver, "receiver"}} + /> + <.live_component module={Receiver} id="receiver" /> +
+ """ + end +end diff --git a/test_app/lib/test_app_web/router.ex b/test_app/lib/test_app_web/router.ex index 610970d..679871e 100644 --- a/test_app/lib/test_app_web/router.ex +++ b/test_app/lib/test_app_web/router.ex @@ -18,6 +18,7 @@ defmodule TestAppWeb.Router do pipe_through :browser get "/", PageController, :home + live "/simple_tutorial", SimpleTutorialLive, :index end # Other scopes may use custom stacks. diff --git a/test_app/mix.exs b/test_app/mix.exs index 577b07b..48900fc 100644 --- a/test_app/mix.exs +++ b/test_app/mix.exs @@ -46,6 +46,8 @@ defmodule TestApp.MixProject do {:phoenix_html, "~> 3.3"}, {:phoenix_live_reload, "~> 1.2", only: :dev}, {:phoenix_live_view, "~> #{phoenix_lv_version}"}, + {:esbuild, "~> 0.7", runtime: Mix.env() == :dev}, + {:tailwind, "~> 0.2.0", runtime: Mix.env() == :dev}, {:live_isolated_component, "~> 0.7.0", only: [:dev, :test]}, {:live_view_events, path: "./.."}, {:floki, ">= 0.30.0", only: :test}, diff --git a/test_app/mix.lock b/test_app/mix.lock index c3c790f..8e23a87 100644 --- a/test_app/mix.lock +++ b/test_app/mix.lock @@ -1,10 +1,13 @@ %{ - "castore": {:hex, :castore, "1.0.3", "7130ba6d24c8424014194676d608cb989f62ef8039efd50ff4b3f33286d06db8", [:mix], [], "hexpm", "680ab01ef5d15b161ed6a95449fac5c6b8f60055677a8e79acf01b27baa4390b"}, + "castore": {:hex, :castore, "1.0.4", "ff4d0fb2e6411c0479b1d965a814ea6d00e51eb2f58697446e9c41a97d940b28", [:mix], [], "hexpm", "9418c1b8144e11656f0be99943db4caf04612e3eaecefb5dae9a2a87565584f8"}, "cowboy": {:hex, :cowboy, "2.10.0", "ff9ffeff91dae4ae270dd975642997afe2a1179d94b1887863e43f681a203e26", [:make, :rebar3], [{:cowlib, "2.12.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "3afdccb7183cc6f143cb14d3cf51fa00e53db9ec80cdcd525482f5e99bc41d6b"}, "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, "cowlib": {:hex, :cowlib, "2.12.1", "a9fa9a625f1d2025fe6b462cb865881329b5caff8f1854d1cbc9f9533f00e1e1", [:make, :rebar3], [], "hexpm", "163b73f6367a7341b33c794c4e88e7dbfe6498ac42dcd69ef44c5bc5507c8db0"}, + "esbuild": {:hex, :esbuild, "0.7.1", "fa0947e8c3c3c2f86c9bf7e791a0a385007ccd42b86885e8e893bdb6631f5169", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "66661cdf70b1378ee4dc16573fcee67750b59761b2605a0207c267ab9d19f13c"}, + "expo": {:hex, :expo, "0.4.1", "1c61d18a5df197dfda38861673d392e642649a9cef7694d2f97a587b2cfb319b", [:mix], [], "hexpm", "2ff7ba7a798c8c543c12550fa0e2cbc81b95d4974c65855d8d15ba7b37a1ce47"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, "floki": {:hex, :floki, "0.34.3", "5e2dcaec5d7c228ce5b1d3501502e308b2d79eb655e4191751a1fe491c37feac", [:mix], [], "hexpm", "9577440eea5b97924b4bf3c7ea55f7b8b6dce589f9b28b096cc294a8dc342341"}, + "gettext": {:hex, :gettext, "0.23.1", "821e619a240e6000db2fc16a574ef68b3bd7fe0167ccc264a81563cc93e67a31", [:mix], [{:expo, "~> 0.4.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "19d744a36b809d810d610b57c27b934425859d158ebd56561bc41f7eeb8795db"}, "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, "live_isolated_component": {:hex, :live_isolated_component, "0.7.1", "9db55ee987484e58b75078ee62010659c8ec2e77afa1b3d6ec91de622c07f8e7", [:mix], [{:phoenix, "~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.19.0 or ~> 0.20.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "hexpm", "8a0f380a05b9cf196438ef37dee61d242ab7f6d9c4fa2c73bb8a69304ebfc9a1"}, "mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"}, @@ -15,10 +18,11 @@ "phoenix_live_view": {:hex, :phoenix_live_view, "0.20.0", "3f3531c835e46a3b45b4c3ca4a09cef7ba1d0f0d0035eef751c7084b8adb1299", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "29875f8a58fb031f2dc8f3be025c92ed78d342b46f9bbf6dfe579549d7c81050"}, "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.3", "3168d78ba41835aecad272d5e8cd51aa87a7ac9eb836eabc42f6e57538e3731d", [:mix], [], "hexpm", "bba06bc1dcfd8cb086759f0edc94a8ba2bc8896d5331a1e2c2902bf8e36ee502"}, "phoenix_template": {:hex, :phoenix_template, "1.0.3", "32de561eefcefa951aead30a1f94f1b5f0379bc9e340bb5c667f65f1edfa4326", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "16f4b6588a4152f3cc057b9d0c0ba7e82ee23afa65543da535313ad8d25d8e2c"}, - "plug": {:hex, :plug, "1.14.2", "cff7d4ec45b4ae176a227acd94a7ab536d9b37b942c8e8fa6dfc0fff98ff4d80", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "842fc50187e13cf4ac3b253d47d9474ed6c296a8732752835ce4a86acdf68d13"}, + "plug": {:hex, :plug, "1.15.1", "b7efd81c1a1286f13efb3f769de343236bd8b7d23b4a9f40d3002fc39ad8f74c", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "459497bd94d041d98d948054ec6c0b76feacd28eec38b219ca04c0de13c79d30"}, "plug_cowboy": {:hex, :plug_cowboy, "2.6.1", "9a3bbfceeb65eff5f39dab529e5cd79137ac36e913c02067dba3963a26efe9b2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "de36e1a21f451a18b790f37765db198075c25875c64834bcc82d90b309eb6613"}, "plug_crypto": {:hex, :plug_crypto, "1.2.5", "918772575e48e81e455818229bf719d4ab4181fcbf7f85b68a35620f78d89ced", [:mix], [], "hexpm", "26549a1d6345e2172eb1c233866756ae44a9609bd33ee6f99147ab3fd87fd842"}, "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, + "tailwind": {:hex, :tailwind, "0.2.1", "83d8eadbe71a8e8f67861fe7f8d51658ecfb258387123afe4d9dc194eddc36b0", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "e8a13f6107c95f73e58ed1b4221744e1eb5a093cd1da244432067e19c8c9a277"}, "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, "telemetry_metrics": {:hex, :telemetry_metrics, "0.6.1", "315d9163a1d4660aedc3fee73f33f1d355dcc76c5c3ab3d59e76e3edf80eef1f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7be9e0871c41732c233be71e4be11b96e56177bf15dde64a8ac9ce72ac9834c6"}, "telemetry_poller": {:hex, :telemetry_poller, "1.0.0", "db91bb424e07f2bb6e73926fcafbfcbcb295f0193e0a00e825e589a0a47e8453", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b3a24eafd66c3f42da30fc3ca7dda1e9d546c12250a2d60d7b81d264fbec4f6e"}, diff --git a/test_app/priv/gettext/en/LC_MESSAGES/errors.po b/test_app/priv/gettext/en/LC_MESSAGES/errors.po new file mode 100644 index 0000000..cdec3a1 --- /dev/null +++ b/test_app/priv/gettext/en/LC_MESSAGES/errors.po @@ -0,0 +1,11 @@ +## `msgid`s in this file come from POT (.pot) files. +## +## Do not add, change, or remove `msgid`s manually here as +## they're tied to the ones in the corresponding POT file +## (with the same domain). +## +## Use `mix gettext.extract --merge` or `mix gettext.merge` +## to merge POT files into PO files. +msgid "" +msgstr "" +"Language: en\n" diff --git a/test_app/priv/gettext/errors.pot b/test_app/priv/gettext/errors.pot new file mode 100644 index 0000000..d6f47fa --- /dev/null +++ b/test_app/priv/gettext/errors.pot @@ -0,0 +1,10 @@ +## This is a PO Template file. +## +## `msgid`s here are often extracted from source code. +## Add new translations manually only if they're dynamic +## translations that can't be statically extracted. +## +## Run `mix gettext.extract` to bring this file up to +## date. Leave `msgstr`s empty as changing them here has no +## effect: edit them in PO (`.po`) files instead. + diff --git a/test_app/priv/static/assets/app.css b/test_app/priv/static/assets/app.css index 35d6918..ed62622 100644 --- a/test_app/priv/static/assets/app.css +++ b/test_app/priv/static/assets/app.css @@ -1 +1,1838 @@ +/* +! tailwindcss v3.3.2 | MIT License | https://tailwindcss.com +*/ + +/* +1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) +2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) +*/ + +*, +::before, +::after { + box-sizing: border-box; + /* 1 */ + border-width: 0; + /* 2 */ + border-style: solid; + /* 2 */ + border-color: #e5e7eb; + /* 2 */ +} + +::before, +::after { + --tw-content: ''; +} + +/* +1. Use a consistent sensible line-height in all browsers. +2. Prevent adjustments of font size after orientation changes in iOS. +3. Use a more readable tab size. +4. Use the user's configured `sans` font-family by default. +5. Use the user's configured `sans` font-feature-settings by default. +6. Use the user's configured `sans` font-variation-settings by default. +*/ + +html { + line-height: 1.5; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ + -moz-tab-size: 4; + /* 3 */ + -o-tab-size: 4; + tab-size: 4; + /* 3 */ + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + /* 4 */ + font-feature-settings: normal; + /* 5 */ + font-variation-settings: normal; + /* 6 */ +} + +/* +1. Remove the margin in all browsers. +2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. +*/ + +body { + margin: 0; + /* 1 */ + line-height: inherit; + /* 2 */ +} + +/* +1. Add the correct height in Firefox. +2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) +3. Ensure horizontal rules are visible by default. +*/ + +hr { + height: 0; + /* 1 */ + color: inherit; + /* 2 */ + border-top-width: 1px; + /* 3 */ +} + +/* +Add the correct text decoration in Chrome, Edge, and Safari. +*/ + +abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; +} + +/* +Remove the default font size and weight for headings. +*/ + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: inherit; + font-weight: inherit; +} + +/* +Reset links to optimize for opt-in styling instead of opt-out. +*/ + +a { + color: inherit; + text-decoration: inherit; +} + +/* +Add the correct font weight in Edge and Safari. +*/ + +b, +strong { + font-weight: bolder; +} + +/* +1. Use the user's configured `mono` font family by default. +2. Correct the odd `em` font sizing in all browsers. +*/ + +code, +kbd, +samp, +pre { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + /* 1 */ + font-size: 1em; + /* 2 */ +} + +/* +Add the correct font size in all browsers. +*/ + +small { + font-size: 80%; +} + +/* +Prevent `sub` and `sup` elements from affecting the line height in all browsers. +*/ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* +1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) +2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) +3. Remove gaps between table borders by default. +*/ + +table { + text-indent: 0; + /* 1 */ + border-color: inherit; + /* 2 */ + border-collapse: collapse; + /* 3 */ +} + +/* +1. Change the font styles in all browsers. +2. Remove the margin in Firefox and Safari. +3. Remove default padding in all browsers. +*/ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; + /* 1 */ + font-size: 100%; + /* 1 */ + font-weight: inherit; + /* 1 */ + line-height: inherit; + /* 1 */ + color: inherit; + /* 1 */ + margin: 0; + /* 2 */ + padding: 0; + /* 3 */ +} + +/* +Remove the inheritance of text transform in Edge and Firefox. +*/ + +button, +select { + text-transform: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Remove default button styles. +*/ + +button, +[type='button'], +[type='reset'], +[type='submit'] { + -webkit-appearance: button; + /* 1 */ + background-color: transparent; + /* 2 */ + background-image: none; + /* 2 */ +} + +/* +Use the modern Firefox focus style for all focusable elements. +*/ + +:-moz-focusring { + outline: auto; +} + +/* +Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) +*/ + +:-moz-ui-invalid { + box-shadow: none; +} + +/* +Add the correct vertical alignment in Chrome and Firefox. +*/ + +progress { + vertical-align: baseline; +} + +/* +Correct the cursor style of increment and decrement buttons in Safari. +*/ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} + +/* +1. Correct the odd appearance in Chrome and Safari. +2. Correct the outline style in Safari. +*/ + +[type='search'] { + -webkit-appearance: textfield; + /* 1 */ + outline-offset: -2px; + /* 2 */ +} + +/* +Remove the inner padding in Chrome and Safari on macOS. +*/ + +::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Change font properties to `inherit` in Safari. +*/ + +::-webkit-file-upload-button { + -webkit-appearance: button; + /* 1 */ + font: inherit; + /* 2 */ +} + +/* +Add the correct display in Chrome and Safari. +*/ + +summary { + display: list-item; +} + +/* +Removes the default spacing and border for appropriate elements. +*/ + +blockquote, +dl, +dd, +h1, +h2, +h3, +h4, +h5, +h6, +hr, +figure, +p, +pre { + margin: 0; +} + +fieldset { + margin: 0; + padding: 0; +} + +legend { + padding: 0; +} + +ol, +ul, +menu { + list-style: none; + margin: 0; + padding: 0; +} + +/* +Prevent resizing textareas horizontally by default. +*/ + +textarea { + resize: vertical; +} + +/* +1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) +2. Set the default placeholder color to the user's configured gray 400 color. +*/ + +input::-moz-placeholder, textarea::-moz-placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +input::placeholder, +textarea::placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +/* +Set the default cursor for buttons. +*/ + +button, +[role="button"] { + cursor: pointer; +} + +/* +Make sure disabled buttons don't get the pointer cursor. +*/ + +:disabled { + cursor: default; +} + +/* +1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) +2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) + This can trigger a poorly considered lint error in some tools but is included by design. +*/ + +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object { + display: block; + /* 1 */ + vertical-align: middle; + /* 2 */ +} + +/* +Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) +*/ + +img, +video { + max-width: 100%; + height: auto; +} + +/* Make elements with the HTML hidden attribute stay hidden by default */ + +[hidden] { + display: none; +} + +[type='text'],[type='email'],[type='url'],[type='password'],[type='number'],[type='date'],[type='datetime-local'],[type='month'],[type='search'],[type='tel'],[type='time'],[type='week'],[multiple],textarea,select { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-color: #fff; + border-color: #6b7280; + border-width: 1px; + border-radius: 0px; + padding-top: 0.5rem; + padding-right: 0.75rem; + padding-bottom: 0.5rem; + padding-left: 0.75rem; + font-size: 1rem; + line-height: 1.5rem; + --tw-shadow: 0 0 #0000; +} + +[type='text']:focus, [type='email']:focus, [type='url']:focus, [type='password']:focus, [type='number']:focus, [type='date']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='week']:focus, [multiple]:focus, textarea:focus, select:focus { + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: #2563eb; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); + border-color: #2563eb; +} + +input::-moz-placeholder, textarea::-moz-placeholder { + color: #6b7280; + opacity: 1; +} + +input::placeholder,textarea::placeholder { + color: #6b7280; + opacity: 1; +} + +::-webkit-datetime-edit-fields-wrapper { + padding: 0; +} + +::-webkit-date-and-time-value { + min-height: 1.5em; +} + +::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field { + padding-top: 0; + padding-bottom: 0; +} + +select { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e"); + background-position: right 0.5rem center; + background-repeat: no-repeat; + background-size: 1.5em 1.5em; + padding-right: 2.5rem; + -webkit-print-color-adjust: exact; + print-color-adjust: exact; +} + +[multiple] { + background-image: initial; + background-position: initial; + background-repeat: unset; + background-size: initial; + padding-right: 0.75rem; + -webkit-print-color-adjust: unset; + print-color-adjust: unset; +} + +[type='checkbox'],[type='radio'] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + padding: 0; + -webkit-print-color-adjust: exact; + print-color-adjust: exact; + display: inline-block; + vertical-align: middle; + background-origin: border-box; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + flex-shrink: 0; + height: 1rem; + width: 1rem; + color: #2563eb; + background-color: #fff; + border-color: #6b7280; + border-width: 1px; + --tw-shadow: 0 0 #0000; +} + +[type='checkbox'] { + border-radius: 0px; +} + +[type='radio'] { + border-radius: 100%; +} + +[type='checkbox']:focus,[type='radio']:focus { + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: #fff; + --tw-ring-color: #2563eb; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); +} + +[type='checkbox']:checked,[type='radio']:checked { + border-color: transparent; + background-color: currentColor; + background-size: 100% 100%; + background-position: center; + background-repeat: no-repeat; +} + +[type='checkbox']:checked { + background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e"); +} + +[type='radio']:checked { + background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e"); +} + +[type='checkbox']:checked:hover,[type='checkbox']:checked:focus,[type='radio']:checked:hover,[type='radio']:checked:focus { + border-color: transparent; + background-color: currentColor; +} + +[type='checkbox']:indeterminate { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e"); + border-color: transparent; + background-color: currentColor; + background-size: 100% 100%; + background-position: center; + background-repeat: no-repeat; +} + +[type='checkbox']:indeterminate:hover,[type='checkbox']:indeterminate:focus { + border-color: transparent; + background-color: currentColor; +} + +[type='file'] { + background: unset; + border-color: inherit; + border-width: 0; + border-radius: 0; + padding: 0; + font-size: unset; + line-height: inherit; +} + +[type='file']:focus { + outline: 1px solid ButtonText; + outline: 1px auto -webkit-focus-ring-color; +} + +*, ::before, ::after { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} + +::backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} + +.container { + width: 100%; +} + +@media (min-width: 640px) { + .container { + max-width: 640px; + } +} + +@media (min-width: 768px) { + .container { + max-width: 768px; + } +} + +@media (min-width: 1024px) { + .container { + max-width: 1024px; + } +} + +@media (min-width: 1280px) { + .container { + max-width: 1280px; + } +} + +@media (min-width: 1536px) { + .container { + max-width: 1536px; + } +} + +.hero-arrow-left-solid { + --hero-arrow-left-solid: url('data:image/svg+xml;utf8,'); + -webkit-mask: var(--hero-arrow-left-solid); + mask: var(--hero-arrow-left-solid); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + background-color: currentColor; + vertical-align: middle; + display: inline-block; + width: 1.25rem; + height: 1.25rem; +} + +.hero-arrow-path { + --hero-arrow-path: url('data:image/svg+xml;utf8,'); + -webkit-mask: var(--hero-arrow-path); + mask: var(--hero-arrow-path); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + background-color: currentColor; + vertical-align: middle; + display: inline-block; + width: 1.25rem; + height: 1.25rem; +} + +.hero-exclamation-circle-mini { + --hero-exclamation-circle-mini: url('data:image/svg+xml;utf8,'); + -webkit-mask: var(--hero-exclamation-circle-mini); + mask: var(--hero-exclamation-circle-mini); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + background-color: currentColor; + vertical-align: middle; + display: inline-block; + width: 1.25rem; + height: 1.25rem; +} + +.hero-information-circle-mini { + --hero-information-circle-mini: url('data:image/svg+xml;utf8,'); + -webkit-mask: var(--hero-information-circle-mini); + mask: var(--hero-information-circle-mini); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + background-color: currentColor; + vertical-align: middle; + display: inline-block; + width: 1.25rem; + height: 1.25rem; +} + +.hero-x-mark-solid { + --hero-x-mark-solid: url('data:image/svg+xml;utf8,'); + -webkit-mask: var(--hero-x-mark-solid); + mask: var(--hero-x-mark-solid); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + background-color: currentColor; + vertical-align: middle; + display: inline-block; + width: 1.25rem; + height: 1.25rem; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; +} + +.static { + position: static; +} + +.fixed { + position: fixed; +} + +.absolute { + position: absolute; +} + +.relative { + position: relative; +} + +.inset-0 { + inset: 0px; +} + +.-inset-y-px { + top: -1px; + bottom: -1px; +} + +.inset-y-0 { + top: 0px; + bottom: 0px; +} + +.-left-4 { + left: -1rem; +} + +.-right-4 { + right: -1rem; +} + +.left-0 { + left: 0px; +} + +.left-\[40rem\] { + left: 40rem; +} + +.right-0 { + right: 0px; +} + +.right-1 { + right: 0.25rem; +} + +.right-2 { + right: 0.5rem; +} + +.right-5 { + right: 1.25rem; +} + +.top-1 { + top: 0.25rem; +} + +.top-2 { + top: 0.5rem; +} + +.top-6 { + top: 1.5rem; +} + +.z-0 { + z-index: 0; +} + +.z-50 { + z-index: 50; +} + +.-m-3 { + margin: -0.75rem; +} + +.-mx-2 { + margin-left: -0.5rem; + margin-right: -0.5rem; +} + +.-my-0 { + margin-top: -0px; + margin-bottom: -0px; +} + +.-my-0\.5 { + margin-top: -0.125rem; + margin-bottom: -0.125rem; +} + +.-my-4 { + margin-top: -1rem; + margin-bottom: -1rem; +} + +.mx-auto { + margin-left: auto; + margin-right: auto; +} + +.ml-1 { + margin-left: 0.25rem; +} + +.ml-2 { + margin-left: 0.5rem; +} + +.ml-3 { + margin-left: 0.75rem; +} + +.ml-4 { + margin-left: 1rem; +} + +.mt-0 { + margin-top: 0px; +} + +.mt-0\.5 { + margin-top: 0.125rem; +} + +.mt-10 { + margin-top: 2.5rem; +} + +.mt-11 { + margin-top: 2.75rem; +} + +.mt-14 { + margin-top: 3.5rem; +} + +.mt-16 { + margin-top: 4rem; +} + +.mt-2 { + margin-top: 0.5rem; +} + +.mt-3 { + margin-top: 0.75rem; +} + +.mt-4 { + margin-top: 1rem; +} + +.block { + display: block; +} + +.flex { + display: flex; +} + +.inline-flex { + display: inline-flex; +} + +.table { + display: table; +} + +.grid { + display: grid; +} + +.contents { + display: contents; +} + +.hidden { + display: none; +} + +.h-12 { + height: 3rem; +} + +.h-3 { + height: 0.75rem; +} + +.h-4 { + height: 1rem; +} + +.h-5 { + height: 1.25rem; +} + +.h-6 { + height: 1.5rem; +} + +.h-full { + height: 100%; +} + +.min-h-\[6rem\] { + min-height: 6rem; +} + +.min-h-full { + min-height: 100%; +} + +.w-1\/4 { + width: 25%; +} + +.w-14 { + width: 3.5rem; +} + +.w-3 { + width: 0.75rem; +} + +.w-4 { + width: 1rem; +} + +.w-5 { + width: 1.25rem; +} + +.w-6 { + width: 1.5rem; +} + +.w-80 { + width: 20rem; +} + +.w-\[40rem\] { + width: 40rem; +} + +.w-full { + width: 100%; +} + +.max-w-2xl { + max-width: 42rem; +} + +.max-w-3xl { + max-width: 48rem; +} + +.max-w-xl { + max-width: 36rem; +} + +.flex-none { + flex: none; +} + +.translate-y-0 { + --tw-translate-y: 0px; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.translate-y-4 { + --tw-translate-y: 1rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.transform { + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +.animate-spin { + animation: spin 1s linear infinite; +} + +.grid-cols-1 { + grid-template-columns: repeat(1, minmax(0, 1fr)); +} + +.items-center { + align-items: center; +} + +.justify-center { + justify-content: center; +} + +.justify-between { + justify-content: space-between; +} + +.gap-1 { + gap: 0.25rem; +} + +.gap-1\.5 { + gap: 0.375rem; +} + +.gap-3 { + gap: 0.75rem; +} + +.gap-4 { + gap: 1rem; +} + +.gap-6 { + gap: 1.5rem; +} + +.gap-x-6 { + -moz-column-gap: 1.5rem; + column-gap: 1.5rem; +} + +.gap-y-4 { + row-gap: 1rem; +} + +.space-y-8 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(2rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(2rem * var(--tw-space-y-reverse)); +} + +.divide-y > :not([hidden]) ~ :not([hidden]) { + --tw-divide-y-reverse: 0; + border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse))); + border-bottom-width: calc(1px * var(--tw-divide-y-reverse)); +} + +.divide-zinc-100 > :not([hidden]) ~ :not([hidden]) { + --tw-divide-opacity: 1; + border-color: rgb(244 244 245 / var(--tw-divide-opacity)); +} + +.overflow-hidden { + overflow: hidden; +} + +.overflow-y-auto { + overflow-y: auto; +} + +.whitespace-nowrap { + white-space: nowrap; +} + +.rounded { + border-radius: 0.25rem; +} + +.rounded-2xl { + border-radius: 1rem; +} + +.rounded-full { + border-radius: 9999px; +} + +.rounded-lg { + border-radius: 0.5rem; +} + +.rounded-md { + border-radius: 0.375rem; +} + +.border { + border-width: 1px; +} + +.border-b { + border-bottom-width: 1px; +} + +.border-t { + border-top-width: 1px; +} + +.border-gray-300 { + --tw-border-opacity: 1; + border-color: rgb(209 213 219 / var(--tw-border-opacity)); +} + +.border-rose-400 { + --tw-border-opacity: 1; + border-color: rgb(251 113 133 / var(--tw-border-opacity)); +} + +.border-zinc-100 { + --tw-border-opacity: 1; + border-color: rgb(244 244 245 / var(--tw-border-opacity)); +} + +.border-zinc-200 { + --tw-border-opacity: 1; + border-color: rgb(228 228 231 / var(--tw-border-opacity)); +} + +.border-zinc-300 { + --tw-border-opacity: 1; + border-color: rgb(212 212 216 / var(--tw-border-opacity)); +} + +.bg-brand\/5 { + background-color: rgb(253 79 0 / 0.05); +} + +.bg-emerald-50 { + --tw-bg-opacity: 1; + background-color: rgb(236 253 245 / var(--tw-bg-opacity)); +} + +.bg-rose-50 { + --tw-bg-opacity: 1; + background-color: rgb(255 241 242 / var(--tw-bg-opacity)); +} + +.bg-white { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); +} + +.bg-zinc-100 { + --tw-bg-opacity: 1; + background-color: rgb(244 244 245 / var(--tw-bg-opacity)); +} + +.bg-zinc-50 { + --tw-bg-opacity: 1; + background-color: rgb(250 250 250 / var(--tw-bg-opacity)); +} + +.bg-zinc-50\/90 { + background-color: rgb(250 250 250 / 0.9); +} + +.bg-zinc-900 { + --tw-bg-opacity: 1; + background-color: rgb(24 24 27 / var(--tw-bg-opacity)); +} + +.fill-cyan-900 { + fill: #164e63; +} + +.fill-rose-900 { + fill: #881337; +} + +.fill-zinc-400 { + fill: #a1a1aa; +} + +.p-0 { + padding: 0px; +} + +.p-14 { + padding: 3.5rem; +} + +.p-2 { + padding: 0.5rem; +} + +.p-3 { + padding: 0.75rem; +} + +.p-4 { + padding: 1rem; +} + +.px-2 { + padding-left: 0.5rem; + padding-right: 0.5rem; +} + +.px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; +} + +.px-4 { + padding-left: 1rem; + padding-right: 1rem; +} + +.px-6 { + padding-left: 1.5rem; + padding-right: 1.5rem; +} + +.py-0 { + padding-top: 0px; + padding-bottom: 0px; +} + +.py-0\.5 { + padding-top: 0.125rem; + padding-bottom: 0.125rem; +} + +.py-1 { + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} + +.py-10 { + padding-top: 2.5rem; + padding-bottom: 2.5rem; +} + +.py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.py-20 { + padding-top: 5rem; + padding-bottom: 5rem; +} + +.py-3 { + padding-top: 0.75rem; + padding-bottom: 0.75rem; +} + +.py-4 { + padding-top: 1rem; + padding-bottom: 1rem; +} + +.pb-4 { + padding-bottom: 1rem; +} + +.pr-6 { + padding-right: 1.5rem; +} + +.text-left { + text-align: left; +} + +.text-right { + text-align: right; +} + +.text-\[0\.8125rem\] { + font-size: 0.8125rem; +} + +.text-\[2rem\] { + font-size: 2rem; +} + +.text-base { + font-size: 1rem; + line-height: 1.5rem; +} + +.text-lg { + font-size: 1.125rem; + line-height: 1.75rem; +} + +.text-sm { + font-size: 0.875rem; + line-height: 1.25rem; +} + +.font-medium { + font-weight: 500; +} + +.font-normal { + font-weight: 400; +} + +.font-semibold { + font-weight: 600; +} + +.leading-10 { + line-height: 2.5rem; +} + +.leading-5 { + line-height: 1.25rem; +} + +.leading-6 { + line-height: 1.5rem; +} + +.leading-7 { + line-height: 1.75rem; +} + +.leading-8 { + line-height: 2rem; +} + +.tracking-tighter { + letter-spacing: -0.05em; +} + +.text-brand { + --tw-text-opacity: 1; + color: rgb(253 79 0 / var(--tw-text-opacity)); +} + +.text-emerald-800 { + --tw-text-opacity: 1; + color: rgb(6 95 70 / var(--tw-text-opacity)); +} + +.text-rose-600 { + --tw-text-opacity: 1; + color: rgb(225 29 72 / var(--tw-text-opacity)); +} + +.text-rose-900 { + --tw-text-opacity: 1; + color: rgb(136 19 55 / var(--tw-text-opacity)); +} + +.text-white { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + +.text-zinc-500 { + --tw-text-opacity: 1; + color: rgb(113 113 122 / var(--tw-text-opacity)); +} + +.text-zinc-600 { + --tw-text-opacity: 1; + color: rgb(82 82 91 / var(--tw-text-opacity)); +} + +.text-zinc-700 { + --tw-text-opacity: 1; + color: rgb(63 63 70 / var(--tw-text-opacity)); +} + +.text-zinc-800 { + --tw-text-opacity: 1; + color: rgb(39 39 42 / var(--tw-text-opacity)); +} + +.text-zinc-900 { + --tw-text-opacity: 1; + color: rgb(24 24 27 / var(--tw-text-opacity)); +} + +.antialiased { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.opacity-0 { + opacity: 0; +} + +.opacity-100 { + opacity: 1; +} + +.opacity-20 { + opacity: 0.2; +} + +.opacity-40 { + opacity: 0.4; +} + +.shadow-lg { + --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-md { + --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-sm { + --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); + --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-zinc-700\/10 { + --tw-shadow-color: rgb(63 63 70 / 0.1); + --tw-shadow: var(--tw-shadow-colored); +} + +.outline { + outline-style: solid; +} + +.ring-1 { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); +} + +.ring-emerald-500 { + --tw-ring-opacity: 1; + --tw-ring-color: rgb(16 185 129 / var(--tw-ring-opacity)); +} + +.ring-rose-500 { + --tw-ring-opacity: 1; + --tw-ring-color: rgb(244 63 94 / var(--tw-ring-opacity)); +} + +.ring-zinc-700\/10 { + --tw-ring-color: rgb(63 63 70 / 0.1); +} + +.transition { + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.transition-all { + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.transition-opacity { + transition-property: opacity; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.duration-200 { + transition-duration: 200ms; +} + +.duration-300 { + transition-duration: 300ms; +} + +.ease-in { + transition-timing-function: cubic-bezier(0.4, 0, 1, 1); +} + +.ease-out { + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); +} + +.\[scrollbar-gutter\:stable\] { + scrollbar-gutter: stable; +} + /* This file is for your main application CSS */ + +.hover\:cursor-pointer:hover { + cursor: pointer; +} + +.hover\:bg-zinc-200\/80:hover { + background-color: rgb(228 228 231 / 0.8); +} + +.hover\:bg-zinc-50:hover { + --tw-bg-opacity: 1; + background-color: rgb(250 250 250 / var(--tw-bg-opacity)); +} + +.hover\:bg-zinc-700:hover { + --tw-bg-opacity: 1; + background-color: rgb(63 63 70 / var(--tw-bg-opacity)); +} + +.hover\:text-zinc-700:hover { + --tw-text-opacity: 1; + color: rgb(63 63 70 / var(--tw-text-opacity)); +} + +.hover\:text-zinc-900:hover { + --tw-text-opacity: 1; + color: rgb(24 24 27 / var(--tw-text-opacity)); +} + +.hover\:opacity-40:hover { + opacity: 0.4; +} + +.focus\:border-rose-400:focus { + --tw-border-opacity: 1; + border-color: rgb(251 113 133 / var(--tw-border-opacity)); +} + +.focus\:border-zinc-400:focus { + --tw-border-opacity: 1; + border-color: rgb(161 161 170 / var(--tw-border-opacity)); +} + +.focus\:ring-0:focus { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); +} + +.active\:text-white\/80:active { + color: rgb(255 255 255 / 0.8); +} + +.group:hover .group-hover\:bg-zinc-100 { + --tw-bg-opacity: 1; + background-color: rgb(244 244 245 / var(--tw-bg-opacity)); +} + +.group:hover .group-hover\:bg-zinc-50 { + --tw-bg-opacity: 1; + background-color: rgb(250 250 250 / var(--tw-bg-opacity)); +} + +.group:hover .group-hover\:fill-zinc-600 { + fill: #52525b; +} + +.group:hover .group-hover\:opacity-70 { + opacity: 0.7; +} + +.phx-no-feedback.phx-no-feedback\:hidden { + display: none; +} + +.phx-no-feedback.phx-no-feedback\:border-zinc-300 { + --tw-border-opacity: 1; + border-color: rgb(212 212 216 / var(--tw-border-opacity)); +} + +.phx-no-feedback.phx-no-feedback\:focus\:border-zinc-400:focus { + --tw-border-opacity: 1; + border-color: rgb(161 161 170 / var(--tw-border-opacity)); +} + +.phx-no-feedback .phx-no-feedback\:hidden { + display: none; +} + +.phx-no-feedback .phx-no-feedback\:border-zinc-300 { + --tw-border-opacity: 1; + border-color: rgb(212 212 216 / var(--tw-border-opacity)); +} + +.phx-no-feedback .phx-no-feedback\:focus\:border-zinc-400:focus { + --tw-border-opacity: 1; + border-color: rgb(161 161 170 / var(--tw-border-opacity)); +} + +.phx-submit-loading.phx-submit-loading\:opacity-75 { + opacity: 0.75; +} + +.phx-submit-loading .phx-submit-loading\:opacity-75 { + opacity: 0.75; +} + +@media (min-width: 640px) { + .sm\:w-96 { + width: 24rem; + } + + .sm\:w-auto { + width: auto; + } + + .sm\:w-full { + width: 100%; + } + + .sm\:translate-y-0 { + --tw-translate-y: 0px; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + } + + .sm\:scale-100 { + --tw-scale-x: 1; + --tw-scale-y: 1; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + } + + .sm\:scale-95 { + --tw-scale-x: .95; + --tw-scale-y: .95; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + } + + .sm\:grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .sm\:grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .sm\:flex-col { + flex-direction: column; + } + + .sm\:gap-8 { + gap: 2rem; + } + + .sm\:overflow-visible { + overflow: visible; + } + + .sm\:rounded-l-xl { + border-top-left-radius: 0.75rem; + border-bottom-left-radius: 0.75rem; + } + + .sm\:rounded-r-xl { + border-top-right-radius: 0.75rem; + border-bottom-right-radius: 0.75rem; + } + + .sm\:p-6 { + padding: 1.5rem; + } + + .sm\:px-0 { + padding-left: 0px; + padding-right: 0px; + } + + .sm\:px-6 { + padding-left: 1.5rem; + padding-right: 1.5rem; + } + + .sm\:py-28 { + padding-top: 7rem; + padding-bottom: 7rem; + } + + .sm\:py-6 { + padding-top: 1.5rem; + padding-bottom: 1.5rem; + } + + .sm\:text-sm { + font-size: 0.875rem; + line-height: 1.25rem; + } + + .sm\:leading-6 { + line-height: 1.5rem; + } + + .group:hover .sm\:group-hover\:scale-105 { + --tw-scale-x: 1.05; + --tw-scale-y: 1.05; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + } +} + +@media (min-width: 1024px) { + .lg\:mx-0 { + margin-left: 0px; + margin-right: 0px; + } + + .lg\:block { + display: block; + } + + .lg\:px-8 { + padding-left: 2rem; + padding-right: 2rem; + } + + .lg\:py-8 { + padding-top: 2rem; + padding-bottom: 2rem; + } +} + +@media (min-width: 1280px) { + .xl\:left-\[50rem\] { + left: 50rem; + } + + .xl\:px-28 { + padding-left: 7rem; + padding-right: 7rem; + } + + .xl\:py-32 { + padding-top: 8rem; + padding-bottom: 8rem; + } +} diff --git a/test_app/priv/static/assets/app.js b/test_app/priv/static/assets/app.js index 4d5caaa..aff35aa 100644 --- a/test_app/priv/static/assets/app.js +++ b/test_app/priv/static/assets/app.js @@ -1,11 +1,5777 @@ -// For Phoenix.HTML support, including form and button helpers -// copy the following scripts into your javascript bundle: -// * deps/phoenix_html/priv/static/phoenix_html.js +(() => { + var __create = Object.create; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __getOwnPropSymbols = Object.getOwnPropertySymbols; + var __getProtoOf = Object.getPrototypeOf; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __propIsEnum = Object.prototype.propertyIsEnumerable; + var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; + var __spreadValues = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp.call(b, prop)) + __defNormalProp(a, prop, b[prop]); + if (__getOwnPropSymbols) + for (var prop of __getOwnPropSymbols(b)) { + if (__propIsEnum.call(b, prop)) + __defNormalProp(a, prop, b[prop]); + } + return a; + }; + var __objRest = (source, exclude) => { + var target = {}; + for (var prop in source) + if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0) + target[prop] = source[prop]; + if (source != null && __getOwnPropSymbols) + for (var prop of __getOwnPropSymbols(source)) { + if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop)) + target[prop] = source[prop]; + } + return target; + }; + var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod + )); -// For Phoenix.Channels support, copy the following scripts -// into your javascript bundle: -// * deps/phoenix/priv/static/phoenix.js + // vendor/topbar.js + var require_topbar = __commonJS({ + "vendor/topbar.js"(exports, module) { + (function(window2, document2) { + "use strict"; + (function() { + var lastTime = 0; + var vendors = ["ms", "moz", "webkit", "o"]; + for (var x = 0; x < vendors.length && !window2.requestAnimationFrame; ++x) { + window2.requestAnimationFrame = window2[vendors[x] + "RequestAnimationFrame"]; + window2.cancelAnimationFrame = window2[vendors[x] + "CancelAnimationFrame"] || window2[vendors[x] + "CancelRequestAnimationFrame"]; + } + if (!window2.requestAnimationFrame) + window2.requestAnimationFrame = function(callback, element) { + var currTime = (/* @__PURE__ */ new Date()).getTime(); + var timeToCall = Math.max(0, 16 - (currTime - lastTime)); + var id = window2.setTimeout(function() { + callback(currTime + timeToCall); + }, timeToCall); + lastTime = currTime + timeToCall; + return id; + }; + if (!window2.cancelAnimationFrame) + window2.cancelAnimationFrame = function(id) { + clearTimeout(id); + }; + })(); + var canvas, currentProgress, showing, progressTimerId = null, fadeTimerId = null, delayTimerId = null, addEvent = function(elem, type, handler) { + if (elem.addEventListener) + elem.addEventListener(type, handler, false); + else if (elem.attachEvent) + elem.attachEvent("on" + type, handler); + else + elem["on" + type] = handler; + }, options = { + autoRun: true, + barThickness: 3, + barColors: { + 0: "rgba(26, 188, 156, .9)", + ".25": "rgba(52, 152, 219, .9)", + ".50": "rgba(241, 196, 15, .9)", + ".75": "rgba(230, 126, 34, .9)", + "1.0": "rgba(211, 84, 0, .9)" + }, + shadowBlur: 10, + shadowColor: "rgba(0, 0, 0, .6)", + className: null + }, repaint = function() { + canvas.width = window2.innerWidth; + canvas.height = options.barThickness * 5; + var ctx = canvas.getContext("2d"); + ctx.shadowBlur = options.shadowBlur; + ctx.shadowColor = options.shadowColor; + var lineGradient = ctx.createLinearGradient(0, 0, canvas.width, 0); + for (var stop in options.barColors) + lineGradient.addColorStop(stop, options.barColors[stop]); + ctx.lineWidth = options.barThickness; + ctx.beginPath(); + ctx.moveTo(0, options.barThickness / 2); + ctx.lineTo( + Math.ceil(currentProgress * canvas.width), + options.barThickness / 2 + ); + ctx.strokeStyle = lineGradient; + ctx.stroke(); + }, createCanvas = function() { + canvas = document2.createElement("canvas"); + var style = canvas.style; + style.position = "fixed"; + style.top = style.left = style.right = style.margin = style.padding = 0; + style.zIndex = 100001; + style.display = "none"; + if (options.className) + canvas.classList.add(options.className); + document2.body.appendChild(canvas); + addEvent(window2, "resize", repaint); + }, topbar2 = { + config: function(opts) { + for (var key in opts) + if (options.hasOwnProperty(key)) + options[key] = opts[key]; + }, + show: function(delay) { + if (showing) + return; + if (delay) { + if (delayTimerId) + return; + delayTimerId = setTimeout(() => topbar2.show(), delay); + } else { + showing = true; + if (fadeTimerId !== null) + window2.cancelAnimationFrame(fadeTimerId); + if (!canvas) + createCanvas(); + canvas.style.opacity = 1; + canvas.style.display = "block"; + topbar2.progress(0); + if (options.autoRun) { + (function loop() { + progressTimerId = window2.requestAnimationFrame(loop); + topbar2.progress( + "+" + 0.05 * Math.pow(1 - Math.sqrt(currentProgress), 2) + ); + })(); + } + } + }, + progress: function(to) { + if (typeof to === "undefined") + return currentProgress; + if (typeof to === "string") { + to = (to.indexOf("+") >= 0 || to.indexOf("-") >= 0 ? currentProgress : 0) + parseFloat(to); + } + currentProgress = to > 1 ? 1 : to; + repaint(); + return currentProgress; + }, + hide: function() { + clearTimeout(delayTimerId); + delayTimerId = null; + if (!showing) + return; + showing = false; + if (progressTimerId != null) { + window2.cancelAnimationFrame(progressTimerId); + progressTimerId = null; + } + (function loop() { + if (topbar2.progress("+.1") >= 1) { + canvas.style.opacity -= 0.05; + if (canvas.style.opacity <= 0.05) { + canvas.style.display = "none"; + fadeTimerId = null; + return; + } + } + fadeTimerId = window2.requestAnimationFrame(loop); + })(); + } + }; + if (typeof module === "object" && typeof module.exports === "object") { + module.exports = topbar2; + } else if (typeof define === "function" && define.amd) { + define(function() { + return topbar2; + }); + } else { + this.topbar = topbar2; + } + }).call(exports, window, document); + } + }); -// For Phoenix.LiveView support, copy the following scripts -// into your javascript bundle: -// * deps/phoenix_live_view/priv/static/phoenix_live_view.js + // ../deps/phoenix_html/priv/static/phoenix_html.js + (function() { + var PolyfillEvent = eventConstructor(); + function eventConstructor() { + if (typeof window.CustomEvent === "function") + return window.CustomEvent; + function CustomEvent2(event, params) { + params = params || { bubbles: false, cancelable: false, detail: void 0 }; + var evt = document.createEvent("CustomEvent"); + evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); + return evt; + } + CustomEvent2.prototype = window.Event.prototype; + return CustomEvent2; + } + function buildHiddenInput(name, value) { + var input = document.createElement("input"); + input.type = "hidden"; + input.name = name; + input.value = value; + return input; + } + function handleClick(element, targetModifierKey) { + var to = element.getAttribute("data-to"), method = buildHiddenInput("_method", element.getAttribute("data-method")), csrf = buildHiddenInput("_csrf_token", element.getAttribute("data-csrf")), form = document.createElement("form"), submit = document.createElement("input"), target = element.getAttribute("target"); + form.method = element.getAttribute("data-method") === "get" ? "get" : "post"; + form.action = to; + form.style.display = "none"; + if (target) + form.target = target; + else if (targetModifierKey) + form.target = "_blank"; + form.appendChild(csrf); + form.appendChild(method); + document.body.appendChild(form); + submit.type = "submit"; + form.appendChild(submit); + submit.click(); + } + window.addEventListener("click", function(e) { + var element = e.target; + if (e.defaultPrevented) + return; + while (element && element.getAttribute) { + var phoenixLinkEvent = new PolyfillEvent("phoenix.link.click", { + "bubbles": true, + "cancelable": true + }); + if (!element.dispatchEvent(phoenixLinkEvent)) { + e.preventDefault(); + e.stopImmediatePropagation(); + return false; + } + if (element.getAttribute("data-method")) { + handleClick(element, e.metaKey || e.shiftKey); + e.preventDefault(); + return false; + } else { + element = element.parentNode; + } + } + }, false); + window.addEventListener("phoenix.link.click", function(e) { + var message = e.target.getAttribute("data-confirm"); + if (message && !window.confirm(message)) { + e.preventDefault(); + } + }, false); + })(); + + // ../deps/phoenix/priv/static/phoenix.mjs + var closure = (value) => { + if (typeof value === "function") { + return value; + } else { + let closure22 = function() { + return value; + }; + return closure22; + } + }; + var globalSelf = typeof self !== "undefined" ? self : null; + var phxWindow = typeof window !== "undefined" ? window : null; + var global = globalSelf || phxWindow || global; + var DEFAULT_VSN = "2.0.0"; + var SOCKET_STATES = { connecting: 0, open: 1, closing: 2, closed: 3 }; + var DEFAULT_TIMEOUT = 1e4; + var WS_CLOSE_NORMAL = 1e3; + var CHANNEL_STATES = { + closed: "closed", + errored: "errored", + joined: "joined", + joining: "joining", + leaving: "leaving" + }; + var CHANNEL_EVENTS = { + close: "phx_close", + error: "phx_error", + join: "phx_join", + reply: "phx_reply", + leave: "phx_leave" + }; + var TRANSPORTS = { + longpoll: "longpoll", + websocket: "websocket" + }; + var XHR_STATES = { + complete: 4 + }; + var Push = class { + constructor(channel, event, payload, timeout) { + this.channel = channel; + this.event = event; + this.payload = payload || function() { + return {}; + }; + this.receivedResp = null; + this.timeout = timeout; + this.timeoutTimer = null; + this.recHooks = []; + this.sent = false; + } + resend(timeout) { + this.timeout = timeout; + this.reset(); + this.send(); + } + send() { + if (this.hasReceived("timeout")) { + return; + } + this.startTimeout(); + this.sent = true; + this.channel.socket.push({ + topic: this.channel.topic, + event: this.event, + payload: this.payload(), + ref: this.ref, + join_ref: this.channel.joinRef() + }); + } + receive(status, callback) { + if (this.hasReceived(status)) { + callback(this.receivedResp.response); + } + this.recHooks.push({ status, callback }); + return this; + } + reset() { + this.cancelRefEvent(); + this.ref = null; + this.refEvent = null; + this.receivedResp = null; + this.sent = false; + } + matchReceive({ status, response, _ref }) { + this.recHooks.filter((h) => h.status === status).forEach((h) => h.callback(response)); + } + cancelRefEvent() { + if (!this.refEvent) { + return; + } + this.channel.off(this.refEvent); + } + cancelTimeout() { + clearTimeout(this.timeoutTimer); + this.timeoutTimer = null; + } + startTimeout() { + if (this.timeoutTimer) { + this.cancelTimeout(); + } + this.ref = this.channel.socket.makeRef(); + this.refEvent = this.channel.replyEventName(this.ref); + this.channel.on(this.refEvent, (payload) => { + this.cancelRefEvent(); + this.cancelTimeout(); + this.receivedResp = payload; + this.matchReceive(payload); + }); + this.timeoutTimer = setTimeout(() => { + this.trigger("timeout", {}); + }, this.timeout); + } + hasReceived(status) { + return this.receivedResp && this.receivedResp.status === status; + } + trigger(status, response) { + this.channel.trigger(this.refEvent, { status, response }); + } + }; + var Timer = class { + constructor(callback, timerCalc) { + this.callback = callback; + this.timerCalc = timerCalc; + this.timer = null; + this.tries = 0; + } + reset() { + this.tries = 0; + clearTimeout(this.timer); + } + scheduleTimeout() { + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.tries = this.tries + 1; + this.callback(); + }, this.timerCalc(this.tries + 1)); + } + }; + var Channel = class { + constructor(topic, params, socket) { + this.state = CHANNEL_STATES.closed; + this.topic = topic; + this.params = closure(params || {}); + this.socket = socket; + this.bindings = []; + this.bindingRef = 0; + this.timeout = this.socket.timeout; + this.joinedOnce = false; + this.joinPush = new Push(this, CHANNEL_EVENTS.join, this.params, this.timeout); + this.pushBuffer = []; + this.stateChangeRefs = []; + this.rejoinTimer = new Timer(() => { + if (this.socket.isConnected()) { + this.rejoin(); + } + }, this.socket.rejoinAfterMs); + this.stateChangeRefs.push(this.socket.onError(() => this.rejoinTimer.reset())); + this.stateChangeRefs.push(this.socket.onOpen(() => { + this.rejoinTimer.reset(); + if (this.isErrored()) { + this.rejoin(); + } + })); + this.joinPush.receive("ok", () => { + this.state = CHANNEL_STATES.joined; + this.rejoinTimer.reset(); + this.pushBuffer.forEach((pushEvent) => pushEvent.send()); + this.pushBuffer = []; + }); + this.joinPush.receive("error", () => { + this.state = CHANNEL_STATES.errored; + if (this.socket.isConnected()) { + this.rejoinTimer.scheduleTimeout(); + } + }); + this.onClose(() => { + this.rejoinTimer.reset(); + if (this.socket.hasLogger()) + this.socket.log("channel", `close ${this.topic} ${this.joinRef()}`); + this.state = CHANNEL_STATES.closed; + this.socket.remove(this); + }); + this.onError((reason) => { + if (this.socket.hasLogger()) + this.socket.log("channel", `error ${this.topic}`, reason); + if (this.isJoining()) { + this.joinPush.reset(); + } + this.state = CHANNEL_STATES.errored; + if (this.socket.isConnected()) { + this.rejoinTimer.scheduleTimeout(); + } + }); + this.joinPush.receive("timeout", () => { + if (this.socket.hasLogger()) + this.socket.log("channel", `timeout ${this.topic} (${this.joinRef()})`, this.joinPush.timeout); + let leavePush = new Push(this, CHANNEL_EVENTS.leave, closure({}), this.timeout); + leavePush.send(); + this.state = CHANNEL_STATES.errored; + this.joinPush.reset(); + if (this.socket.isConnected()) { + this.rejoinTimer.scheduleTimeout(); + } + }); + this.on(CHANNEL_EVENTS.reply, (payload, ref) => { + this.trigger(this.replyEventName(ref), payload); + }); + } + join(timeout = this.timeout) { + if (this.joinedOnce) { + throw new Error("tried to join multiple times. 'join' can only be called a single time per channel instance"); + } else { + this.timeout = timeout; + this.joinedOnce = true; + this.rejoin(); + return this.joinPush; + } + } + onClose(callback) { + this.on(CHANNEL_EVENTS.close, callback); + } + onError(callback) { + return this.on(CHANNEL_EVENTS.error, (reason) => callback(reason)); + } + on(event, callback) { + let ref = this.bindingRef++; + this.bindings.push({ event, ref, callback }); + return ref; + } + off(event, ref) { + this.bindings = this.bindings.filter((bind) => { + return !(bind.event === event && (typeof ref === "undefined" || ref === bind.ref)); + }); + } + canPush() { + return this.socket.isConnected() && this.isJoined(); + } + push(event, payload, timeout = this.timeout) { + payload = payload || {}; + if (!this.joinedOnce) { + throw new Error(`tried to push '${event}' to '${this.topic}' before joining. Use channel.join() before pushing events`); + } + let pushEvent = new Push(this, event, function() { + return payload; + }, timeout); + if (this.canPush()) { + pushEvent.send(); + } else { + pushEvent.startTimeout(); + this.pushBuffer.push(pushEvent); + } + return pushEvent; + } + leave(timeout = this.timeout) { + this.rejoinTimer.reset(); + this.joinPush.cancelTimeout(); + this.state = CHANNEL_STATES.leaving; + let onClose = () => { + if (this.socket.hasLogger()) + this.socket.log("channel", `leave ${this.topic}`); + this.trigger(CHANNEL_EVENTS.close, "leave"); + }; + let leavePush = new Push(this, CHANNEL_EVENTS.leave, closure({}), timeout); + leavePush.receive("ok", () => onClose()).receive("timeout", () => onClose()); + leavePush.send(); + if (!this.canPush()) { + leavePush.trigger("ok", {}); + } + return leavePush; + } + onMessage(_event, payload, _ref) { + return payload; + } + isMember(topic, event, payload, joinRef) { + if (this.topic !== topic) { + return false; + } + if (joinRef && joinRef !== this.joinRef()) { + if (this.socket.hasLogger()) + this.socket.log("channel", "dropping outdated message", { topic, event, payload, joinRef }); + return false; + } else { + return true; + } + } + joinRef() { + return this.joinPush.ref; + } + rejoin(timeout = this.timeout) { + if (this.isLeaving()) { + return; + } + this.socket.leaveOpenTopic(this.topic); + this.state = CHANNEL_STATES.joining; + this.joinPush.resend(timeout); + } + trigger(event, payload, ref, joinRef) { + let handledPayload = this.onMessage(event, payload, ref, joinRef); + if (payload && !handledPayload) { + throw new Error("channel onMessage callbacks must return the payload, modified or unmodified"); + } + let eventBindings = this.bindings.filter((bind) => bind.event === event); + for (let i = 0; i < eventBindings.length; i++) { + let bind = eventBindings[i]; + bind.callback(handledPayload, ref, joinRef || this.joinRef()); + } + } + replyEventName(ref) { + return `chan_reply_${ref}`; + } + isClosed() { + return this.state === CHANNEL_STATES.closed; + } + isErrored() { + return this.state === CHANNEL_STATES.errored; + } + isJoined() { + return this.state === CHANNEL_STATES.joined; + } + isJoining() { + return this.state === CHANNEL_STATES.joining; + } + isLeaving() { + return this.state === CHANNEL_STATES.leaving; + } + }; + var Ajax = class { + static request(method, endPoint, accept, body, timeout, ontimeout, callback) { + if (global.XDomainRequest) { + let req = new global.XDomainRequest(); + return this.xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback); + } else { + let req = new global.XMLHttpRequest(); + return this.xhrRequest(req, method, endPoint, accept, body, timeout, ontimeout, callback); + } + } + static xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback) { + req.timeout = timeout; + req.open(method, endPoint); + req.onload = () => { + let response = this.parseJSON(req.responseText); + callback && callback(response); + }; + if (ontimeout) { + req.ontimeout = ontimeout; + } + req.onprogress = () => { + }; + req.send(body); + return req; + } + static xhrRequest(req, method, endPoint, accept, body, timeout, ontimeout, callback) { + req.open(method, endPoint, true); + req.timeout = timeout; + req.setRequestHeader("Content-Type", accept); + req.onerror = () => callback && callback(null); + req.onreadystatechange = () => { + if (req.readyState === XHR_STATES.complete && callback) { + let response = this.parseJSON(req.responseText); + callback(response); + } + }; + if (ontimeout) { + req.ontimeout = ontimeout; + } + req.send(body); + return req; + } + static parseJSON(resp) { + if (!resp || resp === "") { + return null; + } + try { + return JSON.parse(resp); + } catch (e) { + console && console.log("failed to parse JSON response", resp); + return null; + } + } + static serialize(obj, parentKey) { + let queryStr = []; + for (var key in obj) { + if (!Object.prototype.hasOwnProperty.call(obj, key)) { + continue; + } + let paramKey = parentKey ? `${parentKey}[${key}]` : key; + let paramVal = obj[key]; + if (typeof paramVal === "object") { + queryStr.push(this.serialize(paramVal, paramKey)); + } else { + queryStr.push(encodeURIComponent(paramKey) + "=" + encodeURIComponent(paramVal)); + } + } + return queryStr.join("&"); + } + static appendParams(url, params) { + if (Object.keys(params).length === 0) { + return url; + } + let prefix = url.match(/\?/) ? "&" : "?"; + return `${url}${prefix}${this.serialize(params)}`; + } + }; + var arrayBufferToBase64 = (buffer) => { + let binary = ""; + let bytes = new Uint8Array(buffer); + let len = bytes.byteLength; + for (let i = 0; i < len; i++) { + binary += String.fromCharCode(bytes[i]); + } + return btoa(binary); + }; + var LongPoll = class { + constructor(endPoint) { + this.endPoint = null; + this.token = null; + this.skipHeartbeat = true; + this.reqs = /* @__PURE__ */ new Set(); + this.awaitingBatchAck = false; + this.currentBatch = null; + this.currentBatchTimer = null; + this.batchBuffer = []; + this.onopen = function() { + }; + this.onerror = function() { + }; + this.onmessage = function() { + }; + this.onclose = function() { + }; + this.pollEndpoint = this.normalizeEndpoint(endPoint); + this.readyState = SOCKET_STATES.connecting; + this.poll(); + } + normalizeEndpoint(endPoint) { + return endPoint.replace("ws://", "http://").replace("wss://", "https://").replace(new RegExp("(.*)/" + TRANSPORTS.websocket), "$1/" + TRANSPORTS.longpoll); + } + endpointURL() { + return Ajax.appendParams(this.pollEndpoint, { token: this.token }); + } + closeAndRetry(code, reason, wasClean) { + this.close(code, reason, wasClean); + this.readyState = SOCKET_STATES.connecting; + } + ontimeout() { + this.onerror("timeout"); + this.closeAndRetry(1005, "timeout", false); + } + isActive() { + return this.readyState === SOCKET_STATES.open || this.readyState === SOCKET_STATES.connecting; + } + poll() { + this.ajax("GET", "application/json", null, () => this.ontimeout(), (resp) => { + if (resp) { + var { status, token, messages } = resp; + this.token = token; + } else { + status = 0; + } + switch (status) { + case 200: + messages.forEach((msg) => { + setTimeout(() => this.onmessage({ data: msg }), 0); + }); + this.poll(); + break; + case 204: + this.poll(); + break; + case 410: + this.readyState = SOCKET_STATES.open; + this.onopen({}); + this.poll(); + break; + case 403: + this.onerror(403); + this.close(1008, "forbidden", false); + break; + case 0: + case 500: + this.onerror(500); + this.closeAndRetry(1011, "internal server error", 500); + break; + default: + throw new Error(`unhandled poll status ${status}`); + } + }); + } + send(body) { + if (typeof body !== "string") { + body = arrayBufferToBase64(body); + } + if (this.currentBatch) { + this.currentBatch.push(body); + } else if (this.awaitingBatchAck) { + this.batchBuffer.push(body); + } else { + this.currentBatch = [body]; + this.currentBatchTimer = setTimeout(() => { + this.batchSend(this.currentBatch); + this.currentBatch = null; + }, 0); + } + } + batchSend(messages) { + this.awaitingBatchAck = true; + this.ajax("POST", "application/x-ndjson", messages.join("\n"), () => this.onerror("timeout"), (resp) => { + this.awaitingBatchAck = false; + if (!resp || resp.status !== 200) { + this.onerror(resp && resp.status); + this.closeAndRetry(1011, "internal server error", false); + } else if (this.batchBuffer.length > 0) { + this.batchSend(this.batchBuffer); + this.batchBuffer = []; + } + }); + } + close(code, reason, wasClean) { + for (let req of this.reqs) { + req.abort(); + } + this.readyState = SOCKET_STATES.closed; + let opts = Object.assign({ code: 1e3, reason: void 0, wasClean: true }, { code, reason, wasClean }); + this.batchBuffer = []; + clearTimeout(this.currentBatchTimer); + this.currentBatchTimer = null; + if (typeof CloseEvent !== "undefined") { + this.onclose(new CloseEvent("close", opts)); + } else { + this.onclose(opts); + } + } + ajax(method, contentType, body, onCallerTimeout, callback) { + let req; + let ontimeout = () => { + this.reqs.delete(req); + onCallerTimeout(); + }; + req = Ajax.request(method, this.endpointURL(), contentType, body, this.timeout, ontimeout, (resp) => { + this.reqs.delete(req); + if (this.isActive()) { + callback(resp); + } + }); + this.reqs.add(req); + } + }; + var serializer_default = { + HEADER_LENGTH: 1, + META_LENGTH: 4, + KINDS: { push: 0, reply: 1, broadcast: 2 }, + encode(msg, callback) { + if (msg.payload.constructor === ArrayBuffer) { + return callback(this.binaryEncode(msg)); + } else { + let payload = [msg.join_ref, msg.ref, msg.topic, msg.event, msg.payload]; + return callback(JSON.stringify(payload)); + } + }, + decode(rawPayload, callback) { + if (rawPayload.constructor === ArrayBuffer) { + return callback(this.binaryDecode(rawPayload)); + } else { + let [join_ref, ref, topic, event, payload] = JSON.parse(rawPayload); + return callback({ join_ref, ref, topic, event, payload }); + } + }, + binaryEncode(message) { + let { join_ref, ref, event, topic, payload } = message; + let metaLength = this.META_LENGTH + join_ref.length + ref.length + topic.length + event.length; + let header = new ArrayBuffer(this.HEADER_LENGTH + metaLength); + let view = new DataView(header); + let offset = 0; + view.setUint8(offset++, this.KINDS.push); + view.setUint8(offset++, join_ref.length); + view.setUint8(offset++, ref.length); + view.setUint8(offset++, topic.length); + view.setUint8(offset++, event.length); + Array.from(join_ref, (char) => view.setUint8(offset++, char.charCodeAt(0))); + Array.from(ref, (char) => view.setUint8(offset++, char.charCodeAt(0))); + Array.from(topic, (char) => view.setUint8(offset++, char.charCodeAt(0))); + Array.from(event, (char) => view.setUint8(offset++, char.charCodeAt(0))); + var combined = new Uint8Array(header.byteLength + payload.byteLength); + combined.set(new Uint8Array(header), 0); + combined.set(new Uint8Array(payload), header.byteLength); + return combined.buffer; + }, + binaryDecode(buffer) { + let view = new DataView(buffer); + let kind = view.getUint8(0); + let decoder = new TextDecoder(); + switch (kind) { + case this.KINDS.push: + return this.decodePush(buffer, view, decoder); + case this.KINDS.reply: + return this.decodeReply(buffer, view, decoder); + case this.KINDS.broadcast: + return this.decodeBroadcast(buffer, view, decoder); + } + }, + decodePush(buffer, view, decoder) { + let joinRefSize = view.getUint8(1); + let topicSize = view.getUint8(2); + let eventSize = view.getUint8(3); + let offset = this.HEADER_LENGTH + this.META_LENGTH - 1; + let joinRef = decoder.decode(buffer.slice(offset, offset + joinRefSize)); + offset = offset + joinRefSize; + let topic = decoder.decode(buffer.slice(offset, offset + topicSize)); + offset = offset + topicSize; + let event = decoder.decode(buffer.slice(offset, offset + eventSize)); + offset = offset + eventSize; + let data = buffer.slice(offset, buffer.byteLength); + return { join_ref: joinRef, ref: null, topic, event, payload: data }; + }, + decodeReply(buffer, view, decoder) { + let joinRefSize = view.getUint8(1); + let refSize = view.getUint8(2); + let topicSize = view.getUint8(3); + let eventSize = view.getUint8(4); + let offset = this.HEADER_LENGTH + this.META_LENGTH; + let joinRef = decoder.decode(buffer.slice(offset, offset + joinRefSize)); + offset = offset + joinRefSize; + let ref = decoder.decode(buffer.slice(offset, offset + refSize)); + offset = offset + refSize; + let topic = decoder.decode(buffer.slice(offset, offset + topicSize)); + offset = offset + topicSize; + let event = decoder.decode(buffer.slice(offset, offset + eventSize)); + offset = offset + eventSize; + let data = buffer.slice(offset, buffer.byteLength); + let payload = { status: event, response: data }; + return { join_ref: joinRef, ref, topic, event: CHANNEL_EVENTS.reply, payload }; + }, + decodeBroadcast(buffer, view, decoder) { + let topicSize = view.getUint8(1); + let eventSize = view.getUint8(2); + let offset = this.HEADER_LENGTH + 2; + let topic = decoder.decode(buffer.slice(offset, offset + topicSize)); + offset = offset + topicSize; + let event = decoder.decode(buffer.slice(offset, offset + eventSize)); + offset = offset + eventSize; + let data = buffer.slice(offset, buffer.byteLength); + return { join_ref: null, ref: null, topic, event, payload: data }; + } + }; + var Socket = class { + constructor(endPoint, opts = {}) { + this.stateChangeCallbacks = { open: [], close: [], error: [], message: [] }; + this.channels = []; + this.sendBuffer = []; + this.ref = 0; + this.timeout = opts.timeout || DEFAULT_TIMEOUT; + this.transport = opts.transport || global.WebSocket || LongPoll; + this.establishedConnections = 0; + this.defaultEncoder = serializer_default.encode.bind(serializer_default); + this.defaultDecoder = serializer_default.decode.bind(serializer_default); + this.closeWasClean = false; + this.binaryType = opts.binaryType || "arraybuffer"; + this.connectClock = 1; + if (this.transport !== LongPoll) { + this.encode = opts.encode || this.defaultEncoder; + this.decode = opts.decode || this.defaultDecoder; + } else { + this.encode = this.defaultEncoder; + this.decode = this.defaultDecoder; + } + let awaitingConnectionOnPageShow = null; + if (phxWindow && phxWindow.addEventListener) { + phxWindow.addEventListener("pagehide", (_e) => { + if (this.conn) { + this.disconnect(); + awaitingConnectionOnPageShow = this.connectClock; + } + }); + phxWindow.addEventListener("pageshow", (_e) => { + if (awaitingConnectionOnPageShow === this.connectClock) { + awaitingConnectionOnPageShow = null; + this.connect(); + } + }); + } + this.heartbeatIntervalMs = opts.heartbeatIntervalMs || 3e4; + this.rejoinAfterMs = (tries) => { + if (opts.rejoinAfterMs) { + return opts.rejoinAfterMs(tries); + } else { + return [1e3, 2e3, 5e3][tries - 1] || 1e4; + } + }; + this.reconnectAfterMs = (tries) => { + if (opts.reconnectAfterMs) { + return opts.reconnectAfterMs(tries); + } else { + return [10, 50, 100, 150, 200, 250, 500, 1e3, 2e3][tries - 1] || 5e3; + } + }; + this.logger = opts.logger || null; + this.longpollerTimeout = opts.longpollerTimeout || 2e4; + this.params = closure(opts.params || {}); + this.endPoint = `${endPoint}/${TRANSPORTS.websocket}`; + this.vsn = opts.vsn || DEFAULT_VSN; + this.heartbeatTimeoutTimer = null; + this.heartbeatTimer = null; + this.pendingHeartbeatRef = null; + this.reconnectTimer = new Timer(() => { + this.teardown(() => this.connect()); + }, this.reconnectAfterMs); + } + getLongPollTransport() { + return LongPoll; + } + replaceTransport(newTransport) { + this.connectClock++; + this.closeWasClean = true; + this.reconnectTimer.reset(); + this.sendBuffer = []; + if (this.conn) { + this.conn.close(); + this.conn = null; + } + this.transport = newTransport; + } + protocol() { + return location.protocol.match(/^https/) ? "wss" : "ws"; + } + endPointURL() { + let uri = Ajax.appendParams(Ajax.appendParams(this.endPoint, this.params()), { vsn: this.vsn }); + if (uri.charAt(0) !== "/") { + return uri; + } + if (uri.charAt(1) === "/") { + return `${this.protocol()}:${uri}`; + } + return `${this.protocol()}://${location.host}${uri}`; + } + disconnect(callback, code, reason) { + this.connectClock++; + this.closeWasClean = true; + this.reconnectTimer.reset(); + this.teardown(callback, code, reason); + } + connect(params) { + if (params) { + console && console.log("passing params to connect is deprecated. Instead pass :params to the Socket constructor"); + this.params = closure(params); + } + if (this.conn) { + return; + } + this.connectClock++; + this.closeWasClean = false; + this.conn = new this.transport(this.endPointURL()); + this.conn.binaryType = this.binaryType; + this.conn.timeout = this.longpollerTimeout; + this.conn.onopen = () => this.onConnOpen(); + this.conn.onerror = (error) => this.onConnError(error); + this.conn.onmessage = (event) => this.onConnMessage(event); + this.conn.onclose = (event) => this.onConnClose(event); + } + log(kind, msg, data) { + this.logger(kind, msg, data); + } + hasLogger() { + return this.logger !== null; + } + onOpen(callback) { + let ref = this.makeRef(); + this.stateChangeCallbacks.open.push([ref, callback]); + return ref; + } + onClose(callback) { + let ref = this.makeRef(); + this.stateChangeCallbacks.close.push([ref, callback]); + return ref; + } + onError(callback) { + let ref = this.makeRef(); + this.stateChangeCallbacks.error.push([ref, callback]); + return ref; + } + onMessage(callback) { + let ref = this.makeRef(); + this.stateChangeCallbacks.message.push([ref, callback]); + return ref; + } + ping(callback) { + if (!this.isConnected()) { + return false; + } + let ref = this.makeRef(); + let startTime = Date.now(); + this.push({ topic: "phoenix", event: "heartbeat", payload: {}, ref }); + let onMsgRef = this.onMessage((msg) => { + if (msg.ref === ref) { + this.off([onMsgRef]); + callback(Date.now() - startTime); + } + }); + return true; + } + clearHeartbeats() { + clearTimeout(this.heartbeatTimer); + clearTimeout(this.heartbeatTimeoutTimer); + } + onConnOpen() { + if (this.hasLogger()) + this.log("transport", `connected to ${this.endPointURL()}`); + this.closeWasClean = false; + this.establishedConnections++; + this.flushSendBuffer(); + this.reconnectTimer.reset(); + this.resetHeartbeat(); + this.stateChangeCallbacks.open.forEach(([, callback]) => callback()); + } + heartbeatTimeout() { + if (this.pendingHeartbeatRef) { + this.pendingHeartbeatRef = null; + if (this.hasLogger()) { + this.log("transport", "heartbeat timeout. Attempting to re-establish connection"); + } + this.triggerChanError(); + this.closeWasClean = false; + this.teardown(() => this.reconnectTimer.scheduleTimeout(), WS_CLOSE_NORMAL, "heartbeat timeout"); + } + } + resetHeartbeat() { + if (this.conn && this.conn.skipHeartbeat) { + return; + } + this.pendingHeartbeatRef = null; + this.clearHeartbeats(); + this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs); + } + teardown(callback, code, reason) { + if (!this.conn) { + return callback && callback(); + } + this.waitForBufferDone(() => { + if (this.conn) { + if (code) { + this.conn.close(code, reason || ""); + } else { + this.conn.close(); + } + } + this.waitForSocketClosed(() => { + if (this.conn) { + this.conn.onopen = function() { + }; + this.conn.onerror = function() { + }; + this.conn.onmessage = function() { + }; + this.conn.onclose = function() { + }; + this.conn = null; + } + callback && callback(); + }); + }); + } + waitForBufferDone(callback, tries = 1) { + if (tries === 5 || !this.conn || !this.conn.bufferedAmount) { + callback(); + return; + } + setTimeout(() => { + this.waitForBufferDone(callback, tries + 1); + }, 150 * tries); + } + waitForSocketClosed(callback, tries = 1) { + if (tries === 5 || !this.conn || this.conn.readyState === SOCKET_STATES.closed) { + callback(); + return; + } + setTimeout(() => { + this.waitForSocketClosed(callback, tries + 1); + }, 150 * tries); + } + onConnClose(event) { + let closeCode = event && event.code; + if (this.hasLogger()) + this.log("transport", "close", event); + this.triggerChanError(); + this.clearHeartbeats(); + if (!this.closeWasClean && closeCode !== 1e3) { + this.reconnectTimer.scheduleTimeout(); + } + this.stateChangeCallbacks.close.forEach(([, callback]) => callback(event)); + } + onConnError(error) { + if (this.hasLogger()) + this.log("transport", error); + let transportBefore = this.transport; + let establishedBefore = this.establishedConnections; + this.stateChangeCallbacks.error.forEach(([, callback]) => { + callback(error, transportBefore, establishedBefore); + }); + if (transportBefore === this.transport || establishedBefore > 0) { + this.triggerChanError(); + } + } + triggerChanError() { + this.channels.forEach((channel) => { + if (!(channel.isErrored() || channel.isLeaving() || channel.isClosed())) { + channel.trigger(CHANNEL_EVENTS.error); + } + }); + } + connectionState() { + switch (this.conn && this.conn.readyState) { + case SOCKET_STATES.connecting: + return "connecting"; + case SOCKET_STATES.open: + return "open"; + case SOCKET_STATES.closing: + return "closing"; + default: + return "closed"; + } + } + isConnected() { + return this.connectionState() === "open"; + } + remove(channel) { + this.off(channel.stateChangeRefs); + this.channels = this.channels.filter((c) => c.joinRef() !== channel.joinRef()); + } + off(refs) { + for (let key in this.stateChangeCallbacks) { + this.stateChangeCallbacks[key] = this.stateChangeCallbacks[key].filter(([ref]) => { + return refs.indexOf(ref) === -1; + }); + } + } + channel(topic, chanParams = {}) { + let chan = new Channel(topic, chanParams, this); + this.channels.push(chan); + return chan; + } + push(data) { + if (this.hasLogger()) { + let { topic, event, payload, ref, join_ref } = data; + this.log("push", `${topic} ${event} (${join_ref}, ${ref})`, payload); + } + if (this.isConnected()) { + this.encode(data, (result) => this.conn.send(result)); + } else { + this.sendBuffer.push(() => this.encode(data, (result) => this.conn.send(result))); + } + } + makeRef() { + let newRef = this.ref + 1; + if (newRef === this.ref) { + this.ref = 0; + } else { + this.ref = newRef; + } + return this.ref.toString(); + } + sendHeartbeat() { + if (this.pendingHeartbeatRef && !this.isConnected()) { + return; + } + this.pendingHeartbeatRef = this.makeRef(); + this.push({ topic: "phoenix", event: "heartbeat", payload: {}, ref: this.pendingHeartbeatRef }); + this.heartbeatTimeoutTimer = setTimeout(() => this.heartbeatTimeout(), this.heartbeatIntervalMs); + } + flushSendBuffer() { + if (this.isConnected() && this.sendBuffer.length > 0) { + this.sendBuffer.forEach((callback) => callback()); + this.sendBuffer = []; + } + } + onConnMessage(rawMessage) { + this.decode(rawMessage.data, (msg) => { + let { topic, event, payload, ref, join_ref } = msg; + if (ref && ref === this.pendingHeartbeatRef) { + this.clearHeartbeats(); + this.pendingHeartbeatRef = null; + this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs); + } + if (this.hasLogger()) + this.log("receive", `${payload.status || ""} ${topic} ${event} ${ref && "(" + ref + ")" || ""}`, payload); + for (let i = 0; i < this.channels.length; i++) { + const channel = this.channels[i]; + if (!channel.isMember(topic, event, payload, join_ref)) { + continue; + } + channel.trigger(event, payload, ref, join_ref); + } + for (let i = 0; i < this.stateChangeCallbacks.message.length; i++) { + let [, callback] = this.stateChangeCallbacks.message[i]; + callback(msg); + } + }); + } + leaveOpenTopic(topic) { + let dupChannel = this.channels.find((c) => c.topic === topic && (c.isJoined() || c.isJoining())); + if (dupChannel) { + if (this.hasLogger()) + this.log("transport", `leaving duplicate topic "${topic}"`); + dupChannel.leave(); + } + } + }; + + // ../deps/phoenix_live_view/priv/static/phoenix_live_view.esm.js + var CONSECUTIVE_RELOADS = "consecutive-reloads"; + var MAX_RELOADS = 10; + var RELOAD_JITTER_MIN = 5e3; + var RELOAD_JITTER_MAX = 1e4; + var FAILSAFE_JITTER = 3e4; + var PHX_EVENT_CLASSES = [ + "phx-click-loading", + "phx-change-loading", + "phx-submit-loading", + "phx-keydown-loading", + "phx-keyup-loading", + "phx-blur-loading", + "phx-focus-loading" + ]; + var PHX_COMPONENT = "data-phx-component"; + var PHX_LIVE_LINK = "data-phx-link"; + var PHX_TRACK_STATIC = "track-static"; + var PHX_LINK_STATE = "data-phx-link-state"; + var PHX_REF = "data-phx-ref"; + var PHX_REF_SRC = "data-phx-ref-src"; + var PHX_TRACK_UPLOADS = "track-uploads"; + var PHX_UPLOAD_REF = "data-phx-upload-ref"; + var PHX_PREFLIGHTED_REFS = "data-phx-preflighted-refs"; + var PHX_DONE_REFS = "data-phx-done-refs"; + var PHX_DROP_TARGET = "drop-target"; + var PHX_ACTIVE_ENTRY_REFS = "data-phx-active-refs"; + var PHX_LIVE_FILE_UPDATED = "phx:live-file:updated"; + var PHX_SKIP = "data-phx-skip"; + var PHX_PRUNE = "data-phx-prune"; + var PHX_PAGE_LOADING = "page-loading"; + var PHX_CONNECTED_CLASS = "phx-connected"; + var PHX_LOADING_CLASS = "phx-loading"; + var PHX_NO_FEEDBACK_CLASS = "phx-no-feedback"; + var PHX_ERROR_CLASS = "phx-error"; + var PHX_CLIENT_ERROR_CLASS = "phx-client-error"; + var PHX_SERVER_ERROR_CLASS = "phx-server-error"; + var PHX_PARENT_ID = "data-phx-parent-id"; + var PHX_MAIN = "data-phx-main"; + var PHX_ROOT_ID = "data-phx-root-id"; + var PHX_VIEWPORT_TOP = "viewport-top"; + var PHX_VIEWPORT_BOTTOM = "viewport-bottom"; + var PHX_TRIGGER_ACTION = "trigger-action"; + var PHX_FEEDBACK_FOR = "feedback-for"; + var PHX_HAS_FOCUSED = "phx-has-focused"; + var FOCUSABLE_INPUTS = ["text", "textarea", "number", "email", "password", "search", "tel", "url", "date", "time", "datetime-local", "color", "range"]; + var CHECKABLE_INPUTS = ["checkbox", "radio"]; + var PHX_HAS_SUBMITTED = "phx-has-submitted"; + var PHX_SESSION = "data-phx-session"; + var PHX_VIEW_SELECTOR = `[${PHX_SESSION}]`; + var PHX_STICKY = "data-phx-sticky"; + var PHX_STATIC = "data-phx-static"; + var PHX_READONLY = "data-phx-readonly"; + var PHX_DISABLED = "data-phx-disabled"; + var PHX_DISABLE_WITH = "disable-with"; + var PHX_DISABLE_WITH_RESTORE = "data-phx-disable-with-restore"; + var PHX_HOOK = "hook"; + var PHX_DEBOUNCE = "debounce"; + var PHX_THROTTLE = "throttle"; + var PHX_UPDATE = "update"; + var PHX_STREAM = "stream"; + var PHX_STREAM_REF = "data-phx-stream"; + var PHX_KEY = "key"; + var PHX_PRIVATE = "phxPrivate"; + var PHX_AUTO_RECOVER = "auto-recover"; + var PHX_LV_DEBUG = "phx:live-socket:debug"; + var PHX_LV_PROFILE = "phx:live-socket:profiling"; + var PHX_LV_LATENCY_SIM = "phx:live-socket:latency-sim"; + var PHX_PROGRESS = "progress"; + var PHX_MOUNTED = "mounted"; + var LOADER_TIMEOUT = 1; + var BEFORE_UNLOAD_LOADER_TIMEOUT = 200; + var BINDING_PREFIX = "phx-"; + var PUSH_TIMEOUT = 3e4; + var DEBOUNCE_TRIGGER = "debounce-trigger"; + var THROTTLED = "throttled"; + var DEBOUNCE_PREV_KEY = "debounce-prev-key"; + var DEFAULTS = { + debounce: 300, + throttle: 300 + }; + var DYNAMICS = "d"; + var STATIC = "s"; + var COMPONENTS = "c"; + var EVENTS = "e"; + var REPLY = "r"; + var TITLE = "t"; + var TEMPLATES = "p"; + var STREAM = "stream"; + var EntryUploader = class { + constructor(entry, chunkSize, liveSocket2) { + this.liveSocket = liveSocket2; + this.entry = entry; + this.offset = 0; + this.chunkSize = chunkSize; + this.chunkTimer = null; + this.errored = false; + this.uploadChannel = liveSocket2.channel(`lvu:${entry.ref}`, { token: entry.metadata() }); + } + error(reason) { + if (this.errored) { + return; + } + this.errored = true; + clearTimeout(this.chunkTimer); + this.entry.error(reason); + } + upload() { + this.uploadChannel.onError((reason) => this.error(reason)); + this.uploadChannel.join().receive("ok", (_data) => this.readNextChunk()).receive("error", (reason) => this.error(reason)); + } + isDone() { + return this.offset >= this.entry.file.size; + } + readNextChunk() { + let reader = new window.FileReader(); + let blob = this.entry.file.slice(this.offset, this.chunkSize + this.offset); + reader.onload = (e) => { + if (e.target.error === null) { + this.offset += e.target.result.byteLength; + this.pushChunk(e.target.result); + } else { + return logError("Read error: " + e.target.error); + } + }; + reader.readAsArrayBuffer(blob); + } + pushChunk(chunk) { + if (!this.uploadChannel.isJoined()) { + return; + } + this.uploadChannel.push("chunk", chunk).receive("ok", () => { + this.entry.progress(this.offset / this.entry.file.size * 100); + if (!this.isDone()) { + this.chunkTimer = setTimeout(() => this.readNextChunk(), this.liveSocket.getLatencySim() || 0); + } + }).receive("error", ({ reason }) => this.error(reason)); + } + }; + var logError = (msg, obj) => console.error && console.error(msg, obj); + var isCid = (cid) => { + let type = typeof cid; + return type === "number" || type === "string" && /^(0|[1-9]\d*)$/.test(cid); + }; + function detectDuplicateIds() { + let ids = /* @__PURE__ */ new Set(); + let elems = document.querySelectorAll("*[id]"); + for (let i = 0, len = elems.length; i < len; i++) { + if (ids.has(elems[i].id)) { + console.error(`Multiple IDs detected: ${elems[i].id}. Ensure unique element ids.`); + } else { + ids.add(elems[i].id); + } + } + } + var debug = (view, kind, msg, obj) => { + if (view.liveSocket.isDebugEnabled()) { + console.log(`${view.id} ${kind}: ${msg} - `, obj); + } + }; + var closure2 = (val) => typeof val === "function" ? val : function() { + return val; + }; + var clone = (obj) => { + return JSON.parse(JSON.stringify(obj)); + }; + var closestPhxBinding = (el, binding, borderEl) => { + do { + if (el.matches(`[${binding}]`) && !el.disabled) { + return el; + } + el = el.parentElement || el.parentNode; + } while (el !== null && el.nodeType === 1 && !(borderEl && borderEl.isSameNode(el) || el.matches(PHX_VIEW_SELECTOR))); + return null; + }; + var isObject = (obj) => { + return obj !== null && typeof obj === "object" && !(obj instanceof Array); + }; + var isEqualObj = (obj1, obj2) => JSON.stringify(obj1) === JSON.stringify(obj2); + var isEmpty = (obj) => { + for (let x in obj) { + return false; + } + return true; + }; + var maybe = (el, callback) => el && callback(el); + var channelUploader = function(entries, onError, resp, liveSocket2) { + entries.forEach((entry) => { + let entryUploader = new EntryUploader(entry, resp.config.chunk_size, liveSocket2); + entryUploader.upload(); + }); + }; + var Browser = { + canPushState() { + return typeof history.pushState !== "undefined"; + }, + dropLocal(localStorage, namespace, subkey) { + return localStorage.removeItem(this.localKey(namespace, subkey)); + }, + updateLocal(localStorage, namespace, subkey, initial, func) { + let current = this.getLocal(localStorage, namespace, subkey); + let key = this.localKey(namespace, subkey); + let newVal = current === null ? initial : func(current); + localStorage.setItem(key, JSON.stringify(newVal)); + return newVal; + }, + getLocal(localStorage, namespace, subkey) { + return JSON.parse(localStorage.getItem(this.localKey(namespace, subkey))); + }, + updateCurrentState(callback) { + if (!this.canPushState()) { + return; + } + history.replaceState(callback(history.state || {}), "", window.location.href); + }, + pushState(kind, meta, to) { + if (this.canPushState()) { + if (to !== window.location.href) { + if (meta.type == "redirect" && meta.scroll) { + let currentState = history.state || {}; + currentState.scroll = meta.scroll; + history.replaceState(currentState, "", window.location.href); + } + delete meta.scroll; + history[kind + "State"](meta, "", to || null); + let hashEl = this.getHashTargetEl(window.location.hash); + if (hashEl) { + hashEl.scrollIntoView(); + } else if (meta.type === "redirect") { + window.scroll(0, 0); + } + } + } else { + this.redirect(to); + } + }, + setCookie(name, value) { + document.cookie = `${name}=${value}`; + }, + getCookie(name) { + return document.cookie.replace(new RegExp(`(?:(?:^|.*;s*)${name}s*=s*([^;]*).*$)|^.*$`), "$1"); + }, + redirect(toURL, flash) { + if (flash) { + Browser.setCookie("__phoenix_flash__", flash + "; max-age=60000; path=/"); + } + window.location = toURL; + }, + localKey(namespace, subkey) { + return `${namespace}-${subkey}`; + }, + getHashTargetEl(maybeHash) { + let hash = maybeHash.toString().substring(1); + if (hash === "") { + return; + } + return document.getElementById(hash) || document.querySelector(`a[name="${hash}"]`); + } + }; + var browser_default = Browser; + var DOM = { + byId(id) { + return document.getElementById(id) || logError(`no id found for ${id}`); + }, + removeClass(el, className) { + el.classList.remove(className); + if (el.classList.length === 0) { + el.removeAttribute("class"); + } + }, + all(node, query, callback) { + if (!node) { + return []; + } + let array = Array.from(node.querySelectorAll(query)); + return callback ? array.forEach(callback) : array; + }, + childNodeLength(html) { + let template = document.createElement("template"); + template.innerHTML = html; + return template.content.childElementCount; + }, + isUploadInput(el) { + return el.type === "file" && el.getAttribute(PHX_UPLOAD_REF) !== null; + }, + isAutoUpload(inputEl) { + return inputEl.hasAttribute("data-phx-auto-upload"); + }, + findUploadInputs(node) { + return this.all(node, `input[type="file"][${PHX_UPLOAD_REF}]`); + }, + findComponentNodeList(node, cid) { + return this.filterWithinSameLiveView(this.all(node, `[${PHX_COMPONENT}="${cid}"]`), node); + }, + isPhxDestroyed(node) { + return node.id && DOM.private(node, "destroyed") ? true : false; + }, + wantsNewTab(e) { + let wantsNewTab = e.ctrlKey || e.shiftKey || e.metaKey || e.button && e.button === 1; + let isDownload = e.target instanceof HTMLAnchorElement && e.target.hasAttribute("download"); + let isTargetBlank = e.target.hasAttribute("target") && e.target.getAttribute("target").toLowerCase() === "_blank"; + return wantsNewTab || isTargetBlank || isDownload; + }, + isUnloadableFormSubmit(e) { + let isDialogSubmit = e.target && e.target.getAttribute("method") === "dialog" || e.submitter && e.submitter.getAttribute("formmethod") === "dialog"; + if (isDialogSubmit) { + return false; + } else { + return !e.defaultPrevented && !this.wantsNewTab(e); + } + }, + isNewPageClick(e, currentLocation) { + let href = e.target instanceof HTMLAnchorElement ? e.target.getAttribute("href") : null; + let url; + if (e.defaultPrevented || href === null || this.wantsNewTab(e)) { + return false; + } + if (href.startsWith("mailto:") || href.startsWith("tel:")) { + return false; + } + if (e.target.isContentEditable) { + return false; + } + try { + url = new URL(href); + } catch (e2) { + try { + url = new URL(href, currentLocation); + } catch (e3) { + return true; + } + } + if (url.host === currentLocation.host && url.protocol === currentLocation.protocol) { + if (url.pathname === currentLocation.pathname && url.search === currentLocation.search) { + return url.hash === "" && !url.href.endsWith("#"); + } + } + return url.protocol.startsWith("http"); + }, + markPhxChildDestroyed(el) { + if (this.isPhxChild(el)) { + el.setAttribute(PHX_SESSION, ""); + } + this.putPrivate(el, "destroyed", true); + }, + findPhxChildrenInFragment(html, parentId) { + let template = document.createElement("template"); + template.innerHTML = html; + return this.findPhxChildren(template.content, parentId); + }, + isIgnored(el, phxUpdate) { + return (el.getAttribute(phxUpdate) || el.getAttribute("data-phx-update")) === "ignore"; + }, + isPhxUpdate(el, phxUpdate, updateTypes) { + return el.getAttribute && updateTypes.indexOf(el.getAttribute(phxUpdate)) >= 0; + }, + findPhxSticky(el) { + return this.all(el, `[${PHX_STICKY}]`); + }, + findPhxChildren(el, parentId) { + return this.all(el, `${PHX_VIEW_SELECTOR}[${PHX_PARENT_ID}="${parentId}"]`); + }, + findParentCIDs(node, cids) { + let initial = new Set(cids); + let parentCids = cids.reduce((acc, cid) => { + let selector = `[${PHX_COMPONENT}="${cid}"] [${PHX_COMPONENT}]`; + this.filterWithinSameLiveView(this.all(node, selector), node).map((el) => parseInt(el.getAttribute(PHX_COMPONENT))).forEach((childCID) => acc.delete(childCID)); + return acc; + }, initial); + return parentCids.size === 0 ? new Set(cids) : parentCids; + }, + filterWithinSameLiveView(nodes, parent) { + if (parent.querySelector(PHX_VIEW_SELECTOR)) { + return nodes.filter((el) => this.withinSameLiveView(el, parent)); + } else { + return nodes; + } + }, + withinSameLiveView(node, parent) { + while (node = node.parentNode) { + if (node.isSameNode(parent)) { + return true; + } + if (node.getAttribute(PHX_SESSION) !== null) { + return false; + } + } + }, + private(el, key) { + return el[PHX_PRIVATE] && el[PHX_PRIVATE][key]; + }, + deletePrivate(el, key) { + el[PHX_PRIVATE] && delete el[PHX_PRIVATE][key]; + }, + putPrivate(el, key, value) { + if (!el[PHX_PRIVATE]) { + el[PHX_PRIVATE] = {}; + } + el[PHX_PRIVATE][key] = value; + }, + updatePrivate(el, key, defaultVal, updateFunc) { + let existing = this.private(el, key); + if (existing === void 0) { + this.putPrivate(el, key, updateFunc(defaultVal)); + } else { + this.putPrivate(el, key, updateFunc(existing)); + } + }, + copyPrivates(target, source) { + if (source[PHX_PRIVATE]) { + target[PHX_PRIVATE] = source[PHX_PRIVATE]; + } + }, + putTitle(str) { + let titleEl = document.querySelector("title"); + if (titleEl) { + let { prefix, suffix } = titleEl.dataset; + document.title = `${prefix || ""}${str}${suffix || ""}`; + } else { + document.title = str; + } + }, + debounce(el, event, phxDebounce, defaultDebounce, phxThrottle, defaultThrottle, asyncFilter, callback) { + let debounce = el.getAttribute(phxDebounce); + let throttle = el.getAttribute(phxThrottle); + if (debounce === "") { + debounce = defaultDebounce; + } + if (throttle === "") { + throttle = defaultThrottle; + } + let value = debounce || throttle; + switch (value) { + case null: + return callback(); + case "blur": + if (this.once(el, "debounce-blur")) { + el.addEventListener("blur", () => callback()); + } + return; + default: + let timeout = parseInt(value); + let trigger = () => throttle ? this.deletePrivate(el, THROTTLED) : callback(); + let currentCycle = this.incCycle(el, DEBOUNCE_TRIGGER, trigger); + if (isNaN(timeout)) { + return logError(`invalid throttle/debounce value: ${value}`); + } + if (throttle) { + let newKeyDown = false; + if (event.type === "keydown") { + let prevKey = this.private(el, DEBOUNCE_PREV_KEY); + this.putPrivate(el, DEBOUNCE_PREV_KEY, event.key); + newKeyDown = prevKey !== event.key; + } + if (!newKeyDown && this.private(el, THROTTLED)) { + return false; + } else { + callback(); + this.putPrivate(el, THROTTLED, true); + setTimeout(() => { + if (asyncFilter()) { + this.triggerCycle(el, DEBOUNCE_TRIGGER); + } + }, timeout); + } + } else { + setTimeout(() => { + if (asyncFilter()) { + this.triggerCycle(el, DEBOUNCE_TRIGGER, currentCycle); + } + }, timeout); + } + let form = el.form; + if (form && this.once(form, "bind-debounce")) { + form.addEventListener("submit", () => { + Array.from(new FormData(form).entries(), ([name]) => { + let input = form.querySelector(`[name="${name}"]`); + this.incCycle(input, DEBOUNCE_TRIGGER); + this.deletePrivate(input, THROTTLED); + }); + }); + } + if (this.once(el, "bind-debounce")) { + el.addEventListener("blur", () => this.triggerCycle(el, DEBOUNCE_TRIGGER)); + } + } + }, + triggerCycle(el, key, currentCycle) { + let [cycle, trigger] = this.private(el, key); + if (!currentCycle) { + currentCycle = cycle; + } + if (currentCycle === cycle) { + this.incCycle(el, key); + trigger(); + } + }, + once(el, key) { + if (this.private(el, key) === true) { + return false; + } + this.putPrivate(el, key, true); + return true; + }, + incCycle(el, key, trigger = function() { + }) { + let [currentCycle] = this.private(el, key) || [0, trigger]; + currentCycle++; + this.putPrivate(el, key, [currentCycle, trigger]); + return currentCycle; + }, + maybeAddPrivateHooks(el, phxViewportTop, phxViewportBottom) { + if (el.hasAttribute && (el.hasAttribute(phxViewportTop) || el.hasAttribute(phxViewportBottom))) { + el.setAttribute("data-phx-hook", "Phoenix.InfiniteScroll"); + } + }, + maybeHideFeedback(container, input, phxFeedbackFor) { + if (!(this.private(input, PHX_HAS_FOCUSED) || this.private(input, PHX_HAS_SUBMITTED))) { + let feedbacks = [input.name]; + if (input.name.endsWith("[]")) { + feedbacks.push(input.name.slice(0, -2)); + } + let selector = feedbacks.map((f) => `[${phxFeedbackFor}="${f}"]`).join(", "); + DOM.all(container, selector, (el) => el.classList.add(PHX_NO_FEEDBACK_CLASS)); + } + }, + resetForm(form, phxFeedbackFor) { + Array.from(form.elements).forEach((input) => { + let query = `[${phxFeedbackFor}="${input.id}"], + [${phxFeedbackFor}="${input.name}"], + [${phxFeedbackFor}="${input.name.replace(/\[\]$/, "")}"]`; + this.deletePrivate(input, PHX_HAS_FOCUSED); + this.deletePrivate(input, PHX_HAS_SUBMITTED); + this.all(document, query, (feedbackEl) => { + feedbackEl.classList.add(PHX_NO_FEEDBACK_CLASS); + }); + }); + }, + showError(inputEl, phxFeedbackFor) { + if (inputEl.id || inputEl.name) { + this.all(inputEl.form, `[${phxFeedbackFor}="${inputEl.id}"], [${phxFeedbackFor}="${inputEl.name}"]`, (el) => { + this.removeClass(el, PHX_NO_FEEDBACK_CLASS); + }); + } + }, + isPhxChild(node) { + return node.getAttribute && node.getAttribute(PHX_PARENT_ID); + }, + isPhxSticky(node) { + return node.getAttribute && node.getAttribute(PHX_STICKY) !== null; + }, + firstPhxChild(el) { + return this.isPhxChild(el) ? el : this.all(el, `[${PHX_PARENT_ID}]`)[0]; + }, + dispatchEvent(target, name, opts = {}) { + let bubbles = opts.bubbles === void 0 ? true : !!opts.bubbles; + let eventOpts = { bubbles, cancelable: true, detail: opts.detail || {} }; + let event = name === "click" ? new MouseEvent("click", eventOpts) : new CustomEvent(name, eventOpts); + target.dispatchEvent(event); + }, + cloneNode(node, html) { + if (typeof html === "undefined") { + return node.cloneNode(true); + } else { + let cloned = node.cloneNode(false); + cloned.innerHTML = html; + return cloned; + } + }, + mergeAttrs(target, source, opts = {}) { + let exclude = opts.exclude || []; + let isIgnored = opts.isIgnored; + let sourceAttrs = source.attributes; + for (let i = sourceAttrs.length - 1; i >= 0; i--) { + let name = sourceAttrs[i].name; + if (exclude.indexOf(name) < 0) { + target.setAttribute(name, source.getAttribute(name)); + } + } + let targetAttrs = target.attributes; + for (let i = targetAttrs.length - 1; i >= 0; i--) { + let name = targetAttrs[i].name; + if (isIgnored) { + if (name.startsWith("data-") && !source.hasAttribute(name)) { + target.removeAttribute(name); + } + } else { + if (!source.hasAttribute(name)) { + target.removeAttribute(name); + } + } + } + }, + mergeFocusedInput(target, source) { + if (!(target instanceof HTMLSelectElement)) { + DOM.mergeAttrs(target, source, { exclude: ["value"] }); + } + if (source.readOnly) { + target.setAttribute("readonly", true); + } else { + target.removeAttribute("readonly"); + } + }, + hasSelectionRange(el) { + return el.setSelectionRange && (el.type === "text" || el.type === "textarea"); + }, + restoreFocus(focused, selectionStart, selectionEnd) { + if (!DOM.isTextualInput(focused)) { + return; + } + let wasFocused = focused.matches(":focus"); + if (focused.readOnly) { + focused.blur(); + } + if (!wasFocused) { + focused.focus(); + } + if (this.hasSelectionRange(focused)) { + focused.setSelectionRange(selectionStart, selectionEnd); + } + }, + isFormInput(el) { + return /^(?:input|select|textarea)$/i.test(el.tagName) && el.type !== "button"; + }, + syncAttrsToProps(el) { + if (el instanceof HTMLInputElement && CHECKABLE_INPUTS.indexOf(el.type.toLocaleLowerCase()) >= 0) { + el.checked = el.getAttribute("checked") !== null; + } + }, + isTextualInput(el) { + return FOCUSABLE_INPUTS.indexOf(el.type) >= 0; + }, + isNowTriggerFormExternal(el, phxTriggerExternal) { + return el.getAttribute && el.getAttribute(phxTriggerExternal) !== null; + }, + syncPendingRef(fromEl, toEl, disableWith) { + let ref = fromEl.getAttribute(PHX_REF); + if (ref === null) { + return true; + } + let refSrc = fromEl.getAttribute(PHX_REF_SRC); + if (DOM.isFormInput(fromEl) || fromEl.getAttribute(disableWith) !== null) { + if (DOM.isUploadInput(fromEl)) { + DOM.mergeAttrs(fromEl, toEl, { isIgnored: true }); + } + DOM.putPrivate(fromEl, PHX_REF, toEl); + return false; + } else { + PHX_EVENT_CLASSES.forEach((className) => { + fromEl.classList.contains(className) && toEl.classList.add(className); + }); + toEl.setAttribute(PHX_REF, ref); + toEl.setAttribute(PHX_REF_SRC, refSrc); + return true; + } + }, + cleanChildNodes(container, phxUpdate) { + if (DOM.isPhxUpdate(container, phxUpdate, ["append", "prepend"])) { + let toRemove = []; + container.childNodes.forEach((childNode) => { + if (!childNode.id) { + let isEmptyTextNode = childNode.nodeType === Node.TEXT_NODE && childNode.nodeValue.trim() === ""; + if (!isEmptyTextNode) { + logError(`only HTML element tags with an id are allowed inside containers with phx-update. + +removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}" + +`); + } + toRemove.push(childNode); + } + }); + toRemove.forEach((childNode) => childNode.remove()); + } + }, + replaceRootContainer(container, tagName, attrs) { + let retainedAttrs = /* @__PURE__ */ new Set(["id", PHX_SESSION, PHX_STATIC, PHX_MAIN, PHX_ROOT_ID]); + if (container.tagName.toLowerCase() === tagName.toLowerCase()) { + Array.from(container.attributes).filter((attr) => !retainedAttrs.has(attr.name.toLowerCase())).forEach((attr) => container.removeAttribute(attr.name)); + Object.keys(attrs).filter((name) => !retainedAttrs.has(name.toLowerCase())).forEach((attr) => container.setAttribute(attr, attrs[attr])); + return container; + } else { + let newContainer = document.createElement(tagName); + Object.keys(attrs).forEach((attr) => newContainer.setAttribute(attr, attrs[attr])); + retainedAttrs.forEach((attr) => newContainer.setAttribute(attr, container.getAttribute(attr))); + newContainer.innerHTML = container.innerHTML; + container.replaceWith(newContainer); + return newContainer; + } + }, + getSticky(el, name, defaultVal) { + let op = (DOM.private(el, "sticky") || []).find(([existingName]) => name === existingName); + if (op) { + let [_name, _op, stashedResult] = op; + return stashedResult; + } else { + return typeof defaultVal === "function" ? defaultVal() : defaultVal; + } + }, + deleteSticky(el, name) { + this.updatePrivate(el, "sticky", [], (ops) => { + return ops.filter(([existingName, _]) => existingName !== name); + }); + }, + putSticky(el, name, op) { + let stashedResult = op(el); + this.updatePrivate(el, "sticky", [], (ops) => { + let existingIndex = ops.findIndex(([existingName]) => name === existingName); + if (existingIndex >= 0) { + ops[existingIndex] = [name, op, stashedResult]; + } else { + ops.push([name, op, stashedResult]); + } + return ops; + }); + }, + applyStickyOperations(el) { + let ops = DOM.private(el, "sticky"); + if (!ops) { + return; + } + ops.forEach(([name, op, _stashed]) => this.putSticky(el, name, op)); + } + }; + var dom_default = DOM; + var UploadEntry = class { + static isActive(fileEl, file) { + let isNew = file._phxRef === void 0; + let activeRefs = fileEl.getAttribute(PHX_ACTIVE_ENTRY_REFS).split(","); + let isActive = activeRefs.indexOf(LiveUploader.genFileRef(file)) >= 0; + return file.size > 0 && (isNew || isActive); + } + static isPreflighted(fileEl, file) { + let preflightedRefs = fileEl.getAttribute(PHX_PREFLIGHTED_REFS).split(","); + let isPreflighted = preflightedRefs.indexOf(LiveUploader.genFileRef(file)) >= 0; + return isPreflighted && this.isActive(fileEl, file); + } + constructor(fileEl, file, view) { + this.ref = LiveUploader.genFileRef(file); + this.fileEl = fileEl; + this.file = file; + this.view = view; + this.meta = null; + this._isCancelled = false; + this._isDone = false; + this._progress = 0; + this._lastProgressSent = -1; + this._onDone = function() { + }; + this._onElUpdated = this.onElUpdated.bind(this); + this.fileEl.addEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated); + } + metadata() { + return this.meta; + } + progress(progress) { + this._progress = Math.floor(progress); + if (this._progress > this._lastProgressSent) { + if (this._progress >= 100) { + this._progress = 100; + this._lastProgressSent = 100; + this._isDone = true; + this.view.pushFileProgress(this.fileEl, this.ref, 100, () => { + LiveUploader.untrackFile(this.fileEl, this.file); + this._onDone(); + }); + } else { + this._lastProgressSent = this._progress; + this.view.pushFileProgress(this.fileEl, this.ref, this._progress); + } + } + } + cancel() { + this._isCancelled = true; + this._isDone = true; + this._onDone(); + } + isDone() { + return this._isDone; + } + error(reason = "failed") { + this.fileEl.removeEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated); + this.view.pushFileProgress(this.fileEl, this.ref, { error: reason }); + if (!dom_default.isAutoUpload(this.fileEl)) { + LiveUploader.clearFiles(this.fileEl); + } + } + onDone(callback) { + this._onDone = () => { + this.fileEl.removeEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated); + callback(); + }; + } + onElUpdated() { + let activeRefs = this.fileEl.getAttribute(PHX_ACTIVE_ENTRY_REFS).split(","); + if (activeRefs.indexOf(this.ref) === -1) { + this.cancel(); + } + } + toPreflightPayload() { + return { + last_modified: this.file.lastModified, + name: this.file.name, + relative_path: this.file.webkitRelativePath, + size: this.file.size, + type: this.file.type, + ref: this.ref + }; + } + uploader(uploaders) { + if (this.meta.uploader) { + let callback = uploaders[this.meta.uploader] || logError(`no uploader configured for ${this.meta.uploader}`); + return { name: this.meta.uploader, callback }; + } else { + return { name: "channel", callback: channelUploader }; + } + } + zipPostFlight(resp) { + this.meta = resp.entries[this.ref]; + if (!this.meta) { + logError(`no preflight upload response returned with ref ${this.ref}`, { input: this.fileEl, response: resp }); + } + } + }; + var liveUploaderFileRef = 0; + var LiveUploader = class { + static genFileRef(file) { + let ref = file._phxRef; + if (ref !== void 0) { + return ref; + } else { + file._phxRef = (liveUploaderFileRef++).toString(); + return file._phxRef; + } + } + static getEntryDataURL(inputEl, ref, callback) { + let file = this.activeFiles(inputEl).find((file2) => this.genFileRef(file2) === ref); + callback(URL.createObjectURL(file)); + } + static hasUploadsInProgress(formEl) { + let active = 0; + dom_default.findUploadInputs(formEl).forEach((input) => { + if (input.getAttribute(PHX_PREFLIGHTED_REFS) !== input.getAttribute(PHX_DONE_REFS)) { + active++; + } + }); + return active > 0; + } + static serializeUploads(inputEl) { + let files = this.activeFiles(inputEl); + let fileData = {}; + files.forEach((file) => { + let entry = { path: inputEl.name }; + let uploadRef = inputEl.getAttribute(PHX_UPLOAD_REF); + fileData[uploadRef] = fileData[uploadRef] || []; + entry.ref = this.genFileRef(file); + entry.last_modified = file.lastModified; + entry.name = file.name || entry.ref; + entry.relative_path = file.webkitRelativePath; + entry.type = file.type; + entry.size = file.size; + fileData[uploadRef].push(entry); + }); + return fileData; + } + static clearFiles(inputEl) { + inputEl.value = null; + inputEl.removeAttribute(PHX_UPLOAD_REF); + dom_default.putPrivate(inputEl, "files", []); + } + static untrackFile(inputEl, file) { + dom_default.putPrivate(inputEl, "files", dom_default.private(inputEl, "files").filter((f) => !Object.is(f, file))); + } + static trackFiles(inputEl, files, dataTransfer) { + if (inputEl.getAttribute("multiple") !== null) { + let newFiles = files.filter((file) => !this.activeFiles(inputEl).find((f) => Object.is(f, file))); + dom_default.putPrivate(inputEl, "files", this.activeFiles(inputEl).concat(newFiles)); + inputEl.value = null; + } else { + if (dataTransfer && dataTransfer.files.length > 0) { + inputEl.files = dataTransfer.files; + } + dom_default.putPrivate(inputEl, "files", files); + } + } + static activeFileInputs(formEl) { + let fileInputs = dom_default.findUploadInputs(formEl); + return Array.from(fileInputs).filter((el) => el.files && this.activeFiles(el).length > 0); + } + static activeFiles(input) { + return (dom_default.private(input, "files") || []).filter((f) => UploadEntry.isActive(input, f)); + } + static inputsAwaitingPreflight(formEl) { + let fileInputs = dom_default.findUploadInputs(formEl); + return Array.from(fileInputs).filter((input) => this.filesAwaitingPreflight(input).length > 0); + } + static filesAwaitingPreflight(input) { + return this.activeFiles(input).filter((f) => !UploadEntry.isPreflighted(input, f)); + } + constructor(inputEl, view, onComplete) { + this.view = view; + this.onComplete = onComplete; + this._entries = Array.from(LiveUploader.filesAwaitingPreflight(inputEl) || []).map((file) => new UploadEntry(inputEl, file, view)); + this.numEntriesInProgress = this._entries.length; + } + entries() { + return this._entries; + } + initAdapterUpload(resp, onError, liveSocket2) { + this._entries = this._entries.map((entry) => { + entry.zipPostFlight(resp); + entry.onDone(() => { + this.numEntriesInProgress--; + if (this.numEntriesInProgress === 0) { + this.onComplete(); + } + }); + return entry; + }); + let groupedEntries = this._entries.reduce((acc, entry) => { + if (!entry.meta) { + return acc; + } + let { name, callback } = entry.uploader(liveSocket2.uploaders); + acc[name] = acc[name] || { callback, entries: [] }; + acc[name].entries.push(entry); + return acc; + }, {}); + for (let name in groupedEntries) { + let { callback, entries } = groupedEntries[name]; + callback(entries, onError, resp, liveSocket2); + } + } + }; + var ARIA = { + focusMain() { + let target = document.querySelector("main h1, main, h1"); + if (target) { + let origTabIndex = target.tabIndex; + target.tabIndex = -1; + target.focus(); + target.tabIndex = origTabIndex; + } + }, + anyOf(instance, classes) { + return classes.find((name) => instance instanceof name); + }, + isFocusable(el, interactiveOnly) { + return el instanceof HTMLAnchorElement && el.rel !== "ignore" || el instanceof HTMLAreaElement && el.href !== void 0 || !el.disabled && this.anyOf(el, [HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement, HTMLButtonElement]) || el instanceof HTMLIFrameElement || (el.tabIndex > 0 || !interactiveOnly && el.tabIndex === 0 && el.getAttribute("tabindex") !== null && el.getAttribute("aria-hidden") !== "true"); + }, + attemptFocus(el, interactiveOnly) { + if (this.isFocusable(el, interactiveOnly)) { + try { + el.focus(); + } catch (e) { + } + } + return !!document.activeElement && document.activeElement.isSameNode(el); + }, + focusFirstInteractive(el) { + let child = el.firstElementChild; + while (child) { + if (this.attemptFocus(child, true) || this.focusFirstInteractive(child, true)) { + return true; + } + child = child.nextElementSibling; + } + }, + focusFirst(el) { + let child = el.firstElementChild; + while (child) { + if (this.attemptFocus(child) || this.focusFirst(child)) { + return true; + } + child = child.nextElementSibling; + } + }, + focusLast(el) { + let child = el.lastElementChild; + while (child) { + if (this.attemptFocus(child) || this.focusLast(child)) { + return true; + } + child = child.previousElementSibling; + } + } + }; + var aria_default = ARIA; + var Hooks = { + LiveFileUpload: { + activeRefs() { + return this.el.getAttribute(PHX_ACTIVE_ENTRY_REFS); + }, + preflightedRefs() { + return this.el.getAttribute(PHX_PREFLIGHTED_REFS); + }, + mounted() { + this.preflightedWas = this.preflightedRefs(); + }, + updated() { + let newPreflights = this.preflightedRefs(); + if (this.preflightedWas !== newPreflights) { + this.preflightedWas = newPreflights; + if (newPreflights === "") { + this.__view.cancelSubmit(this.el.form); + } + } + if (this.activeRefs() === "") { + this.el.value = null; + } + this.el.dispatchEvent(new CustomEvent(PHX_LIVE_FILE_UPDATED)); + } + }, + LiveImgPreview: { + mounted() { + this.ref = this.el.getAttribute("data-phx-entry-ref"); + this.inputEl = document.getElementById(this.el.getAttribute(PHX_UPLOAD_REF)); + LiveUploader.getEntryDataURL(this.inputEl, this.ref, (url) => { + this.url = url; + this.el.src = url; + }); + }, + destroyed() { + URL.revokeObjectURL(this.url); + } + }, + FocusWrap: { + mounted() { + this.focusStart = this.el.firstElementChild; + this.focusEnd = this.el.lastElementChild; + this.focusStart.addEventListener("focus", () => aria_default.focusLast(this.el)); + this.focusEnd.addEventListener("focus", () => aria_default.focusFirst(this.el)); + this.el.addEventListener("phx:show-end", () => this.el.focus()); + if (window.getComputedStyle(this.el).display !== "none") { + aria_default.focusFirst(this.el); + } + } + } + }; + var scrollTop = () => document.documentElement.scrollTop || document.body.scrollTop; + var winHeight = () => window.innerHeight || document.documentElement.clientHeight; + var isAtViewportTop = (el) => { + let rect = el.getBoundingClientRect(); + return rect.top >= 0 && rect.left >= 0 && rect.top <= winHeight(); + }; + var isAtViewportBottom = (el) => { + let rect = el.getBoundingClientRect(); + return rect.right >= 0 && rect.left >= 0 && rect.bottom <= winHeight(); + }; + var isWithinViewport = (el) => { + let rect = el.getBoundingClientRect(); + return rect.top >= 0 && rect.left >= 0 && rect.top <= winHeight(); + }; + Hooks.InfiniteScroll = { + mounted() { + let scrollBefore = scrollTop(); + let topOverran = false; + let throttleInterval = 500; + let pendingOp = null; + let onTopOverrun = this.throttle(throttleInterval, (topEvent, firstChild) => { + pendingOp = () => true; + this.liveSocket.execJSHookPush(this.el, topEvent, { id: firstChild.id, _overran: true }, () => { + pendingOp = null; + }); + }); + let onFirstChildAtTop = this.throttle(throttleInterval, (topEvent, firstChild) => { + pendingOp = () => firstChild.scrollIntoView({ block: "start" }); + this.liveSocket.execJSHookPush(this.el, topEvent, { id: firstChild.id }, () => { + pendingOp = null; + if (!isWithinViewport(firstChild)) { + firstChild.scrollIntoView({ block: "start" }); + } + }); + }); + let onLastChildAtBottom = this.throttle(throttleInterval, (bottomEvent, lastChild) => { + pendingOp = () => lastChild.scrollIntoView({ block: "end" }); + this.liveSocket.execJSHookPush(this.el, bottomEvent, { id: lastChild.id }, () => { + pendingOp = null; + if (!isWithinViewport(lastChild)) { + lastChild.scrollIntoView({ block: "end" }); + } + }); + }); + this.onScroll = (e) => { + let scrollNow = scrollTop(); + if (pendingOp) { + scrollBefore = scrollNow; + return pendingOp(); + } + let rect = this.el.getBoundingClientRect(); + let topEvent = this.el.getAttribute(this.liveSocket.binding("viewport-top")); + let bottomEvent = this.el.getAttribute(this.liveSocket.binding("viewport-bottom")); + let lastChild = this.el.lastElementChild; + let firstChild = this.el.firstElementChild; + let isScrollingUp = scrollNow < scrollBefore; + let isScrollingDown = scrollNow > scrollBefore; + if (isScrollingUp && topEvent && !topOverran && rect.top >= 0) { + topOverran = true; + onTopOverrun(topEvent, firstChild); + } else if (isScrollingDown && topOverran && rect.top <= 0) { + topOverran = false; + } + if (topEvent && isScrollingUp && isAtViewportTop(firstChild)) { + onFirstChildAtTop(topEvent, firstChild); + } else if (bottomEvent && isScrollingDown && isAtViewportBottom(lastChild)) { + onLastChildAtBottom(bottomEvent, lastChild); + } + scrollBefore = scrollNow; + }; + window.addEventListener("scroll", this.onScroll); + }, + destroyed() { + window.removeEventListener("scroll", this.onScroll); + }, + throttle(interval, callback) { + let lastCallAt = 0; + let timer; + return (...args) => { + let now = Date.now(); + let remainingTime = interval - (now - lastCallAt); + if (remainingTime <= 0 || remainingTime > interval) { + if (timer) { + clearTimeout(timer); + timer = null; + } + lastCallAt = now; + callback(...args); + } else if (!timer) { + timer = setTimeout(() => { + lastCallAt = Date.now(); + timer = null; + callback(...args); + }, remainingTime); + } + }; + } + }; + var hooks_default = Hooks; + var DOMPostMorphRestorer = class { + constructor(containerBefore, containerAfter, updateType) { + let idsBefore = /* @__PURE__ */ new Set(); + let idsAfter = new Set([...containerAfter.children].map((child) => child.id)); + let elementsToModify = []; + Array.from(containerBefore.children).forEach((child) => { + if (child.id) { + idsBefore.add(child.id); + if (idsAfter.has(child.id)) { + let previousElementId = child.previousElementSibling && child.previousElementSibling.id; + elementsToModify.push({ elementId: child.id, previousElementId }); + } + } + }); + this.containerId = containerAfter.id; + this.updateType = updateType; + this.elementsToModify = elementsToModify; + this.elementIdsToAdd = [...idsAfter].filter((id) => !idsBefore.has(id)); + } + perform() { + let container = dom_default.byId(this.containerId); + this.elementsToModify.forEach((elementToModify) => { + if (elementToModify.previousElementId) { + maybe(document.getElementById(elementToModify.previousElementId), (previousElem) => { + maybe(document.getElementById(elementToModify.elementId), (elem) => { + let isInRightPlace = elem.previousElementSibling && elem.previousElementSibling.id == previousElem.id; + if (!isInRightPlace) { + previousElem.insertAdjacentElement("afterend", elem); + } + }); + }); + } else { + maybe(document.getElementById(elementToModify.elementId), (elem) => { + let isInRightPlace = elem.previousElementSibling == null; + if (!isInRightPlace) { + container.insertAdjacentElement("afterbegin", elem); + } + }); + } + }); + if (this.updateType == "prepend") { + this.elementIdsToAdd.reverse().forEach((elemId) => { + maybe(document.getElementById(elemId), (elem) => container.insertAdjacentElement("afterbegin", elem)); + }); + } + } + }; + var DOCUMENT_FRAGMENT_NODE = 11; + function morphAttrs(fromNode, toNode) { + var toNodeAttrs = toNode.attributes; + var attr; + var attrName; + var attrNamespaceURI; + var attrValue; + var fromValue; + if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE || fromNode.nodeType === DOCUMENT_FRAGMENT_NODE) { + return; + } + for (var i = toNodeAttrs.length - 1; i >= 0; i--) { + attr = toNodeAttrs[i]; + attrName = attr.name; + attrNamespaceURI = attr.namespaceURI; + attrValue = attr.value; + if (attrNamespaceURI) { + attrName = attr.localName || attrName; + fromValue = fromNode.getAttributeNS(attrNamespaceURI, attrName); + if (fromValue !== attrValue) { + if (attr.prefix === "xmlns") { + attrName = attr.name; + } + fromNode.setAttributeNS(attrNamespaceURI, attrName, attrValue); + } + } else { + fromValue = fromNode.getAttribute(attrName); + if (fromValue !== attrValue) { + fromNode.setAttribute(attrName, attrValue); + } + } + } + var fromNodeAttrs = fromNode.attributes; + for (var d = fromNodeAttrs.length - 1; d >= 0; d--) { + attr = fromNodeAttrs[d]; + attrName = attr.name; + attrNamespaceURI = attr.namespaceURI; + if (attrNamespaceURI) { + attrName = attr.localName || attrName; + if (!toNode.hasAttributeNS(attrNamespaceURI, attrName)) { + fromNode.removeAttributeNS(attrNamespaceURI, attrName); + } + } else { + if (!toNode.hasAttribute(attrName)) { + fromNode.removeAttribute(attrName); + } + } + } + } + var range; + var NS_XHTML = "http://www.w3.org/1999/xhtml"; + var doc = typeof document === "undefined" ? void 0 : document; + var HAS_TEMPLATE_SUPPORT = !!doc && "content" in doc.createElement("template"); + var HAS_RANGE_SUPPORT = !!doc && doc.createRange && "createContextualFragment" in doc.createRange(); + function createFragmentFromTemplate(str) { + var template = doc.createElement("template"); + template.innerHTML = str; + return template.content.childNodes[0]; + } + function createFragmentFromRange(str) { + if (!range) { + range = doc.createRange(); + range.selectNode(doc.body); + } + var fragment = range.createContextualFragment(str); + return fragment.childNodes[0]; + } + function createFragmentFromWrap(str) { + var fragment = doc.createElement("body"); + fragment.innerHTML = str; + return fragment.childNodes[0]; + } + function toElement(str) { + str = str.trim(); + if (HAS_TEMPLATE_SUPPORT) { + return createFragmentFromTemplate(str); + } else if (HAS_RANGE_SUPPORT) { + return createFragmentFromRange(str); + } + return createFragmentFromWrap(str); + } + function compareNodeNames(fromEl, toEl) { + var fromNodeName = fromEl.nodeName; + var toNodeName = toEl.nodeName; + var fromCodeStart, toCodeStart; + if (fromNodeName === toNodeName) { + return true; + } + fromCodeStart = fromNodeName.charCodeAt(0); + toCodeStart = toNodeName.charCodeAt(0); + if (fromCodeStart <= 90 && toCodeStart >= 97) { + return fromNodeName === toNodeName.toUpperCase(); + } else if (toCodeStart <= 90 && fromCodeStart >= 97) { + return toNodeName === fromNodeName.toUpperCase(); + } else { + return false; + } + } + function createElementNS(name, namespaceURI) { + return !namespaceURI || namespaceURI === NS_XHTML ? doc.createElement(name) : doc.createElementNS(namespaceURI, name); + } + function moveChildren(fromEl, toEl) { + var curChild = fromEl.firstChild; + while (curChild) { + var nextChild = curChild.nextSibling; + toEl.appendChild(curChild); + curChild = nextChild; + } + return toEl; + } + function syncBooleanAttrProp(fromEl, toEl, name) { + if (fromEl[name] !== toEl[name]) { + fromEl[name] = toEl[name]; + if (fromEl[name]) { + fromEl.setAttribute(name, ""); + } else { + fromEl.removeAttribute(name); + } + } + } + var specialElHandlers = { + OPTION: function(fromEl, toEl) { + var parentNode = fromEl.parentNode; + if (parentNode) { + var parentName = parentNode.nodeName.toUpperCase(); + if (parentName === "OPTGROUP") { + parentNode = parentNode.parentNode; + parentName = parentNode && parentNode.nodeName.toUpperCase(); + } + if (parentName === "SELECT" && !parentNode.hasAttribute("multiple")) { + if (fromEl.hasAttribute("selected") && !toEl.selected) { + fromEl.setAttribute("selected", "selected"); + fromEl.removeAttribute("selected"); + } + parentNode.selectedIndex = -1; + } + } + syncBooleanAttrProp(fromEl, toEl, "selected"); + }, + INPUT: function(fromEl, toEl) { + syncBooleanAttrProp(fromEl, toEl, "checked"); + syncBooleanAttrProp(fromEl, toEl, "disabled"); + if (fromEl.value !== toEl.value) { + fromEl.value = toEl.value; + } + if (!toEl.hasAttribute("value")) { + fromEl.removeAttribute("value"); + } + }, + TEXTAREA: function(fromEl, toEl) { + var newValue = toEl.value; + if (fromEl.value !== newValue) { + fromEl.value = newValue; + } + var firstChild = fromEl.firstChild; + if (firstChild) { + var oldValue = firstChild.nodeValue; + if (oldValue == newValue || !newValue && oldValue == fromEl.placeholder) { + return; + } + firstChild.nodeValue = newValue; + } + }, + SELECT: function(fromEl, toEl) { + if (!toEl.hasAttribute("multiple")) { + var selectedIndex = -1; + var i = 0; + var curChild = fromEl.firstChild; + var optgroup; + var nodeName; + while (curChild) { + nodeName = curChild.nodeName && curChild.nodeName.toUpperCase(); + if (nodeName === "OPTGROUP") { + optgroup = curChild; + curChild = optgroup.firstChild; + } else { + if (nodeName === "OPTION") { + if (curChild.hasAttribute("selected")) { + selectedIndex = i; + break; + } + i++; + } + curChild = curChild.nextSibling; + if (!curChild && optgroup) { + curChild = optgroup.nextSibling; + optgroup = null; + } + } + } + fromEl.selectedIndex = selectedIndex; + } + } + }; + var ELEMENT_NODE = 1; + var DOCUMENT_FRAGMENT_NODE$1 = 11; + var TEXT_NODE = 3; + var COMMENT_NODE = 8; + function noop() { + } + function defaultGetNodeKey(node) { + if (node) { + return node.getAttribute && node.getAttribute("id") || node.id; + } + } + function morphdomFactory(morphAttrs2) { + return function morphdom2(fromNode, toNode, options) { + if (!options) { + options = {}; + } + if (typeof toNode === "string") { + if (fromNode.nodeName === "#document" || fromNode.nodeName === "HTML" || fromNode.nodeName === "BODY") { + var toNodeHtml = toNode; + toNode = doc.createElement("html"); + toNode.innerHTML = toNodeHtml; + } else { + toNode = toElement(toNode); + } + } else if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE$1) { + toNode = toNode.firstElementChild; + } + var getNodeKey = options.getNodeKey || defaultGetNodeKey; + var onBeforeNodeAdded = options.onBeforeNodeAdded || noop; + var onNodeAdded = options.onNodeAdded || noop; + var onBeforeElUpdated = options.onBeforeElUpdated || noop; + var onElUpdated = options.onElUpdated || noop; + var onBeforeNodeDiscarded = options.onBeforeNodeDiscarded || noop; + var onNodeDiscarded = options.onNodeDiscarded || noop; + var onBeforeElChildrenUpdated = options.onBeforeElChildrenUpdated || noop; + var skipFromChildren = options.skipFromChildren || noop; + var addChild = options.addChild || function(parent, child) { + return parent.appendChild(child); + }; + var childrenOnly = options.childrenOnly === true; + var fromNodesLookup = /* @__PURE__ */ Object.create(null); + var keyedRemovalList = []; + function addKeyedRemoval(key) { + keyedRemovalList.push(key); + } + function walkDiscardedChildNodes(node, skipKeyedNodes) { + if (node.nodeType === ELEMENT_NODE) { + var curChild = node.firstChild; + while (curChild) { + var key = void 0; + if (skipKeyedNodes && (key = getNodeKey(curChild))) { + addKeyedRemoval(key); + } else { + onNodeDiscarded(curChild); + if (curChild.firstChild) { + walkDiscardedChildNodes(curChild, skipKeyedNodes); + } + } + curChild = curChild.nextSibling; + } + } + } + function removeNode(node, parentNode, skipKeyedNodes) { + if (onBeforeNodeDiscarded(node) === false) { + return; + } + if (parentNode) { + parentNode.removeChild(node); + } + onNodeDiscarded(node); + walkDiscardedChildNodes(node, skipKeyedNodes); + } + function indexTree(node) { + if (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE$1) { + var curChild = node.firstChild; + while (curChild) { + var key = getNodeKey(curChild); + if (key) { + fromNodesLookup[key] = curChild; + } + indexTree(curChild); + curChild = curChild.nextSibling; + } + } + } + indexTree(fromNode); + function handleNodeAdded(el) { + onNodeAdded(el); + var curChild = el.firstChild; + while (curChild) { + var nextSibling = curChild.nextSibling; + var key = getNodeKey(curChild); + if (key) { + var unmatchedFromEl = fromNodesLookup[key]; + if (unmatchedFromEl && compareNodeNames(curChild, unmatchedFromEl)) { + curChild.parentNode.replaceChild(unmatchedFromEl, curChild); + morphEl(unmatchedFromEl, curChild); + } else { + handleNodeAdded(curChild); + } + } else { + handleNodeAdded(curChild); + } + curChild = nextSibling; + } + } + function cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey) { + while (curFromNodeChild) { + var fromNextSibling = curFromNodeChild.nextSibling; + if (curFromNodeKey = getNodeKey(curFromNodeChild)) { + addKeyedRemoval(curFromNodeKey); + } else { + removeNode(curFromNodeChild, fromEl, true); + } + curFromNodeChild = fromNextSibling; + } + } + function morphEl(fromEl, toEl, childrenOnly2) { + var toElKey = getNodeKey(toEl); + if (toElKey) { + delete fromNodesLookup[toElKey]; + } + if (!childrenOnly2) { + if (onBeforeElUpdated(fromEl, toEl) === false) { + return; + } + morphAttrs2(fromEl, toEl); + onElUpdated(fromEl); + if (onBeforeElChildrenUpdated(fromEl, toEl) === false) { + return; + } + } + if (fromEl.nodeName !== "TEXTAREA") { + morphChildren(fromEl, toEl); + } else { + specialElHandlers.TEXTAREA(fromEl, toEl); + } + } + function morphChildren(fromEl, toEl) { + var skipFrom = skipFromChildren(fromEl); + var curToNodeChild = toEl.firstChild; + var curFromNodeChild = fromEl.firstChild; + var curToNodeKey; + var curFromNodeKey; + var fromNextSibling; + var toNextSibling; + var matchingFromEl; + outer: + while (curToNodeChild) { + toNextSibling = curToNodeChild.nextSibling; + curToNodeKey = getNodeKey(curToNodeChild); + while (!skipFrom && curFromNodeChild) { + fromNextSibling = curFromNodeChild.nextSibling; + if (curToNodeChild.isSameNode && curToNodeChild.isSameNode(curFromNodeChild)) { + curToNodeChild = toNextSibling; + curFromNodeChild = fromNextSibling; + continue outer; + } + curFromNodeKey = getNodeKey(curFromNodeChild); + var curFromNodeType = curFromNodeChild.nodeType; + var isCompatible = void 0; + if (curFromNodeType === curToNodeChild.nodeType) { + if (curFromNodeType === ELEMENT_NODE) { + if (curToNodeKey) { + if (curToNodeKey !== curFromNodeKey) { + if (matchingFromEl = fromNodesLookup[curToNodeKey]) { + if (fromNextSibling === matchingFromEl) { + isCompatible = false; + } else { + fromEl.insertBefore(matchingFromEl, curFromNodeChild); + if (curFromNodeKey) { + addKeyedRemoval(curFromNodeKey); + } else { + removeNode(curFromNodeChild, fromEl, true); + } + curFromNodeChild = matchingFromEl; + } + } else { + isCompatible = false; + } + } + } else if (curFromNodeKey) { + isCompatible = false; + } + isCompatible = isCompatible !== false && compareNodeNames(curFromNodeChild, curToNodeChild); + if (isCompatible) { + morphEl(curFromNodeChild, curToNodeChild); + } + } else if (curFromNodeType === TEXT_NODE || curFromNodeType == COMMENT_NODE) { + isCompatible = true; + if (curFromNodeChild.nodeValue !== curToNodeChild.nodeValue) { + curFromNodeChild.nodeValue = curToNodeChild.nodeValue; + } + } + } + if (isCompatible) { + curToNodeChild = toNextSibling; + curFromNodeChild = fromNextSibling; + continue outer; + } + if (curFromNodeKey) { + addKeyedRemoval(curFromNodeKey); + } else { + removeNode(curFromNodeChild, fromEl, true); + } + curFromNodeChild = fromNextSibling; + } + if (curToNodeKey && (matchingFromEl = fromNodesLookup[curToNodeKey]) && compareNodeNames(matchingFromEl, curToNodeChild)) { + if (!skipFrom) { + addChild(fromEl, matchingFromEl); + } + morphEl(matchingFromEl, curToNodeChild); + } else { + var onBeforeNodeAddedResult = onBeforeNodeAdded(curToNodeChild); + if (onBeforeNodeAddedResult !== false) { + if (onBeforeNodeAddedResult) { + curToNodeChild = onBeforeNodeAddedResult; + } + if (curToNodeChild.actualize) { + curToNodeChild = curToNodeChild.actualize(fromEl.ownerDocument || doc); + } + addChild(fromEl, curToNodeChild); + handleNodeAdded(curToNodeChild); + } + } + curToNodeChild = toNextSibling; + curFromNodeChild = fromNextSibling; + } + cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey); + var specialElHandler = specialElHandlers[fromEl.nodeName]; + if (specialElHandler) { + specialElHandler(fromEl, toEl); + } + } + var morphedNode = fromNode; + var morphedNodeType = morphedNode.nodeType; + var toNodeType = toNode.nodeType; + if (!childrenOnly) { + if (morphedNodeType === ELEMENT_NODE) { + if (toNodeType === ELEMENT_NODE) { + if (!compareNodeNames(fromNode, toNode)) { + onNodeDiscarded(fromNode); + morphedNode = moveChildren(fromNode, createElementNS(toNode.nodeName, toNode.namespaceURI)); + } + } else { + morphedNode = toNode; + } + } else if (morphedNodeType === TEXT_NODE || morphedNodeType === COMMENT_NODE) { + if (toNodeType === morphedNodeType) { + if (morphedNode.nodeValue !== toNode.nodeValue) { + morphedNode.nodeValue = toNode.nodeValue; + } + return morphedNode; + } else { + morphedNode = toNode; + } + } + } + if (morphedNode === toNode) { + onNodeDiscarded(fromNode); + } else { + if (toNode.isSameNode && toNode.isSameNode(morphedNode)) { + return; + } + morphEl(morphedNode, toNode, childrenOnly); + if (keyedRemovalList) { + for (var i = 0, len = keyedRemovalList.length; i < len; i++) { + var elToRemove = fromNodesLookup[keyedRemovalList[i]]; + if (elToRemove) { + removeNode(elToRemove, elToRemove.parentNode, false); + } + } + } + } + if (!childrenOnly && morphedNode !== fromNode && fromNode.parentNode) { + if (morphedNode.actualize) { + morphedNode = morphedNode.actualize(fromNode.ownerDocument || doc); + } + fromNode.parentNode.replaceChild(morphedNode, fromNode); + } + return morphedNode; + }; + } + var morphdom = morphdomFactory(morphAttrs); + var morphdom_esm_default = morphdom; + var DOMPatch = class { + static patchEl(fromEl, toEl, activeElement) { + morphdom_esm_default(fromEl, toEl, { + childrenOnly: false, + onBeforeElUpdated: (fromEl2, toEl2) => { + if (activeElement && activeElement.isSameNode(fromEl2) && dom_default.isFormInput(fromEl2)) { + dom_default.mergeFocusedInput(fromEl2, toEl2); + return false; + } + } + }); + } + constructor(view, container, id, html, streams, targetCID) { + this.view = view; + this.liveSocket = view.liveSocket; + this.container = container; + this.id = id; + this.rootID = view.root.id; + this.html = html; + this.streams = streams; + this.streamInserts = {}; + this.targetCID = targetCID; + this.cidPatch = isCid(this.targetCID); + this.pendingRemoves = []; + this.phxRemove = this.liveSocket.binding("remove"); + this.callbacks = { + beforeadded: [], + beforeupdated: [], + beforephxChildAdded: [], + afteradded: [], + afterupdated: [], + afterdiscarded: [], + afterphxChildAdded: [], + aftertransitionsDiscarded: [] + }; + } + before(kind, callback) { + this.callbacks[`before${kind}`].push(callback); + } + after(kind, callback) { + this.callbacks[`after${kind}`].push(callback); + } + trackBefore(kind, ...args) { + this.callbacks[`before${kind}`].forEach((callback) => callback(...args)); + } + trackAfter(kind, ...args) { + this.callbacks[`after${kind}`].forEach((callback) => callback(...args)); + } + markPrunableContentForRemoval() { + let phxUpdate = this.liveSocket.binding(PHX_UPDATE); + dom_default.all(this.container, `[${phxUpdate}=${PHX_STREAM}]`, (el) => el.innerHTML = ""); + dom_default.all(this.container, `[${phxUpdate}=append] > *, [${phxUpdate}=prepend] > *`, (el) => { + el.setAttribute(PHX_PRUNE, ""); + }); + } + perform() { + let { view, liveSocket: liveSocket2, container, html } = this; + let targetContainer = this.isCIDPatch() ? this.targetCIDContainer(html) : container; + if (this.isCIDPatch() && !targetContainer) { + return; + } + let focused = liveSocket2.getActiveElement(); + let { selectionStart, selectionEnd } = focused && dom_default.hasSelectionRange(focused) ? focused : {}; + let phxUpdate = liveSocket2.binding(PHX_UPDATE); + let phxFeedbackFor = liveSocket2.binding(PHX_FEEDBACK_FOR); + let disableWith = liveSocket2.binding(PHX_DISABLE_WITH); + let phxViewportTop = liveSocket2.binding(PHX_VIEWPORT_TOP); + let phxViewportBottom = liveSocket2.binding(PHX_VIEWPORT_BOTTOM); + let phxTriggerExternal = liveSocket2.binding(PHX_TRIGGER_ACTION); + let added = []; + let trackedInputs = []; + let updates = []; + let appendPrependUpdates = []; + let externalFormTriggered = null; + let diffHTML = liveSocket2.time("premorph container prep", () => { + return this.buildDiffHTML(container, html, phxUpdate, targetContainer); + }); + this.trackBefore("added", container); + this.trackBefore("updated", container, container); + liveSocket2.time("morphdom", () => { + this.streams.forEach(([ref, inserts, deleteIds, reset]) => { + Object.entries(inserts).forEach(([key, [streamAt, limit]]) => { + this.streamInserts[key] = { ref, streamAt, limit }; + }); + if (reset !== void 0) { + dom_default.all(container, `[${PHX_STREAM_REF}="${ref}"]`, (child) => { + if (!inserts[child.id]) { + this.removeStreamChildElement(child); + } + }); + } + deleteIds.forEach((id) => { + let child = container.querySelector(`[id="${id}"]`); + if (child) { + this.removeStreamChildElement(child); + } + }); + }); + morphdom_esm_default(targetContainer, diffHTML, { + childrenOnly: targetContainer.getAttribute(PHX_COMPONENT) === null, + getNodeKey: (node) => { + return dom_default.isPhxDestroyed(node) ? null : node.id; + }, + skipFromChildren: (from) => { + return from.getAttribute(phxUpdate) === PHX_STREAM; + }, + addChild: (parent, child) => { + let { ref, streamAt, limit } = this.getStreamInsert(child); + if (ref === void 0) { + return parent.appendChild(child); + } + dom_default.putSticky(child, PHX_STREAM_REF, (el) => el.setAttribute(PHX_STREAM_REF, ref)); + if (streamAt === 0) { + parent.insertAdjacentElement("afterbegin", child); + } else if (streamAt === -1) { + parent.appendChild(child); + } else if (streamAt > 0) { + let sibling = Array.from(parent.children)[streamAt]; + parent.insertBefore(child, sibling); + } + let children = limit !== null && Array.from(parent.children); + let childrenToRemove = []; + if (limit && limit < 0 && children.length > limit * -1) { + childrenToRemove = children.slice(0, children.length + limit); + } else if (limit && limit >= 0 && children.length > limit) { + childrenToRemove = children.slice(limit); + } + childrenToRemove.forEach((removeChild) => { + if (!this.streamInserts[removeChild.id]) { + this.removeStreamChildElement(removeChild); + } + }); + }, + onBeforeNodeAdded: (el) => { + dom_default.maybeAddPrivateHooks(el, phxViewportTop, phxViewportBottom); + this.trackBefore("added", el); + return el; + }, + onNodeAdded: (el) => { + if (el.getAttribute) { + this.maybeReOrderStream(el); + } + if (el instanceof HTMLImageElement && el.srcset) { + el.srcset = el.srcset; + } else if (el instanceof HTMLVideoElement && el.autoplay) { + el.play(); + } + if (dom_default.isNowTriggerFormExternal(el, phxTriggerExternal)) { + externalFormTriggered = el; + } + if (el.getAttribute && el.getAttribute("name") && dom_default.isFormInput(el)) { + trackedInputs.push(el); + } + if (dom_default.isPhxChild(el) && view.ownsElement(el) || dom_default.isPhxSticky(el) && view.ownsElement(el.parentNode)) { + this.trackAfter("phxChildAdded", el); + } + added.push(el); + }, + onNodeDiscarded: (el) => this.onNodeDiscarded(el), + onBeforeNodeDiscarded: (el) => { + if (el.getAttribute && el.getAttribute(PHX_PRUNE) !== null) { + return true; + } + if (el.parentElement !== null && el.id && dom_default.isPhxUpdate(el.parentElement, phxUpdate, [PHX_STREAM, "append", "prepend"])) { + return false; + } + if (this.maybePendingRemove(el)) { + return false; + } + if (this.skipCIDSibling(el)) { + return false; + } + return true; + }, + onElUpdated: (el) => { + if (dom_default.isNowTriggerFormExternal(el, phxTriggerExternal)) { + externalFormTriggered = el; + } + updates.push(el); + this.maybeReOrderStream(el); + }, + onBeforeElUpdated: (fromEl, toEl) => { + dom_default.maybeAddPrivateHooks(toEl, phxViewportTop, phxViewportBottom); + dom_default.cleanChildNodes(toEl, phxUpdate); + if (this.skipCIDSibling(toEl)) { + return false; + } + if (dom_default.isPhxSticky(fromEl)) { + return false; + } + if (dom_default.isIgnored(fromEl, phxUpdate) || fromEl.form && fromEl.form.isSameNode(externalFormTriggered)) { + this.trackBefore("updated", fromEl, toEl); + dom_default.mergeAttrs(fromEl, toEl, { isIgnored: true }); + updates.push(fromEl); + dom_default.applyStickyOperations(fromEl); + return false; + } + if (fromEl.type === "number" && (fromEl.validity && fromEl.validity.badInput)) { + return false; + } + if (!dom_default.syncPendingRef(fromEl, toEl, disableWith)) { + if (dom_default.isUploadInput(fromEl)) { + this.trackBefore("updated", fromEl, toEl); + updates.push(fromEl); + } + dom_default.applyStickyOperations(fromEl); + return false; + } + if (dom_default.isPhxChild(toEl)) { + let prevSession = fromEl.getAttribute(PHX_SESSION); + dom_default.mergeAttrs(fromEl, toEl, { exclude: [PHX_STATIC] }); + if (prevSession !== "") { + fromEl.setAttribute(PHX_SESSION, prevSession); + } + fromEl.setAttribute(PHX_ROOT_ID, this.rootID); + dom_default.applyStickyOperations(fromEl); + return false; + } + dom_default.copyPrivates(toEl, fromEl); + let isFocusedFormEl = focused && fromEl.isSameNode(focused) && dom_default.isFormInput(fromEl); + if (isFocusedFormEl && fromEl.type !== "hidden") { + this.trackBefore("updated", fromEl, toEl); + dom_default.mergeFocusedInput(fromEl, toEl); + dom_default.syncAttrsToProps(fromEl); + updates.push(fromEl); + dom_default.applyStickyOperations(fromEl); + trackedInputs.push(fromEl); + return false; + } else { + if (dom_default.isPhxUpdate(toEl, phxUpdate, ["append", "prepend"])) { + appendPrependUpdates.push(new DOMPostMorphRestorer(fromEl, toEl, toEl.getAttribute(phxUpdate))); + } + dom_default.syncAttrsToProps(toEl); + dom_default.applyStickyOperations(toEl); + if (toEl.getAttribute("name") && dom_default.isFormInput(toEl)) { + trackedInputs.push(toEl); + } + this.trackBefore("updated", fromEl, toEl); + return true; + } + } + }); + }); + if (liveSocket2.isDebugEnabled()) { + detectDuplicateIds(); + } + if (appendPrependUpdates.length > 0) { + liveSocket2.time("post-morph append/prepend restoration", () => { + appendPrependUpdates.forEach((update) => update.perform()); + }); + } + trackedInputs.forEach((input) => { + dom_default.maybeHideFeedback(targetContainer, input, phxFeedbackFor); + }); + liveSocket2.silenceEvents(() => dom_default.restoreFocus(focused, selectionStart, selectionEnd)); + dom_default.dispatchEvent(document, "phx:update"); + added.forEach((el) => this.trackAfter("added", el)); + updates.forEach((el) => this.trackAfter("updated", el)); + this.transitionPendingRemoves(); + if (externalFormTriggered) { + liveSocket2.unload(); + Object.getPrototypeOf(externalFormTriggered).submit.call(externalFormTriggered); + } + return true; + } + onNodeDiscarded(el) { + if (dom_default.isPhxChild(el) || dom_default.isPhxSticky(el)) { + this.liveSocket.destroyViewByEl(el); + } + this.trackAfter("discarded", el); + } + maybePendingRemove(node) { + if (node.getAttribute && node.getAttribute(this.phxRemove) !== null) { + this.pendingRemoves.push(node); + return true; + } else { + return false; + } + } + removeStreamChildElement(child) { + if (!this.maybePendingRemove(child)) { + child.remove(); + this.onNodeDiscarded(child); + } + } + getStreamInsert(el) { + let insert = el.id ? this.streamInserts[el.id] : {}; + return insert || {}; + } + maybeReOrderStream(el) { + let { ref, streamAt, limit } = this.getStreamInsert(el); + if (streamAt === void 0) { + return; + } + dom_default.putSticky(el, PHX_STREAM_REF, (el2) => el2.setAttribute(PHX_STREAM_REF, ref)); + if (streamAt === 0) { + el.parentElement.insertBefore(el, el.parentElement.firstElementChild); + } else if (streamAt > 0) { + let children = Array.from(el.parentElement.children); + let oldIndex = children.indexOf(el); + if (streamAt >= children.length - 1) { + el.parentElement.appendChild(el); + } else { + let sibling = children[streamAt]; + if (oldIndex > streamAt) { + el.parentElement.insertBefore(el, sibling); + } else { + el.parentElement.insertBefore(el, sibling.nextElementSibling); + } + } + } + } + transitionPendingRemoves() { + let { pendingRemoves, liveSocket: liveSocket2 } = this; + if (pendingRemoves.length > 0) { + liveSocket2.transitionRemoves(pendingRemoves); + liveSocket2.requestDOMUpdate(() => { + pendingRemoves.forEach((el) => { + let child = dom_default.firstPhxChild(el); + if (child) { + liveSocket2.destroyViewByEl(child); + } + el.remove(); + }); + this.trackAfter("transitionsDiscarded", pendingRemoves); + }); + } + } + isCIDPatch() { + return this.cidPatch; + } + skipCIDSibling(el) { + return el.nodeType === Node.ELEMENT_NODE && el.getAttribute(PHX_SKIP) !== null; + } + targetCIDContainer(html) { + if (!this.isCIDPatch()) { + return; + } + let [first, ...rest] = dom_default.findComponentNodeList(this.container, this.targetCID); + if (rest.length === 0 && dom_default.childNodeLength(html) === 1) { + return first; + } else { + return first && first.parentNode; + } + } + buildDiffHTML(container, html, phxUpdate, targetContainer) { + let isCIDPatch = this.isCIDPatch(); + let isCIDWithSingleRoot = isCIDPatch && targetContainer.getAttribute(PHX_COMPONENT) === this.targetCID.toString(); + if (!isCIDPatch || isCIDWithSingleRoot) { + return html; + } else { + let diffContainer = null; + let template = document.createElement("template"); + diffContainer = dom_default.cloneNode(targetContainer); + let [firstComponent, ...rest] = dom_default.findComponentNodeList(diffContainer, this.targetCID); + template.innerHTML = html; + rest.forEach((el) => el.remove()); + Array.from(diffContainer.childNodes).forEach((child) => { + if (child.id && child.nodeType === Node.ELEMENT_NODE && child.getAttribute(PHX_COMPONENT) !== this.targetCID.toString()) { + child.setAttribute(PHX_SKIP, ""); + child.innerHTML = ""; + } + }); + Array.from(template.content.childNodes).forEach((el) => diffContainer.insertBefore(el, firstComponent)); + firstComponent.remove(); + return diffContainer.outerHTML; + } + } + indexOf(parent, child) { + return Array.from(parent.children).indexOf(child); + } + }; + var Rendered = class { + static extract(diff) { + let { [REPLY]: reply, [EVENTS]: events, [TITLE]: title } = diff; + delete diff[REPLY]; + delete diff[EVENTS]; + delete diff[TITLE]; + return { diff, title, reply: reply || null, events: events || [] }; + } + constructor(viewId, rendered) { + this.viewId = viewId; + this.rendered = {}; + this.mergeDiff(rendered); + } + parentViewId() { + return this.viewId; + } + toString(onlyCids) { + let [str, streams] = this.recursiveToString(this.rendered, this.rendered[COMPONENTS], onlyCids); + return [str, streams]; + } + recursiveToString(rendered, components = rendered[COMPONENTS], onlyCids) { + onlyCids = onlyCids ? new Set(onlyCids) : null; + let output = { buffer: "", components, onlyCids, streams: /* @__PURE__ */ new Set() }; + this.toOutputBuffer(rendered, null, output); + return [output.buffer, output.streams]; + } + componentCIDs(diff) { + return Object.keys(diff[COMPONENTS] || {}).map((i) => parseInt(i)); + } + isComponentOnlyDiff(diff) { + if (!diff[COMPONENTS]) { + return false; + } + return Object.keys(diff).length === 1; + } + getComponent(diff, cid) { + return diff[COMPONENTS][cid]; + } + mergeDiff(diff) { + let newc = diff[COMPONENTS]; + let cache = {}; + delete diff[COMPONENTS]; + this.rendered = this.mutableMerge(this.rendered, diff); + this.rendered[COMPONENTS] = this.rendered[COMPONENTS] || {}; + if (newc) { + let oldc = this.rendered[COMPONENTS]; + for (let cid in newc) { + newc[cid] = this.cachedFindComponent(cid, newc[cid], oldc, newc, cache); + } + for (let cid in newc) { + oldc[cid] = newc[cid]; + } + diff[COMPONENTS] = newc; + } + } + cachedFindComponent(cid, cdiff, oldc, newc, cache) { + if (cache[cid]) { + return cache[cid]; + } else { + let ndiff, stat, scid = cdiff[STATIC]; + if (isCid(scid)) { + let tdiff; + if (scid > 0) { + tdiff = this.cachedFindComponent(scid, newc[scid], oldc, newc, cache); + } else { + tdiff = oldc[-scid]; + } + stat = tdiff[STATIC]; + ndiff = this.cloneMerge(tdiff, cdiff); + ndiff[STATIC] = stat; + } else { + ndiff = cdiff[STATIC] !== void 0 ? cdiff : this.cloneMerge(oldc[cid] || {}, cdiff); + } + cache[cid] = ndiff; + return ndiff; + } + } + mutableMerge(target, source) { + if (source[STATIC] !== void 0) { + return source; + } else { + this.doMutableMerge(target, source); + return target; + } + } + doMutableMerge(target, source) { + for (let key in source) { + let val = source[key]; + let targetVal = target[key]; + let isObjVal = isObject(val); + if (isObjVal && val[STATIC] === void 0 && isObject(targetVal)) { + this.doMutableMerge(targetVal, val); + } else { + target[key] = val; + } + } + } + cloneMerge(target, source) { + let merged = __spreadValues(__spreadValues({}, target), source); + for (let key in merged) { + let val = source[key]; + let targetVal = target[key]; + if (isObject(val) && val[STATIC] === void 0 && isObject(targetVal)) { + merged[key] = this.cloneMerge(targetVal, val); + } + } + return merged; + } + componentToString(cid) { + let [str, streams] = this.recursiveCIDToString(this.rendered[COMPONENTS], cid, null, false); + return [str, streams]; + } + pruneCIDs(cids) { + cids.forEach((cid) => delete this.rendered[COMPONENTS][cid]); + } + get() { + return this.rendered; + } + isNewFingerprint(diff = {}) { + return !!diff[STATIC]; + } + templateStatic(part, templates) { + if (typeof part === "number") { + return templates[part]; + } else { + return part; + } + } + toOutputBuffer(rendered, templates, output) { + if (rendered[DYNAMICS]) { + return this.comprehensionToBuffer(rendered, templates, output); + } + let { [STATIC]: statics } = rendered; + statics = this.templateStatic(statics, templates); + output.buffer += statics[0]; + for (let i = 1; i < statics.length; i++) { + this.dynamicToBuffer(rendered[i - 1], templates, output); + output.buffer += statics[i]; + } + } + comprehensionToBuffer(rendered, templates, output) { + let { [DYNAMICS]: dynamics, [STATIC]: statics, [STREAM]: stream } = rendered; + let [_ref, _inserts, deleteIds, reset] = stream || [null, {}, [], null]; + statics = this.templateStatic(statics, templates); + let compTemplates = templates || rendered[TEMPLATES]; + for (let d = 0; d < dynamics.length; d++) { + let dynamic = dynamics[d]; + output.buffer += statics[0]; + for (let i = 1; i < statics.length; i++) { + this.dynamicToBuffer(dynamic[i - 1], compTemplates, output); + output.buffer += statics[i]; + } + } + if (stream !== void 0 && (rendered[DYNAMICS].length > 0 || deleteIds.length > 0 || reset)) { + delete rendered[STREAM]; + rendered[DYNAMICS] = []; + output.streams.add(stream); + } + } + dynamicToBuffer(rendered, templates, output) { + if (typeof rendered === "number") { + let [str, streams] = this.recursiveCIDToString(output.components, rendered, output.onlyCids); + output.buffer += str; + output.streams = /* @__PURE__ */ new Set([...output.streams, ...streams]); + } else if (isObject(rendered)) { + this.toOutputBuffer(rendered, templates, output); + } else { + output.buffer += rendered; + } + } + recursiveCIDToString(components, cid, onlyCids, allowRootComments = true) { + let component = components[cid] || logError(`no component for CID ${cid}`, components); + let template = document.createElement("template"); + let [html, streams] = this.recursiveToString(component, components, onlyCids); + template.innerHTML = html; + let container = template.content; + let skip = onlyCids && !onlyCids.has(cid); + let [hasChildNodes, hasChildComponents] = Array.from(container.childNodes).reduce(([hasNodes, hasComponents], child, i) => { + if (child.nodeType === Node.ELEMENT_NODE) { + if (child.getAttribute(PHX_COMPONENT)) { + return [hasNodes, true]; + } + child.setAttribute(PHX_COMPONENT, cid); + if (!child.id) { + child.id = `${this.parentViewId()}-${cid}-${i}`; + } + if (skip) { + child.setAttribute(PHX_SKIP, ""); + child.innerHTML = ""; + } + return [true, hasComponents]; + } else if (child.nodeType === Node.COMMENT_NODE) { + if (!allowRootComments) { + child.remove(); + } + return [hasNodes, hasComponents]; + } else { + if (child.nodeValue.trim() !== "") { + logError(`only HTML element tags are allowed at the root of components. + +got: "${child.nodeValue.trim()}" + +within: +`, template.innerHTML.trim()); + child.replaceWith(this.createSpan(child.nodeValue, cid)); + return [true, hasComponents]; + } else { + child.remove(); + return [hasNodes, hasComponents]; + } + } + }, [false, false]); + if (!hasChildNodes && !hasChildComponents) { + logError("expected at least one HTML element tag inside a component, but the component is empty:\n", template.innerHTML.trim()); + return [this.createSpan("", cid).outerHTML, streams]; + } else if (!hasChildNodes && hasChildComponents) { + logError("expected at least one HTML element tag directly inside a component, but only subcomponents were found. A component must render at least one HTML tag directly inside itself.", template.innerHTML.trim()); + return [template.innerHTML, streams]; + } else { + return [template.innerHTML, streams]; + } + } + createSpan(text, cid) { + let span = document.createElement("span"); + span.innerText = text; + span.setAttribute(PHX_COMPONENT, cid); + return span; + } + }; + var viewHookID = 1; + var ViewHook = class { + static makeID() { + return viewHookID++; + } + static elementID(el) { + return el.phxHookId; + } + constructor(view, el, callbacks) { + this.__view = view; + this.liveSocket = view.liveSocket; + this.__callbacks = callbacks; + this.__listeners = /* @__PURE__ */ new Set(); + this.__isDisconnected = false; + this.el = el; + this.el.phxHookId = this.constructor.makeID(); + for (let key in this.__callbacks) { + this[key] = this.__callbacks[key]; + } + } + __mounted() { + this.mounted && this.mounted(); + } + __updated() { + this.updated && this.updated(); + } + __beforeUpdate() { + this.beforeUpdate && this.beforeUpdate(); + } + __destroyed() { + this.destroyed && this.destroyed(); + } + __reconnected() { + if (this.__isDisconnected) { + this.__isDisconnected = false; + this.reconnected && this.reconnected(); + } + } + __disconnected() { + this.__isDisconnected = true; + this.disconnected && this.disconnected(); + } + pushEvent(event, payload = {}, onReply = function() { + }) { + return this.__view.pushHookEvent(this.el, null, event, payload, onReply); + } + pushEventTo(phxTarget, event, payload = {}, onReply = function() { + }) { + return this.__view.withinTargets(phxTarget, (view, targetCtx) => { + return view.pushHookEvent(this.el, targetCtx, event, payload, onReply); + }); + } + handleEvent(event, callback) { + let callbackRef = (customEvent, bypass) => bypass ? event : callback(customEvent.detail); + window.addEventListener(`phx:${event}`, callbackRef); + this.__listeners.add(callbackRef); + return callbackRef; + } + removeHandleEvent(callbackRef) { + let event = callbackRef(null, true); + window.removeEventListener(`phx:${event}`, callbackRef); + this.__listeners.delete(callbackRef); + } + upload(name, files) { + return this.__view.dispatchUploads(name, files); + } + uploadTo(phxTarget, name, files) { + return this.__view.withinTargets(phxTarget, (view) => view.dispatchUploads(name, files)); + } + __cleanup__() { + this.__listeners.forEach((callbackRef) => this.removeHandleEvent(callbackRef)); + } + }; + var focusStack = null; + var JS = { + exec(eventType, phxEvent, view, sourceEl, defaults) { + let [defaultKind, defaultArgs] = defaults || [null, { callback: defaults && defaults.callback }]; + let commands = phxEvent.charAt(0) === "[" ? JSON.parse(phxEvent) : [[defaultKind, defaultArgs]]; + commands.forEach(([kind, args]) => { + if (kind === defaultKind && defaultArgs.data) { + args.data = Object.assign(args.data || {}, defaultArgs.data); + args.callback = args.callback || defaultArgs.callback; + } + this.filterToEls(sourceEl, args).forEach((el) => { + this[`exec_${kind}`](eventType, phxEvent, view, sourceEl, el, args); + }); + }); + }, + isVisible(el) { + return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length > 0); + }, + exec_exec(eventType, phxEvent, view, sourceEl, el, [attr, to]) { + let nodes = to ? dom_default.all(document, to) : [sourceEl]; + nodes.forEach((node) => { + let encodedJS = node.getAttribute(attr); + if (!encodedJS) { + throw new Error(`expected ${attr} to contain JS command on "${to}"`); + } + view.liveSocket.execJS(node, encodedJS, eventType); + }); + }, + exec_dispatch(eventType, phxEvent, view, sourceEl, el, { to, event, detail, bubbles }) { + detail = detail || {}; + detail.dispatcher = sourceEl; + dom_default.dispatchEvent(el, event, { detail, bubbles }); + }, + exec_push(eventType, phxEvent, view, sourceEl, el, args) { + if (!view.isConnected()) { + return; + } + let { event, data, target, page_loading, loading, value, dispatcher, callback } = args; + let pushOpts = { loading, value, target, page_loading: !!page_loading }; + let targetSrc = eventType === "change" && dispatcher ? dispatcher : sourceEl; + let phxTarget = target || targetSrc.getAttribute(view.binding("target")) || targetSrc; + view.withinTargets(phxTarget, (targetView, targetCtx) => { + if (eventType === "change") { + let { newCid, _target } = args; + _target = _target || (dom_default.isFormInput(sourceEl) ? sourceEl.name : void 0); + if (_target) { + pushOpts._target = _target; + } + targetView.pushInput(sourceEl, targetCtx, newCid, event || phxEvent, pushOpts, callback); + } else if (eventType === "submit") { + let { submitter } = args; + targetView.submitForm(sourceEl, targetCtx, event || phxEvent, submitter, pushOpts, callback); + } else { + targetView.pushEvent(eventType, sourceEl, targetCtx, event || phxEvent, data, pushOpts, callback); + } + }); + }, + exec_navigate(eventType, phxEvent, view, sourceEl, el, { href, replace }) { + view.liveSocket.historyRedirect(href, replace ? "replace" : "push"); + }, + exec_patch(eventType, phxEvent, view, sourceEl, el, { href, replace }) { + view.liveSocket.pushHistoryPatch(href, replace ? "replace" : "push", sourceEl); + }, + exec_focus(eventType, phxEvent, view, sourceEl, el) { + window.requestAnimationFrame(() => aria_default.attemptFocus(el)); + }, + exec_focus_first(eventType, phxEvent, view, sourceEl, el) { + window.requestAnimationFrame(() => aria_default.focusFirstInteractive(el) || aria_default.focusFirst(el)); + }, + exec_push_focus(eventType, phxEvent, view, sourceEl, el) { + window.requestAnimationFrame(() => focusStack = el || sourceEl); + }, + exec_pop_focus(eventType, phxEvent, view, sourceEl, el) { + window.requestAnimationFrame(() => { + if (focusStack) { + focusStack.focus(); + } + focusStack = null; + }); + }, + exec_add_class(eventType, phxEvent, view, sourceEl, el, { names, transition, time }) { + this.addOrRemoveClasses(el, names, [], transition, time, view); + }, + exec_remove_class(eventType, phxEvent, view, sourceEl, el, { names, transition, time }) { + this.addOrRemoveClasses(el, [], names, transition, time, view); + }, + exec_transition(eventType, phxEvent, view, sourceEl, el, { time, transition }) { + this.addOrRemoveClasses(el, [], [], transition, time, view); + }, + exec_toggle(eventType, phxEvent, view, sourceEl, el, { display, ins, outs, time }) { + this.toggle(eventType, view, el, display, ins, outs, time); + }, + exec_show(eventType, phxEvent, view, sourceEl, el, { display, transition, time }) { + this.show(eventType, view, el, display, transition, time); + }, + exec_hide(eventType, phxEvent, view, sourceEl, el, { display, transition, time }) { + this.hide(eventType, view, el, display, transition, time); + }, + exec_set_attr(eventType, phxEvent, view, sourceEl, el, { attr: [attr, val] }) { + this.setOrRemoveAttrs(el, [[attr, val]], []); + }, + exec_remove_attr(eventType, phxEvent, view, sourceEl, el, { attr }) { + this.setOrRemoveAttrs(el, [], [attr]); + }, + show(eventType, view, el, display, transition, time) { + if (!this.isVisible(el)) { + this.toggle(eventType, view, el, display, transition, null, time); + } + }, + hide(eventType, view, el, display, transition, time) { + if (this.isVisible(el)) { + this.toggle(eventType, view, el, display, null, transition, time); + } + }, + toggle(eventType, view, el, display, ins, outs, time) { + let [inClasses, inStartClasses, inEndClasses] = ins || [[], [], []]; + let [outClasses, outStartClasses, outEndClasses] = outs || [[], [], []]; + if (inClasses.length > 0 || outClasses.length > 0) { + if (this.isVisible(el)) { + let onStart = () => { + this.addOrRemoveClasses(el, outStartClasses, inClasses.concat(inStartClasses).concat(inEndClasses)); + window.requestAnimationFrame(() => { + this.addOrRemoveClasses(el, outClasses, []); + window.requestAnimationFrame(() => this.addOrRemoveClasses(el, outEndClasses, outStartClasses)); + }); + }; + el.dispatchEvent(new Event("phx:hide-start")); + view.transition(time, onStart, () => { + this.addOrRemoveClasses(el, [], outClasses.concat(outEndClasses)); + dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = "none"); + el.dispatchEvent(new Event("phx:hide-end")); + }); + } else { + if (eventType === "remove") { + return; + } + let onStart = () => { + this.addOrRemoveClasses(el, inStartClasses, outClasses.concat(outStartClasses).concat(outEndClasses)); + let stickyDisplay = display || this.defaultDisplay(el); + dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = stickyDisplay); + window.requestAnimationFrame(() => { + this.addOrRemoveClasses(el, inClasses, []); + window.requestAnimationFrame(() => this.addOrRemoveClasses(el, inEndClasses, inStartClasses)); + }); + }; + el.dispatchEvent(new Event("phx:show-start")); + view.transition(time, onStart, () => { + this.addOrRemoveClasses(el, [], inClasses.concat(inEndClasses)); + el.dispatchEvent(new Event("phx:show-end")); + }); + } + } else { + if (this.isVisible(el)) { + window.requestAnimationFrame(() => { + el.dispatchEvent(new Event("phx:hide-start")); + dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = "none"); + el.dispatchEvent(new Event("phx:hide-end")); + }); + } else { + window.requestAnimationFrame(() => { + el.dispatchEvent(new Event("phx:show-start")); + let stickyDisplay = display || this.defaultDisplay(el); + dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = stickyDisplay); + el.dispatchEvent(new Event("phx:show-end")); + }); + } + } + }, + addOrRemoveClasses(el, adds, removes, transition, time, view) { + let [transitionRun, transitionStart, transitionEnd] = transition || [[], [], []]; + if (transitionRun.length > 0) { + let onStart = () => { + this.addOrRemoveClasses(el, transitionStart, [].concat(transitionRun).concat(transitionEnd)); + window.requestAnimationFrame(() => { + this.addOrRemoveClasses(el, transitionRun, []); + window.requestAnimationFrame(() => this.addOrRemoveClasses(el, transitionEnd, transitionStart)); + }); + }; + let onDone = () => this.addOrRemoveClasses(el, adds.concat(transitionEnd), removes.concat(transitionRun).concat(transitionStart)); + return view.transition(time, onStart, onDone); + } + window.requestAnimationFrame(() => { + let [prevAdds, prevRemoves] = dom_default.getSticky(el, "classes", [[], []]); + let keepAdds = adds.filter((name) => prevAdds.indexOf(name) < 0 && !el.classList.contains(name)); + let keepRemoves = removes.filter((name) => prevRemoves.indexOf(name) < 0 && el.classList.contains(name)); + let newAdds = prevAdds.filter((name) => removes.indexOf(name) < 0).concat(keepAdds); + let newRemoves = prevRemoves.filter((name) => adds.indexOf(name) < 0).concat(keepRemoves); + dom_default.putSticky(el, "classes", (currentEl) => { + currentEl.classList.remove(...newRemoves); + currentEl.classList.add(...newAdds); + return [newAdds, newRemoves]; + }); + }); + }, + setOrRemoveAttrs(el, sets, removes) { + let [prevSets, prevRemoves] = dom_default.getSticky(el, "attrs", [[], []]); + let alteredAttrs = sets.map(([attr, _val]) => attr).concat(removes); + let newSets = prevSets.filter(([attr, _val]) => !alteredAttrs.includes(attr)).concat(sets); + let newRemoves = prevRemoves.filter((attr) => !alteredAttrs.includes(attr)).concat(removes); + dom_default.putSticky(el, "attrs", (currentEl) => { + newRemoves.forEach((attr) => currentEl.removeAttribute(attr)); + newSets.forEach(([attr, val]) => currentEl.setAttribute(attr, val)); + return [newSets, newRemoves]; + }); + }, + hasAllClasses(el, classes) { + return classes.every((name) => el.classList.contains(name)); + }, + isToggledOut(el, outClasses) { + return !this.isVisible(el) || this.hasAllClasses(el, outClasses); + }, + filterToEls(sourceEl, { to }) { + return to ? dom_default.all(document, to) : [sourceEl]; + }, + defaultDisplay(el) { + return { tr: "table-row", td: "table-cell" }[el.tagName.toLowerCase()] || "block"; + } + }; + var js_default = JS; + var serializeForm = (form, metadata, onlyNames = []) => { + let _a = metadata, { submitter } = _a, meta = __objRest(_a, ["submitter"]); + let formData = new FormData(form); + if (submitter && submitter.hasAttribute("name") && submitter.form && submitter.form === form) { + formData.append(submitter.name, submitter.value); + } + let toRemove = []; + formData.forEach((val, key, _index) => { + if (val instanceof File) { + toRemove.push(key); + } + }); + toRemove.forEach((key) => formData.delete(key)); + let params = new URLSearchParams(); + for (let [key, val] of formData.entries()) { + if (onlyNames.length === 0 || onlyNames.indexOf(key) >= 0) { + params.append(key, val); + } + } + for (let metaKey in meta) { + params.append(metaKey, meta[metaKey]); + } + return params.toString(); + }; + var View = class { + constructor(el, liveSocket2, parentView, flash, liveReferer) { + this.isDead = false; + this.liveSocket = liveSocket2; + this.flash = flash; + this.parent = parentView; + this.root = parentView ? parentView.root : this; + this.el = el; + this.id = this.el.id; + this.ref = 0; + this.childJoins = 0; + this.loaderTimer = null; + this.pendingDiffs = []; + this.pruningCIDs = []; + this.redirect = false; + this.href = null; + this.joinCount = this.parent ? this.parent.joinCount - 1 : 0; + this.joinPending = true; + this.destroyed = false; + this.joinCallback = function(onDone) { + onDone && onDone(); + }; + this.stopCallback = function() { + }; + this.pendingJoinOps = this.parent ? null : []; + this.viewHooks = {}; + this.uploaders = {}; + this.formSubmits = []; + this.children = this.parent ? null : {}; + this.root.children[this.id] = {}; + this.channel = this.liveSocket.channel(`lv:${this.id}`, () => { + return { + redirect: this.redirect ? this.href : void 0, + url: this.redirect ? void 0 : this.href || void 0, + params: this.connectParams(liveReferer), + session: this.getSession(), + static: this.getStatic(), + flash: this.flash + }; + }); + } + setHref(href) { + this.href = href; + } + setRedirect(href) { + this.redirect = true; + this.href = href; + } + isMain() { + return this.el.hasAttribute(PHX_MAIN); + } + connectParams(liveReferer) { + let params = this.liveSocket.params(this.el); + let manifest = dom_default.all(document, `[${this.binding(PHX_TRACK_STATIC)}]`).map((node) => node.src || node.href).filter((url) => typeof url === "string"); + if (manifest.length > 0) { + params["_track_static"] = manifest; + } + params["_mounts"] = this.joinCount; + params["_live_referer"] = liveReferer; + return params; + } + isConnected() { + return this.channel.canPush(); + } + getSession() { + return this.el.getAttribute(PHX_SESSION); + } + getStatic() { + let val = this.el.getAttribute(PHX_STATIC); + return val === "" ? null : val; + } + destroy(callback = function() { + }) { + this.destroyAllChildren(); + this.destroyed = true; + delete this.root.children[this.id]; + if (this.parent) { + delete this.root.children[this.parent.id][this.id]; + } + clearTimeout(this.loaderTimer); + let onFinished = () => { + callback(); + for (let id in this.viewHooks) { + this.destroyHook(this.viewHooks[id]); + } + }; + dom_default.markPhxChildDestroyed(this.el); + this.log("destroyed", () => ["the child has been removed from the parent"]); + this.channel.leave().receive("ok", onFinished).receive("error", onFinished).receive("timeout", onFinished); + } + setContainerClasses(...classes) { + this.el.classList.remove(PHX_CONNECTED_CLASS, PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_CLIENT_ERROR_CLASS, PHX_SERVER_ERROR_CLASS); + this.el.classList.add(...classes); + } + showLoader(timeout) { + clearTimeout(this.loaderTimer); + if (timeout) { + this.loaderTimer = setTimeout(() => this.showLoader(), timeout); + } else { + for (let id in this.viewHooks) { + this.viewHooks[id].__disconnected(); + } + this.setContainerClasses(PHX_LOADING_CLASS); + } + } + execAll(binding) { + dom_default.all(this.el, `[${binding}]`, (el) => this.liveSocket.execJS(el, el.getAttribute(binding))); + } + hideLoader() { + clearTimeout(this.loaderTimer); + this.setContainerClasses(PHX_CONNECTED_CLASS); + this.execAll(this.binding("connected")); + } + triggerReconnected() { + for (let id in this.viewHooks) { + this.viewHooks[id].__reconnected(); + } + } + log(kind, msgCallback) { + this.liveSocket.log(this, kind, msgCallback); + } + transition(time, onStart, onDone = function() { + }) { + this.liveSocket.transition(time, onStart, onDone); + } + withinTargets(phxTarget, callback) { + if (phxTarget instanceof HTMLElement || phxTarget instanceof SVGElement) { + return this.liveSocket.owner(phxTarget, (view) => callback(view, phxTarget)); + } + if (isCid(phxTarget)) { + let targets = dom_default.findComponentNodeList(this.el, phxTarget); + if (targets.length === 0) { + logError(`no component found matching phx-target of ${phxTarget}`); + } else { + callback(this, parseInt(phxTarget)); + } + } else { + let targets = Array.from(document.querySelectorAll(phxTarget)); + if (targets.length === 0) { + logError(`nothing found matching the phx-target selector "${phxTarget}"`); + } + targets.forEach((target) => this.liveSocket.owner(target, (view) => callback(view, target))); + } + } + applyDiff(type, rawDiff, callback) { + this.log(type, () => ["", clone(rawDiff)]); + let { diff, reply, events, title } = Rendered.extract(rawDiff); + callback({ diff, reply, events }); + if (title) { + window.requestAnimationFrame(() => dom_default.putTitle(title)); + } + } + onJoin(resp) { + let { rendered, container } = resp; + if (container) { + let [tag, attrs] = container; + this.el = dom_default.replaceRootContainer(this.el, tag, attrs); + } + this.childJoins = 0; + this.joinPending = true; + this.flash = null; + browser_default.dropLocal(this.liveSocket.localStorage, window.location.pathname, CONSECUTIVE_RELOADS); + this.applyDiff("mount", rendered, ({ diff, events }) => { + this.rendered = new Rendered(this.id, diff); + let [html, streams] = this.renderContainer(null, "join"); + this.dropPendingRefs(); + let forms = this.formsForRecovery(html); + this.joinCount++; + if (forms.length > 0) { + forms.forEach(([form, newForm, newCid], i) => { + this.pushFormRecovery(form, newCid, (resp2) => { + if (i === forms.length - 1) { + this.onJoinComplete(resp2, html, streams, events); + } + }); + }); + } else { + this.onJoinComplete(resp, html, streams, events); + } + }); + } + dropPendingRefs() { + dom_default.all(document, `[${PHX_REF_SRC}="${this.id}"][${PHX_REF}]`, (el) => { + el.removeAttribute(PHX_REF); + el.removeAttribute(PHX_REF_SRC); + }); + } + onJoinComplete({ live_patch }, html, streams, events) { + if (this.joinCount > 1 || this.parent && !this.parent.isJoinPending()) { + return this.applyJoinPatch(live_patch, html, streams, events); + } + let newChildren = dom_default.findPhxChildrenInFragment(html, this.id).filter((toEl) => { + let fromEl = toEl.id && this.el.querySelector(`[id="${toEl.id}"]`); + let phxStatic = fromEl && fromEl.getAttribute(PHX_STATIC); + if (phxStatic) { + toEl.setAttribute(PHX_STATIC, phxStatic); + } + return this.joinChild(toEl); + }); + if (newChildren.length === 0) { + if (this.parent) { + this.root.pendingJoinOps.push([this, () => this.applyJoinPatch(live_patch, html, streams, events)]); + this.parent.ackJoin(this); + } else { + this.onAllChildJoinsComplete(); + this.applyJoinPatch(live_patch, html, streams, events); + } + } else { + this.root.pendingJoinOps.push([this, () => this.applyJoinPatch(live_patch, html, streams, events)]); + } + } + attachTrueDocEl() { + this.el = dom_default.byId(this.id); + this.el.setAttribute(PHX_ROOT_ID, this.root.id); + } + execNewMounted() { + let phxViewportTop = this.binding(PHX_VIEWPORT_TOP); + let phxViewportBottom = this.binding(PHX_VIEWPORT_BOTTOM); + dom_default.all(this.el, `[${phxViewportTop}], [${phxViewportBottom}]`, (hookEl) => { + dom_default.maybeAddPrivateHooks(hookEl, phxViewportTop, phxViewportBottom); + this.maybeAddNewHook(hookEl); + }); + dom_default.all(this.el, `[${this.binding(PHX_HOOK)}], [data-phx-${PHX_HOOK}]`, (hookEl) => { + this.maybeAddNewHook(hookEl); + }); + dom_default.all(this.el, `[${this.binding(PHX_MOUNTED)}]`, (el) => this.maybeMounted(el)); + } + applyJoinPatch(live_patch, html, streams, events) { + this.attachTrueDocEl(); + let patch = new DOMPatch(this, this.el, this.id, html, streams, null); + patch.markPrunableContentForRemoval(); + this.performPatch(patch, false); + this.joinNewChildren(); + this.execNewMounted(); + this.joinPending = false; + this.liveSocket.dispatchEvents(events); + this.applyPendingUpdates(); + if (live_patch) { + let { kind, to } = live_patch; + this.liveSocket.historyPatch(to, kind); + } + this.hideLoader(); + if (this.joinCount > 1) { + this.triggerReconnected(); + } + this.stopCallback(); + } + triggerBeforeUpdateHook(fromEl, toEl) { + this.liveSocket.triggerDOM("onBeforeElUpdated", [fromEl, toEl]); + let hook = this.getHook(fromEl); + let isIgnored = hook && dom_default.isIgnored(fromEl, this.binding(PHX_UPDATE)); + if (hook && !fromEl.isEqualNode(toEl) && !(isIgnored && isEqualObj(fromEl.dataset, toEl.dataset))) { + hook.__beforeUpdate(); + return hook; + } + } + maybeMounted(el) { + let phxMounted = el.getAttribute(this.binding(PHX_MOUNTED)); + let hasBeenInvoked = phxMounted && dom_default.private(el, "mounted"); + if (phxMounted && !hasBeenInvoked) { + this.liveSocket.execJS(el, phxMounted); + dom_default.putPrivate(el, "mounted", true); + } + } + maybeAddNewHook(el, force) { + let newHook = this.addHook(el); + if (newHook) { + newHook.__mounted(); + } + } + performPatch(patch, pruneCids) { + let removedEls = []; + let phxChildrenAdded = false; + let updatedHookIds = /* @__PURE__ */ new Set(); + patch.after("added", (el) => { + this.liveSocket.triggerDOM("onNodeAdded", [el]); + this.maybeAddNewHook(el); + if (el.getAttribute) { + this.maybeMounted(el); + } + }); + patch.after("phxChildAdded", (el) => { + if (dom_default.isPhxSticky(el)) { + this.liveSocket.joinRootViews(); + } else { + phxChildrenAdded = true; + } + }); + patch.before("updated", (fromEl, toEl) => { + let hook = this.triggerBeforeUpdateHook(fromEl, toEl); + if (hook) { + updatedHookIds.add(fromEl.id); + } + }); + patch.after("updated", (el) => { + if (updatedHookIds.has(el.id)) { + this.getHook(el).__updated(); + } + }); + patch.after("discarded", (el) => { + if (el.nodeType === Node.ELEMENT_NODE) { + removedEls.push(el); + } + }); + patch.after("transitionsDiscarded", (els) => this.afterElementsRemoved(els, pruneCids)); + patch.perform(); + this.afterElementsRemoved(removedEls, pruneCids); + return phxChildrenAdded; + } + afterElementsRemoved(elements, pruneCids) { + let destroyedCIDs = []; + elements.forEach((parent) => { + let components = dom_default.all(parent, `[${PHX_COMPONENT}]`); + let hooks = dom_default.all(parent, `[${this.binding(PHX_HOOK)}]`); + components.concat(parent).forEach((el) => { + let cid = this.componentID(el); + if (isCid(cid) && destroyedCIDs.indexOf(cid) === -1) { + destroyedCIDs.push(cid); + } + }); + hooks.concat(parent).forEach((hookEl) => { + let hook = this.getHook(hookEl); + hook && this.destroyHook(hook); + }); + }); + if (pruneCids) { + this.maybePushComponentsDestroyed(destroyedCIDs); + } + } + joinNewChildren() { + dom_default.findPhxChildren(this.el, this.id).forEach((el) => this.joinChild(el)); + } + getChildById(id) { + return this.root.children[this.id][id]; + } + getDescendentByEl(el) { + if (el.id === this.id) { + return this; + } else { + return this.children[el.getAttribute(PHX_PARENT_ID)][el.id]; + } + } + destroyDescendent(id) { + for (let parentId in this.root.children) { + for (let childId in this.root.children[parentId]) { + if (childId === id) { + return this.root.children[parentId][childId].destroy(); + } + } + } + } + joinChild(el) { + let child = this.getChildById(el.id); + if (!child) { + let view = new View(el, this.liveSocket, this); + this.root.children[this.id][view.id] = view; + view.join(); + this.childJoins++; + return true; + } + } + isJoinPending() { + return this.joinPending; + } + ackJoin(_child) { + this.childJoins--; + if (this.childJoins === 0) { + if (this.parent) { + this.parent.ackJoin(this); + } else { + this.onAllChildJoinsComplete(); + } + } + } + onAllChildJoinsComplete() { + this.joinCallback(() => { + this.pendingJoinOps.forEach(([view, op]) => { + if (!view.isDestroyed()) { + op(); + } + }); + this.pendingJoinOps = []; + }); + } + update(diff, events) { + if (this.isJoinPending() || this.liveSocket.hasPendingLink() && this.root.isMain()) { + return this.pendingDiffs.push({ diff, events }); + } + this.rendered.mergeDiff(diff); + let phxChildrenAdded = false; + if (this.rendered.isComponentOnlyDiff(diff)) { + this.liveSocket.time("component patch complete", () => { + let parentCids = dom_default.findParentCIDs(this.el, this.rendered.componentCIDs(diff)); + parentCids.forEach((parentCID) => { + if (this.componentPatch(this.rendered.getComponent(diff, parentCID), parentCID)) { + phxChildrenAdded = true; + } + }); + }); + } else if (!isEmpty(diff)) { + this.liveSocket.time("full patch complete", () => { + let [html, streams] = this.renderContainer(diff, "update"); + let patch = new DOMPatch(this, this.el, this.id, html, streams, null); + phxChildrenAdded = this.performPatch(patch, true); + }); + } + this.liveSocket.dispatchEvents(events); + if (phxChildrenAdded) { + this.joinNewChildren(); + } + } + renderContainer(diff, kind) { + return this.liveSocket.time(`toString diff (${kind})`, () => { + let tag = this.el.tagName; + let cids = diff ? this.rendered.componentCIDs(diff).concat(this.pruningCIDs) : null; + let [html, streams] = this.rendered.toString(cids); + return [`<${tag}>${html}`, streams]; + }); + } + componentPatch(diff, cid) { + if (isEmpty(diff)) + return false; + let [html, streams] = this.rendered.componentToString(cid); + let patch = new DOMPatch(this, this.el, this.id, html, streams, cid); + let childrenAdded = this.performPatch(patch, true); + return childrenAdded; + } + getHook(el) { + return this.viewHooks[ViewHook.elementID(el)]; + } + addHook(el) { + if (ViewHook.elementID(el) || !el.getAttribute) { + return; + } + let hookName = el.getAttribute(`data-phx-${PHX_HOOK}`) || el.getAttribute(this.binding(PHX_HOOK)); + if (hookName && !this.ownsElement(el)) { + return; + } + let callbacks = this.liveSocket.getHookCallbacks(hookName); + if (callbacks) { + if (!el.id) { + logError(`no DOM ID for hook "${hookName}". Hooks require a unique ID on each element.`, el); + } + let hook = new ViewHook(this, el, callbacks); + this.viewHooks[ViewHook.elementID(hook.el)] = hook; + return hook; + } else if (hookName !== null) { + logError(`unknown hook found for "${hookName}"`, el); + } + } + destroyHook(hook) { + hook.__destroyed(); + hook.__cleanup__(); + delete this.viewHooks[ViewHook.elementID(hook.el)]; + } + applyPendingUpdates() { + this.pendingDiffs.forEach(({ diff, events }) => this.update(diff, events)); + this.pendingDiffs = []; + this.eachChild((child) => child.applyPendingUpdates()); + } + eachChild(callback) { + let children = this.root.children[this.id] || {}; + for (let id in children) { + callback(this.getChildById(id)); + } + } + onChannel(event, cb) { + this.liveSocket.onChannel(this.channel, event, (resp) => { + if (this.isJoinPending()) { + this.root.pendingJoinOps.push([this, () => cb(resp)]); + } else { + this.liveSocket.requestDOMUpdate(() => cb(resp)); + } + }); + } + bindChannel() { + this.liveSocket.onChannel(this.channel, "diff", (rawDiff) => { + this.liveSocket.requestDOMUpdate(() => { + this.applyDiff("update", rawDiff, ({ diff, events }) => this.update(diff, events)); + }); + }); + this.onChannel("redirect", ({ to, flash }) => this.onRedirect({ to, flash })); + this.onChannel("live_patch", (redir) => this.onLivePatch(redir)); + this.onChannel("live_redirect", (redir) => this.onLiveRedirect(redir)); + this.channel.onError((reason) => this.onError(reason)); + this.channel.onClose((reason) => this.onClose(reason)); + } + destroyAllChildren() { + this.eachChild((child) => child.destroy()); + } + onLiveRedirect(redir) { + let { to, kind, flash } = redir; + let url = this.expandURL(to); + this.liveSocket.historyRedirect(url, kind, flash); + } + onLivePatch(redir) { + let { to, kind } = redir; + this.href = this.expandURL(to); + this.liveSocket.historyPatch(to, kind); + } + expandURL(to) { + return to.startsWith("/") ? `${window.location.protocol}//${window.location.host}${to}` : to; + } + onRedirect({ to, flash }) { + this.liveSocket.redirect(to, flash); + } + isDestroyed() { + return this.destroyed; + } + joinDead() { + this.isDead = true; + } + join(callback) { + this.showLoader(this.liveSocket.loaderTimeout); + this.bindChannel(); + if (this.isMain()) { + this.stopCallback = this.liveSocket.withPageLoading({ to: this.href, kind: "initial" }); + } + this.joinCallback = (onDone) => { + onDone = onDone || function() { + }; + callback ? callback(this.joinCount, onDone) : onDone(); + }; + this.liveSocket.wrapPush(this, { timeout: false }, () => { + return this.channel.join().receive("ok", (data) => { + if (!this.isDestroyed()) { + this.liveSocket.requestDOMUpdate(() => this.onJoin(data)); + } + }).receive("error", (resp) => !this.isDestroyed() && this.onJoinError(resp)).receive("timeout", () => !this.isDestroyed() && this.onJoinError({ reason: "timeout" })); + }); + } + onJoinError(resp) { + if (resp.reason === "reload") { + this.log("error", () => [`failed mount with ${resp.status}. Falling back to page request`, resp]); + if (this.isMain()) { + this.onRedirect({ to: this.href }); + } + return; + } else if (resp.reason === "unauthorized" || resp.reason === "stale") { + this.log("error", () => ["unauthorized live_redirect. Falling back to page request", resp]); + if (this.isMain()) { + this.onRedirect({ to: this.href }); + } + return; + } + if (resp.redirect || resp.live_redirect) { + this.joinPending = false; + this.channel.leave(); + } + if (resp.redirect) { + return this.onRedirect(resp.redirect); + } + if (resp.live_redirect) { + return this.onLiveRedirect(resp.live_redirect); + } + this.displayError([PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS]); + this.log("error", () => ["unable to join", resp]); + if (this.liveSocket.isConnected()) { + this.liveSocket.reloadWithJitter(this); + } + } + onClose(reason) { + if (this.isDestroyed()) { + return; + } + if (this.liveSocket.hasPendingLink() && reason !== "leave") { + return this.liveSocket.reloadWithJitter(this); + } + this.destroyAllChildren(); + this.liveSocket.dropActiveElement(this); + if (document.activeElement) { + document.activeElement.blur(); + } + if (this.liveSocket.isUnloaded()) { + this.showLoader(BEFORE_UNLOAD_LOADER_TIMEOUT); + } + } + onError(reason) { + this.onClose(reason); + if (this.liveSocket.isConnected()) { + this.log("error", () => ["view crashed", reason]); + } + if (!this.liveSocket.isUnloaded()) { + if (this.liveSocket.isConnected()) { + this.displayError([PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS]); + } else { + this.displayError([PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_CLIENT_ERROR_CLASS]); + } + } + } + displayError(classes) { + if (this.isMain()) { + dom_default.dispatchEvent(window, "phx:page-loading-start", { detail: { to: this.href, kind: "error" } }); + } + this.showLoader(); + this.setContainerClasses(...classes); + this.execAll(this.binding("disconnected")); + } + pushWithReply(refGenerator, event, payload, onReply = function() { + }) { + if (!this.isConnected()) { + return; + } + let [ref, [el], opts] = refGenerator ? refGenerator() : [null, [], {}]; + let onLoadingDone = function() { + }; + if (opts.page_loading || el && el.getAttribute(this.binding(PHX_PAGE_LOADING)) !== null) { + onLoadingDone = this.liveSocket.withPageLoading({ kind: "element", target: el }); + } + if (typeof payload.cid !== "number") { + delete payload.cid; + } + return this.liveSocket.wrapPush(this, { timeout: true }, () => { + return this.channel.push(event, payload, PUSH_TIMEOUT).receive("ok", (resp) => { + let finish = (hookReply) => { + if (resp.redirect) { + this.onRedirect(resp.redirect); + } + if (resp.live_patch) { + this.onLivePatch(resp.live_patch); + } + if (resp.live_redirect) { + this.onLiveRedirect(resp.live_redirect); + } + onLoadingDone(); + onReply(resp, hookReply); + }; + if (resp.diff) { + this.liveSocket.requestDOMUpdate(() => { + this.applyDiff("update", resp.diff, ({ diff, reply, events }) => { + if (ref !== null) { + this.undoRefs(ref); + } + this.update(diff, events); + finish(reply); + }); + }); + } else { + if (ref !== null) { + this.undoRefs(ref); + } + finish(null); + } + }); + }); + } + undoRefs(ref) { + if (!this.isConnected()) { + return; + } + dom_default.all(document, `[${PHX_REF_SRC}="${this.id}"][${PHX_REF}="${ref}"]`, (el) => { + let disabledVal = el.getAttribute(PHX_DISABLED); + el.removeAttribute(PHX_REF); + el.removeAttribute(PHX_REF_SRC); + if (el.getAttribute(PHX_READONLY) !== null) { + el.readOnly = false; + el.removeAttribute(PHX_READONLY); + } + if (disabledVal !== null) { + el.disabled = disabledVal === "true" ? true : false; + el.removeAttribute(PHX_DISABLED); + } + PHX_EVENT_CLASSES.forEach((className) => dom_default.removeClass(el, className)); + let disableRestore = el.getAttribute(PHX_DISABLE_WITH_RESTORE); + if (disableRestore !== null) { + el.innerText = disableRestore; + el.removeAttribute(PHX_DISABLE_WITH_RESTORE); + } + let toEl = dom_default.private(el, PHX_REF); + if (toEl) { + let hook = this.triggerBeforeUpdateHook(el, toEl); + DOMPatch.patchEl(el, toEl, this.liveSocket.getActiveElement()); + if (hook) { + hook.__updated(); + } + dom_default.deletePrivate(el, PHX_REF); + } + }); + } + putRef(elements, event, opts = {}) { + let newRef = this.ref++; + let disableWith = this.binding(PHX_DISABLE_WITH); + if (opts.loading) { + elements = elements.concat(dom_default.all(document, opts.loading)); + } + elements.forEach((el) => { + el.classList.add(`phx-${event}-loading`); + el.setAttribute(PHX_REF, newRef); + el.setAttribute(PHX_REF_SRC, this.el.id); + let disableText = el.getAttribute(disableWith); + if (disableText !== null) { + if (!el.getAttribute(PHX_DISABLE_WITH_RESTORE)) { + el.setAttribute(PHX_DISABLE_WITH_RESTORE, el.innerText); + } + if (disableText !== "") { + el.innerText = disableText; + } + el.setAttribute("disabled", ""); + } + }); + return [newRef, elements, opts]; + } + componentID(el) { + let cid = el.getAttribute && el.getAttribute(PHX_COMPONENT); + return cid ? parseInt(cid) : null; + } + targetComponentID(target, targetCtx, opts = {}) { + if (isCid(targetCtx)) { + return targetCtx; + } + let cidOrSelector = target.getAttribute(this.binding("target")); + if (isCid(cidOrSelector)) { + return parseInt(cidOrSelector); + } else if (targetCtx && (cidOrSelector !== null || opts.target)) { + return this.closestComponentID(targetCtx); + } else { + return null; + } + } + closestComponentID(targetCtx) { + if (isCid(targetCtx)) { + return targetCtx; + } else if (targetCtx) { + return maybe(targetCtx.closest(`[${PHX_COMPONENT}]`), (el) => this.ownsElement(el) && this.componentID(el)); + } else { + return null; + } + } + pushHookEvent(el, targetCtx, event, payload, onReply) { + if (!this.isConnected()) { + this.log("hook", () => ["unable to push hook event. LiveView not connected", event, payload]); + return false; + } + let [ref, els, opts] = this.putRef([el], "hook"); + this.pushWithReply(() => [ref, els, opts], "event", { + type: "hook", + event, + value: payload, + cid: this.closestComponentID(targetCtx) + }, (resp, reply) => onReply(reply, ref)); + return ref; + } + extractMeta(el, meta, value) { + let prefix = this.binding("value-"); + for (let i = 0; i < el.attributes.length; i++) { + if (!meta) { + meta = {}; + } + let name = el.attributes[i].name; + if (name.startsWith(prefix)) { + meta[name.replace(prefix, "")] = el.getAttribute(name); + } + } + if (el.value !== void 0 && !(el instanceof HTMLFormElement)) { + if (!meta) { + meta = {}; + } + meta.value = el.value; + if (el.tagName === "INPUT" && CHECKABLE_INPUTS.indexOf(el.type) >= 0 && !el.checked) { + delete meta.value; + } + } + if (value) { + if (!meta) { + meta = {}; + } + for (let key in value) { + meta[key] = value[key]; + } + } + return meta; + } + pushEvent(type, el, targetCtx, phxEvent, meta, opts = {}, onReply) { + this.pushWithReply(() => this.putRef([el], type, opts), "event", { + type, + event: phxEvent, + value: this.extractMeta(el, meta, opts.value), + cid: this.targetComponentID(el, targetCtx, opts) + }, (resp, reply) => onReply && onReply(reply)); + } + pushFileProgress(fileEl, entryRef, progress, onReply = function() { + }) { + this.liveSocket.withinOwners(fileEl.form, (view, targetCtx) => { + view.pushWithReply(null, "progress", { + event: fileEl.getAttribute(view.binding(PHX_PROGRESS)), + ref: fileEl.getAttribute(PHX_UPLOAD_REF), + entry_ref: entryRef, + progress, + cid: view.targetComponentID(fileEl.form, targetCtx) + }, onReply); + }); + } + pushInput(inputEl, targetCtx, forceCid, phxEvent, opts, callback) { + let uploads; + let cid = isCid(forceCid) ? forceCid : this.targetComponentID(inputEl.form, targetCtx); + let refGenerator = () => this.putRef([inputEl, inputEl.form], "change", opts); + let formData; + let meta = this.extractMeta(inputEl.form); + if (inputEl.getAttribute(this.binding("change"))) { + formData = serializeForm(inputEl.form, __spreadValues({ _target: opts._target }, meta), [inputEl.name]); + } else { + formData = serializeForm(inputEl.form, __spreadValues({ _target: opts._target }, meta)); + } + if (dom_default.isUploadInput(inputEl) && inputEl.files && inputEl.files.length > 0) { + LiveUploader.trackFiles(inputEl, Array.from(inputEl.files)); + } + uploads = LiveUploader.serializeUploads(inputEl); + let event = { + type: "form", + event: phxEvent, + value: formData, + uploads, + cid + }; + this.pushWithReply(refGenerator, "event", event, (resp) => { + dom_default.showError(inputEl, this.liveSocket.binding(PHX_FEEDBACK_FOR)); + if (dom_default.isUploadInput(inputEl) && dom_default.isAutoUpload(inputEl)) { + if (LiveUploader.filesAwaitingPreflight(inputEl).length > 0) { + let [ref, _els] = refGenerator(); + this.uploadFiles(inputEl.form, targetCtx, ref, cid, (_uploads) => { + callback && callback(resp); + this.triggerAwaitingSubmit(inputEl.form); + }); + } + } else { + callback && callback(resp); + } + }); + } + triggerAwaitingSubmit(formEl) { + let awaitingSubmit = this.getScheduledSubmit(formEl); + if (awaitingSubmit) { + let [_el, _ref, _opts, callback] = awaitingSubmit; + this.cancelSubmit(formEl); + callback(); + } + } + getScheduledSubmit(formEl) { + return this.formSubmits.find(([el, _ref, _opts, _callback]) => el.isSameNode(formEl)); + } + scheduleSubmit(formEl, ref, opts, callback) { + if (this.getScheduledSubmit(formEl)) { + return true; + } + this.formSubmits.push([formEl, ref, opts, callback]); + } + cancelSubmit(formEl) { + this.formSubmits = this.formSubmits.filter(([el, ref, _callback]) => { + if (el.isSameNode(formEl)) { + this.undoRefs(ref); + return false; + } else { + return true; + } + }); + } + disableForm(formEl, opts = {}) { + let filterIgnored = (el) => { + let userIgnored = closestPhxBinding(el, `${this.binding(PHX_UPDATE)}=ignore`, el.form); + return !(userIgnored || closestPhxBinding(el, "data-phx-update=ignore", el.form)); + }; + let filterDisables = (el) => { + return el.hasAttribute(this.binding(PHX_DISABLE_WITH)); + }; + let filterButton = (el) => el.tagName == "BUTTON"; + let filterInput = (el) => ["INPUT", "TEXTAREA", "SELECT"].includes(el.tagName); + let formElements = Array.from(formEl.elements); + let disables = formElements.filter(filterDisables); + let buttons = formElements.filter(filterButton).filter(filterIgnored); + let inputs = formElements.filter(filterInput).filter(filterIgnored); + buttons.forEach((button) => { + button.setAttribute(PHX_DISABLED, button.disabled); + button.disabled = true; + }); + inputs.forEach((input) => { + input.setAttribute(PHX_READONLY, input.readOnly); + input.readOnly = true; + if (input.files) { + input.setAttribute(PHX_DISABLED, input.disabled); + input.disabled = true; + } + }); + formEl.setAttribute(this.binding(PHX_PAGE_LOADING), ""); + return this.putRef([formEl].concat(disables).concat(buttons).concat(inputs), "submit", opts); + } + pushFormSubmit(formEl, targetCtx, phxEvent, submitter, opts, onReply) { + let refGenerator = () => this.disableForm(formEl, opts); + let cid = this.targetComponentID(formEl, targetCtx); + if (LiveUploader.hasUploadsInProgress(formEl)) { + let [ref, _els] = refGenerator(); + let push = () => this.pushFormSubmit(formEl, submitter, targetCtx, phxEvent, opts, onReply); + return this.scheduleSubmit(formEl, ref, opts, push); + } else if (LiveUploader.inputsAwaitingPreflight(formEl).length > 0) { + let [ref, els] = refGenerator(); + let proxyRefGen = () => [ref, els, opts]; + this.uploadFiles(formEl, targetCtx, ref, cid, (_uploads) => { + let meta = this.extractMeta(formEl); + let formData = serializeForm(formEl, __spreadValues({ submitter }, meta)); + this.pushWithReply(proxyRefGen, "event", { + type: "form", + event: phxEvent, + value: formData, + cid + }, onReply); + }); + } else if (!(formEl.hasAttribute(PHX_REF) && formEl.classList.contains("phx-submit-loading"))) { + let meta = this.extractMeta(formEl); + let formData = serializeForm(formEl, __spreadValues({ submitter }, meta)); + this.pushWithReply(refGenerator, "event", { + type: "form", + event: phxEvent, + value: formData, + cid + }, onReply); + } + } + uploadFiles(formEl, targetCtx, ref, cid, onComplete) { + let joinCountAtUpload = this.joinCount; + let inputEls = LiveUploader.activeFileInputs(formEl); + let numFileInputsInProgress = inputEls.length; + inputEls.forEach((inputEl) => { + let uploader = new LiveUploader(inputEl, this, () => { + numFileInputsInProgress--; + if (numFileInputsInProgress === 0) { + onComplete(); + } + }); + this.uploaders[inputEl] = uploader; + let entries = uploader.entries().map((entry) => entry.toPreflightPayload()); + let payload = { + ref: inputEl.getAttribute(PHX_UPLOAD_REF), + entries, + cid: this.targetComponentID(inputEl.form, targetCtx) + }; + this.log("upload", () => ["sending preflight request", payload]); + this.pushWithReply(null, "allow_upload", payload, (resp) => { + this.log("upload", () => ["got preflight response", resp]); + if (resp.error) { + this.undoRefs(ref); + let [entry_ref, reason] = resp.error; + this.log("upload", () => [`error for entry ${entry_ref}`, reason]); + } else { + let onError = (callback) => { + this.channel.onError(() => { + if (this.joinCount === joinCountAtUpload) { + callback(); + } + }); + }; + uploader.initAdapterUpload(resp, onError, this.liveSocket); + } + }); + }); + } + dispatchUploads(name, filesOrBlobs) { + let inputs = dom_default.findUploadInputs(this.el).filter((el) => el.name === name); + if (inputs.length === 0) { + logError(`no live file inputs found matching the name "${name}"`); + } else if (inputs.length > 1) { + logError(`duplicate live file inputs found matching the name "${name}"`); + } else { + dom_default.dispatchEvent(inputs[0], PHX_TRACK_UPLOADS, { detail: { files: filesOrBlobs } }); + } + } + pushFormRecovery(form, newCid, callback) { + this.liveSocket.withinOwners(form, (view, targetCtx) => { + let phxChange = this.binding("change"); + let inputs = Array.from(form.elements).filter((el) => dom_default.isFormInput(el) && el.name && !el.hasAttribute(phxChange)); + if (inputs.length === 0) { + return; + } + inputs.forEach((input2) => input2.hasAttribute(PHX_UPLOAD_REF) && LiveUploader.clearFiles(input2)); + let input = inputs.find((el) => el.type !== "hidden") || inputs[0]; + let phxEvent = form.getAttribute(this.binding(PHX_AUTO_RECOVER)) || form.getAttribute(this.binding("change")); + js_default.exec("change", phxEvent, view, input, ["push", { _target: input.name, newCid, callback }]); + }); + } + pushLinkPatch(href, targetEl, callback) { + let linkRef = this.liveSocket.setPendingLink(href); + let refGen = targetEl ? () => this.putRef([targetEl], "click") : null; + let fallback = () => this.liveSocket.redirect(window.location.href); + let url = href.startsWith("/") ? `${location.protocol}//${location.host}${href}` : href; + let push = this.pushWithReply(refGen, "live_patch", { url }, (resp) => { + this.liveSocket.requestDOMUpdate(() => { + if (resp.link_redirect) { + this.liveSocket.replaceMain(href, null, callback, linkRef); + } else { + if (this.liveSocket.commitPendingLink(linkRef)) { + this.href = href; + } + this.applyPendingUpdates(); + callback && callback(linkRef); + } + }); + }); + if (push) { + push.receive("timeout", fallback); + } else { + fallback(); + } + } + formsForRecovery(html) { + if (this.joinCount === 0) { + return []; + } + let phxChange = this.binding("change"); + let template = document.createElement("template"); + template.innerHTML = html; + return dom_default.all(this.el, `form[${phxChange}]`).filter((form) => form.id && this.ownsElement(form)).filter((form) => form.elements.length > 0).filter((form) => form.getAttribute(this.binding(PHX_AUTO_RECOVER)) !== "ignore").map((form) => { + const phxChangeValue = form.getAttribute(phxChange).replaceAll(/([\[\]"])/g, "\\$1"); + let newForm = template.content.querySelector(`form[id="${form.id}"][${phxChange}="${phxChangeValue}"]`); + if (newForm) { + return [form, newForm, this.targetComponentID(newForm)]; + } else { + return [form, form, this.targetComponentID(form)]; + } + }).filter(([form, newForm, newCid]) => newForm); + } + maybePushComponentsDestroyed(destroyedCIDs) { + let willDestroyCIDs = destroyedCIDs.filter((cid) => { + return dom_default.findComponentNodeList(this.el, cid).length === 0; + }); + if (willDestroyCIDs.length > 0) { + this.pruningCIDs.push(...willDestroyCIDs); + this.pushWithReply(null, "cids_will_destroy", { cids: willDestroyCIDs }, () => { + this.pruningCIDs = this.pruningCIDs.filter((cid) => willDestroyCIDs.indexOf(cid) !== -1); + let completelyDestroyCIDs = willDestroyCIDs.filter((cid) => { + return dom_default.findComponentNodeList(this.el, cid).length === 0; + }); + if (completelyDestroyCIDs.length > 0) { + this.pushWithReply(null, "cids_destroyed", { cids: completelyDestroyCIDs }, (resp) => { + this.rendered.pruneCIDs(resp.cids); + }); + } + }); + } + } + ownsElement(el) { + let parentViewEl = el.closest(PHX_VIEW_SELECTOR); + return el.getAttribute(PHX_PARENT_ID) === this.id || parentViewEl && parentViewEl.id === this.id || !parentViewEl && this.isDead; + } + submitForm(form, targetCtx, phxEvent, submitter, opts = {}) { + dom_default.putPrivate(form, PHX_HAS_SUBMITTED, true); + let phxFeedback = this.liveSocket.binding(PHX_FEEDBACK_FOR); + let inputs = Array.from(form.elements); + inputs.forEach((input) => dom_default.putPrivate(input, PHX_HAS_SUBMITTED, true)); + this.liveSocket.blurActiveElement(this); + this.pushFormSubmit(form, targetCtx, phxEvent, submitter, opts, () => { + inputs.forEach((input) => dom_default.showError(input, phxFeedback)); + this.liveSocket.restorePreviouslyActiveFocus(); + }); + } + binding(kind) { + return this.liveSocket.binding(kind); + } + }; + var LiveSocket = class { + constructor(url, phxSocket, opts = {}) { + this.unloaded = false; + if (!phxSocket || phxSocket.constructor.name === "Object") { + throw new Error(` + a phoenix Socket must be provided as the second argument to the LiveSocket constructor. For example: + + import {Socket} from "phoenix" + import {LiveSocket} from "phoenix_live_view" + let liveSocket = new LiveSocket("/live", Socket, {...}) + `); + } + this.socket = new phxSocket(url, opts); + this.bindingPrefix = opts.bindingPrefix || BINDING_PREFIX; + this.opts = opts; + this.params = closure2(opts.params || {}); + this.viewLogger = opts.viewLogger; + this.metadataCallbacks = opts.metadata || {}; + this.defaults = Object.assign(clone(DEFAULTS), opts.defaults || {}); + this.activeElement = null; + this.prevActive = null; + this.silenced = false; + this.main = null; + this.outgoingMainEl = null; + this.clickStartedAtTarget = null; + this.linkRef = 1; + this.roots = {}; + this.href = window.location.href; + this.pendingLink = null; + this.currentLocation = clone(window.location); + this.hooks = opts.hooks || {}; + this.uploaders = opts.uploaders || {}; + this.loaderTimeout = opts.loaderTimeout || LOADER_TIMEOUT; + this.reloadWithJitterTimer = null; + this.maxReloads = opts.maxReloads || MAX_RELOADS; + this.reloadJitterMin = opts.reloadJitterMin || RELOAD_JITTER_MIN; + this.reloadJitterMax = opts.reloadJitterMax || RELOAD_JITTER_MAX; + this.failsafeJitter = opts.failsafeJitter || FAILSAFE_JITTER; + this.localStorage = opts.localStorage || window.localStorage; + this.sessionStorage = opts.sessionStorage || window.sessionStorage; + this.boundTopLevelEvents = false; + this.domCallbacks = Object.assign({ onNodeAdded: closure2(), onBeforeElUpdated: closure2() }, opts.dom || {}); + this.transitions = new TransitionSet(); + window.addEventListener("pagehide", (_e) => { + this.unloaded = true; + }); + this.socket.onOpen(() => { + if (this.isUnloaded()) { + window.location.reload(); + } + }); + } + isProfileEnabled() { + return this.sessionStorage.getItem(PHX_LV_PROFILE) === "true"; + } + isDebugEnabled() { + return this.sessionStorage.getItem(PHX_LV_DEBUG) === "true"; + } + isDebugDisabled() { + return this.sessionStorage.getItem(PHX_LV_DEBUG) === "false"; + } + enableDebug() { + this.sessionStorage.setItem(PHX_LV_DEBUG, "true"); + } + enableProfiling() { + this.sessionStorage.setItem(PHX_LV_PROFILE, "true"); + } + disableDebug() { + this.sessionStorage.setItem(PHX_LV_DEBUG, "false"); + } + disableProfiling() { + this.sessionStorage.removeItem(PHX_LV_PROFILE); + } + enableLatencySim(upperBoundMs) { + this.enableDebug(); + console.log("latency simulator enabled for the duration of this browser session. Call disableLatencySim() to disable"); + this.sessionStorage.setItem(PHX_LV_LATENCY_SIM, upperBoundMs); + } + disableLatencySim() { + this.sessionStorage.removeItem(PHX_LV_LATENCY_SIM); + } + getLatencySim() { + let str = this.sessionStorage.getItem(PHX_LV_LATENCY_SIM); + return str ? parseInt(str) : null; + } + getSocket() { + return this.socket; + } + connect() { + if (window.location.hostname === "localhost" && !this.isDebugDisabled()) { + this.enableDebug(); + } + let doConnect = () => { + if (this.joinRootViews()) { + this.bindTopLevelEvents(); + this.socket.connect(); + } else if (this.main) { + this.socket.connect(); + } else { + this.bindTopLevelEvents({ dead: true }); + } + this.joinDeadView(); + }; + if (["complete", "loaded", "interactive"].indexOf(document.readyState) >= 0) { + doConnect(); + } else { + document.addEventListener("DOMContentLoaded", () => doConnect()); + } + } + disconnect(callback) { + clearTimeout(this.reloadWithJitterTimer); + this.socket.disconnect(callback); + } + replaceTransport(transport) { + clearTimeout(this.reloadWithJitterTimer); + this.socket.replaceTransport(transport); + this.connect(); + } + execJS(el, encodedJS, eventType = null) { + this.owner(el, (view) => js_default.exec(eventType, encodedJS, view, el)); + } + execJSHookPush(el, phxEvent, data, callback) { + this.withinOwners(el, (view) => { + js_default.exec("hook", phxEvent, view, el, ["push", { data, callback }]); + }); + } + unload() { + if (this.unloaded) { + return; + } + if (this.main && this.isConnected()) { + this.log(this.main, "socket", () => ["disconnect for page nav"]); + } + this.unloaded = true; + this.destroyAllViews(); + this.disconnect(); + } + triggerDOM(kind, args) { + this.domCallbacks[kind](...args); + } + time(name, func) { + if (!this.isProfileEnabled() || !console.time) { + return func(); + } + console.time(name); + let result = func(); + console.timeEnd(name); + return result; + } + log(view, kind, msgCallback) { + if (this.viewLogger) { + let [msg, obj] = msgCallback(); + this.viewLogger(view, kind, msg, obj); + } else if (this.isDebugEnabled()) { + let [msg, obj] = msgCallback(); + debug(view, kind, msg, obj); + } + } + requestDOMUpdate(callback) { + this.transitions.after(callback); + } + transition(time, onStart, onDone = function() { + }) { + this.transitions.addTransition(time, onStart, onDone); + } + onChannel(channel, event, cb) { + channel.on(event, (data) => { + let latency = this.getLatencySim(); + if (!latency) { + cb(data); + } else { + setTimeout(() => cb(data), latency); + } + }); + } + wrapPush(view, opts, push) { + let latency = this.getLatencySim(); + let oldJoinCount = view.joinCount; + if (!latency) { + if (this.isConnected() && opts.timeout) { + return push().receive("timeout", () => { + if (view.joinCount === oldJoinCount && !view.isDestroyed()) { + this.reloadWithJitter(view, () => { + this.log(view, "timeout", () => ["received timeout while communicating with server. Falling back to hard refresh for recovery"]); + }); + } + }); + } else { + return push(); + } + } + let fakePush = { + receives: [], + receive(kind, cb) { + this.receives.push([kind, cb]); + } + }; + setTimeout(() => { + if (view.isDestroyed()) { + return; + } + fakePush.receives.reduce((acc, [kind, cb]) => acc.receive(kind, cb), push()); + }, latency); + return fakePush; + } + reloadWithJitter(view, log) { + clearTimeout(this.reloadWithJitterTimer); + this.disconnect(); + let minMs = this.reloadJitterMin; + let maxMs = this.reloadJitterMax; + let afterMs = Math.floor(Math.random() * (maxMs - minMs + 1)) + minMs; + let tries = browser_default.updateLocal(this.localStorage, window.location.pathname, CONSECUTIVE_RELOADS, 0, (count) => count + 1); + if (tries > this.maxReloads) { + afterMs = this.failsafeJitter; + } + this.reloadWithJitterTimer = setTimeout(() => { + if (view.isDestroyed() || view.isConnected()) { + return; + } + view.destroy(); + log ? log() : this.log(view, "join", () => [`encountered ${tries} consecutive reloads`]); + if (tries > this.maxReloads) { + this.log(view, "join", () => [`exceeded ${this.maxReloads} consecutive reloads. Entering failsafe mode`]); + } + if (this.hasPendingLink()) { + window.location = this.pendingLink; + } else { + window.location.reload(); + } + }, afterMs); + } + getHookCallbacks(name) { + return name && name.startsWith("Phoenix.") ? hooks_default[name.split(".")[1]] : this.hooks[name]; + } + isUnloaded() { + return this.unloaded; + } + isConnected() { + return this.socket.isConnected(); + } + getBindingPrefix() { + return this.bindingPrefix; + } + binding(kind) { + return `${this.getBindingPrefix()}${kind}`; + } + channel(topic, params) { + return this.socket.channel(topic, params); + } + joinDeadView() { + let body = document.body; + if (body && !this.isPhxView(body) && !this.isPhxView(document.firstElementChild)) { + let view = this.newRootView(body); + view.setHref(this.getHref()); + view.joinDead(); + if (!this.main) { + this.main = view; + } + window.requestAnimationFrame(() => view.execNewMounted()); + } + } + joinRootViews() { + let rootsFound = false; + dom_default.all(document, `${PHX_VIEW_SELECTOR}:not([${PHX_PARENT_ID}])`, (rootEl) => { + if (!this.getRootById(rootEl.id)) { + let view = this.newRootView(rootEl); + view.setHref(this.getHref()); + view.join(); + if (rootEl.hasAttribute(PHX_MAIN)) { + this.main = view; + } + } + rootsFound = true; + }); + return rootsFound; + } + redirect(to, flash) { + this.unload(); + browser_default.redirect(to, flash); + } + replaceMain(href, flash, callback = null, linkRef = this.setPendingLink(href)) { + let liveReferer = this.currentLocation.href; + this.outgoingMainEl = this.outgoingMainEl || this.main.el; + let newMainEl = dom_default.cloneNode(this.outgoingMainEl, ""); + this.main.showLoader(this.loaderTimeout); + this.main.destroy(); + this.main = this.newRootView(newMainEl, flash, liveReferer); + this.main.setRedirect(href); + this.transitionRemoves(); + this.main.join((joinCount, onDone) => { + if (joinCount === 1 && this.commitPendingLink(linkRef)) { + this.requestDOMUpdate(() => { + dom_default.findPhxSticky(document).forEach((el) => newMainEl.appendChild(el)); + this.outgoingMainEl.replaceWith(newMainEl); + this.outgoingMainEl = null; + callback && requestAnimationFrame(() => callback(linkRef)); + onDone(); + }); + } + }); + } + transitionRemoves(elements) { + let removeAttr = this.binding("remove"); + elements = elements || dom_default.all(document, `[${removeAttr}]`); + elements.forEach((el) => { + this.execJS(el, el.getAttribute(removeAttr), "remove"); + }); + } + isPhxView(el) { + return el.getAttribute && el.getAttribute(PHX_SESSION) !== null; + } + newRootView(el, flash, liveReferer) { + let view = new View(el, this, null, flash, liveReferer); + this.roots[view.id] = view; + return view; + } + owner(childEl, callback) { + let view = maybe(childEl.closest(PHX_VIEW_SELECTOR), (el) => this.getViewByEl(el)) || this.main; + if (view) { + callback(view); + } + } + withinOwners(childEl, callback) { + this.owner(childEl, (view) => callback(view, childEl)); + } + getViewByEl(el) { + let rootId = el.getAttribute(PHX_ROOT_ID); + return maybe(this.getRootById(rootId), (root) => root.getDescendentByEl(el)); + } + getRootById(id) { + return this.roots[id]; + } + destroyAllViews() { + for (let id in this.roots) { + this.roots[id].destroy(); + delete this.roots[id]; + } + this.main = null; + } + destroyViewByEl(el) { + let root = this.getRootById(el.getAttribute(PHX_ROOT_ID)); + if (root && root.id === el.id) { + root.destroy(); + delete this.roots[root.id]; + } else if (root) { + root.destroyDescendent(el.id); + } + } + setActiveElement(target) { + if (this.activeElement === target) { + return; + } + this.activeElement = target; + let cancel = () => { + if (target === this.activeElement) { + this.activeElement = null; + } + target.removeEventListener("mouseup", this); + target.removeEventListener("touchend", this); + }; + target.addEventListener("mouseup", cancel); + target.addEventListener("touchend", cancel); + } + getActiveElement() { + if (document.activeElement === document.body) { + return this.activeElement || document.activeElement; + } else { + return document.activeElement || document.body; + } + } + dropActiveElement(view) { + if (this.prevActive && view.ownsElement(this.prevActive)) { + this.prevActive = null; + } + } + restorePreviouslyActiveFocus() { + if (this.prevActive && this.prevActive !== document.body) { + this.prevActive.focus(); + } + } + blurActiveElement() { + this.prevActive = this.getActiveElement(); + if (this.prevActive !== document.body) { + this.prevActive.blur(); + } + } + bindTopLevelEvents({ dead } = {}) { + if (this.boundTopLevelEvents) { + return; + } + this.boundTopLevelEvents = true; + this.socket.onClose((event) => { + if (event && event.code === 1e3 && this.main) { + return this.reloadWithJitter(this.main); + } + }); + document.body.addEventListener("click", function() { + }); + window.addEventListener("pageshow", (e) => { + if (e.persisted) { + this.getSocket().disconnect(); + this.withPageLoading({ to: window.location.href, kind: "redirect" }); + window.location.reload(); + } + }, true); + if (!dead) { + this.bindNav(); + } + this.bindClicks(); + if (!dead) { + this.bindForms(); + } + this.bind({ keyup: "keyup", keydown: "keydown" }, (e, type, view, targetEl, phxEvent, eventTarget) => { + let matchKey = targetEl.getAttribute(this.binding(PHX_KEY)); + let pressedKey = e.key && e.key.toLowerCase(); + if (matchKey && matchKey.toLowerCase() !== pressedKey) { + return; + } + let data = __spreadValues({ key: e.key }, this.eventMeta(type, e, targetEl)); + js_default.exec(type, phxEvent, view, targetEl, ["push", { data }]); + }); + this.bind({ blur: "focusout", focus: "focusin" }, (e, type, view, targetEl, phxEvent, eventTarget) => { + if (!eventTarget) { + let data = __spreadValues({ key: e.key }, this.eventMeta(type, e, targetEl)); + js_default.exec(type, phxEvent, view, targetEl, ["push", { data }]); + } + }); + this.bind({ blur: "blur", focus: "focus" }, (e, type, view, targetEl, targetCtx, phxEvent, phxTarget) => { + if (phxTarget === "window") { + let data = this.eventMeta(type, e, targetEl); + js_default.exec(type, phxEvent, view, targetEl, ["push", { data }]); + } + }); + window.addEventListener("dragover", (e) => e.preventDefault()); + window.addEventListener("drop", (e) => { + e.preventDefault(); + let dropTargetId = maybe(closestPhxBinding(e.target, this.binding(PHX_DROP_TARGET)), (trueTarget) => { + return trueTarget.getAttribute(this.binding(PHX_DROP_TARGET)); + }); + let dropTarget = dropTargetId && document.getElementById(dropTargetId); + let files = Array.from(e.dataTransfer.files || []); + if (!dropTarget || dropTarget.disabled || files.length === 0 || !(dropTarget.files instanceof FileList)) { + return; + } + LiveUploader.trackFiles(dropTarget, files, e.dataTransfer); + dropTarget.dispatchEvent(new Event("input", { bubbles: true })); + }); + this.on(PHX_TRACK_UPLOADS, (e) => { + let uploadTarget = e.target; + if (!dom_default.isUploadInput(uploadTarget)) { + return; + } + let files = Array.from(e.detail.files || []).filter((f) => f instanceof File || f instanceof Blob); + LiveUploader.trackFiles(uploadTarget, files); + uploadTarget.dispatchEvent(new Event("input", { bubbles: true })); + }); + } + eventMeta(eventName, e, targetEl) { + let callback = this.metadataCallbacks[eventName]; + return callback ? callback(e, targetEl) : {}; + } + setPendingLink(href) { + this.linkRef++; + this.pendingLink = href; + return this.linkRef; + } + commitPendingLink(linkRef) { + if (this.linkRef !== linkRef) { + return false; + } else { + this.href = this.pendingLink; + this.pendingLink = null; + return true; + } + } + getHref() { + return this.href; + } + hasPendingLink() { + return !!this.pendingLink; + } + bind(events, callback) { + for (let event in events) { + let browserEventName = events[event]; + this.on(browserEventName, (e) => { + let binding = this.binding(event); + let windowBinding = this.binding(`window-${event}`); + let targetPhxEvent = e.target.getAttribute && e.target.getAttribute(binding); + if (targetPhxEvent) { + this.debounce(e.target, e, browserEventName, () => { + this.withinOwners(e.target, (view) => { + callback(e, event, view, e.target, targetPhxEvent, null); + }); + }); + } else { + dom_default.all(document, `[${windowBinding}]`, (el) => { + let phxEvent = el.getAttribute(windowBinding); + this.debounce(el, e, browserEventName, () => { + this.withinOwners(el, (view) => { + callback(e, event, view, el, phxEvent, "window"); + }); + }); + }); + } + }); + } + } + bindClicks() { + window.addEventListener("click", (e) => this.clickStartedAtTarget = e.target); + this.bindClick("click", "click", false); + this.bindClick("mousedown", "capture-click", true); + } + bindClick(eventName, bindingName, capture) { + let click = this.binding(bindingName); + window.addEventListener(eventName, (e) => { + let target = null; + if (capture) { + target = e.target.matches(`[${click}]`) ? e.target : e.target.querySelector(`[${click}]`); + } else { + let clickStartedAtTarget = this.clickStartedAtTarget || e.target; + target = closestPhxBinding(clickStartedAtTarget, click); + this.dispatchClickAway(e, clickStartedAtTarget); + this.clickStartedAtTarget = null; + } + let phxEvent = target && target.getAttribute(click); + if (!phxEvent) { + if (!capture && dom_default.isNewPageClick(e, window.location)) { + this.unload(); + } + return; + } + if (target.getAttribute("href") === "#") { + e.preventDefault(); + } + if (target.hasAttribute(PHX_REF)) { + return; + } + this.debounce(target, e, "click", () => { + this.withinOwners(target, (view) => { + js_default.exec("click", phxEvent, view, target, ["push", { data: this.eventMeta("click", e, target) }]); + }); + }); + }, capture); + } + dispatchClickAway(e, clickStartedAt) { + let phxClickAway = this.binding("click-away"); + dom_default.all(document, `[${phxClickAway}]`, (el) => { + if (!(el.isSameNode(clickStartedAt) || el.contains(clickStartedAt))) { + this.withinOwners(e.target, (view) => { + let phxEvent = el.getAttribute(phxClickAway); + if (js_default.isVisible(el)) { + js_default.exec("click", phxEvent, view, el, ["push", { data: this.eventMeta("click", e, e.target) }]); + } + }); + } + }); + } + bindNav() { + if (!browser_default.canPushState()) { + return; + } + if (history.scrollRestoration) { + history.scrollRestoration = "manual"; + } + let scrollTimer = null; + window.addEventListener("scroll", (_e) => { + clearTimeout(scrollTimer); + scrollTimer = setTimeout(() => { + browser_default.updateCurrentState((state) => Object.assign(state, { scroll: window.scrollY })); + }, 100); + }); + window.addEventListener("popstate", (event) => { + if (!this.registerNewLocation(window.location)) { + return; + } + let { type, id, root, scroll } = event.state || {}; + let href = window.location.href; + dom_default.dispatchEvent(window, "phx:navigate", { detail: { href, patch: type === "patch", pop: true } }); + this.requestDOMUpdate(() => { + if (this.main.isConnected() && (type === "patch" && id === this.main.id)) { + this.main.pushLinkPatch(href, null, () => { + this.maybeScroll(scroll); + }); + } else { + this.replaceMain(href, null, () => { + if (root) { + this.replaceRootHistory(); + } + this.maybeScroll(scroll); + }); + } + }); + }, false); + window.addEventListener("click", (e) => { + let target = closestPhxBinding(e.target, PHX_LIVE_LINK); + let type = target && target.getAttribute(PHX_LIVE_LINK); + if (!type || !this.isConnected() || !this.main || dom_default.wantsNewTab(e)) { + return; + } + let href = target.href; + let linkState = target.getAttribute(PHX_LINK_STATE); + e.preventDefault(); + e.stopImmediatePropagation(); + if (this.pendingLink === href) { + return; + } + this.requestDOMUpdate(() => { + if (type === "patch") { + this.pushHistoryPatch(href, linkState, target); + } else if (type === "redirect") { + this.historyRedirect(href, linkState); + } else { + throw new Error(`expected ${PHX_LIVE_LINK} to be "patch" or "redirect", got: ${type}`); + } + let phxClick = target.getAttribute(this.binding("click")); + if (phxClick) { + this.requestDOMUpdate(() => this.execJS(target, phxClick, "click")); + } + }); + }, false); + } + maybeScroll(scroll) { + if (typeof scroll === "number") { + requestAnimationFrame(() => { + window.scrollTo(0, scroll); + }); + } + } + dispatchEvent(event, payload = {}) { + dom_default.dispatchEvent(window, `phx:${event}`, { detail: payload }); + } + dispatchEvents(events) { + events.forEach(([event, payload]) => this.dispatchEvent(event, payload)); + } + withPageLoading(info, callback) { + dom_default.dispatchEvent(window, "phx:page-loading-start", { detail: info }); + let done = () => dom_default.dispatchEvent(window, "phx:page-loading-stop", { detail: info }); + return callback ? callback(done) : done; + } + pushHistoryPatch(href, linkState, targetEl) { + if (!this.isConnected()) { + return browser_default.redirect(href); + } + this.withPageLoading({ to: href, kind: "patch" }, (done) => { + this.main.pushLinkPatch(href, targetEl, (linkRef) => { + this.historyPatch(href, linkState, linkRef); + done(); + }); + }); + } + historyPatch(href, linkState, linkRef = this.setPendingLink(href)) { + if (!this.commitPendingLink(linkRef)) { + return; + } + browser_default.pushState(linkState, { type: "patch", id: this.main.id }, href); + dom_default.dispatchEvent(window, "phx:navigate", { detail: { patch: true, href, pop: false } }); + this.registerNewLocation(window.location); + } + historyRedirect(href, linkState, flash) { + if (!this.isConnected()) { + return browser_default.redirect(href, flash); + } + if (/^\/$|^\/[^\/]+.*$/.test(href)) { + let { protocol, host } = window.location; + href = `${protocol}//${host}${href}`; + } + let scroll = window.scrollY; + this.withPageLoading({ to: href, kind: "redirect" }, (done) => { + this.replaceMain(href, flash, (linkRef) => { + if (linkRef === this.linkRef) { + browser_default.pushState(linkState, { type: "redirect", id: this.main.id, scroll }, href); + dom_default.dispatchEvent(window, "phx:navigate", { detail: { href, patch: false, pop: false } }); + this.registerNewLocation(window.location); + } + done(); + }); + }); + } + replaceRootHistory() { + browser_default.pushState("replace", { root: true, type: "patch", id: this.main.id }); + } + registerNewLocation(newLocation) { + let { pathname, search } = this.currentLocation; + if (pathname + search === newLocation.pathname + newLocation.search) { + return false; + } else { + this.currentLocation = clone(newLocation); + return true; + } + } + bindForms() { + let iterations = 0; + let externalFormSubmitted = false; + this.on("submit", (e) => { + let phxSubmit = e.target.getAttribute(this.binding("submit")); + let phxChange = e.target.getAttribute(this.binding("change")); + if (!externalFormSubmitted && phxChange && !phxSubmit) { + externalFormSubmitted = true; + e.preventDefault(); + this.withinOwners(e.target, (view) => { + view.disableForm(e.target); + window.requestAnimationFrame(() => { + if (dom_default.isUnloadableFormSubmit(e)) { + this.unload(); + } + e.target.submit(); + }); + }); + } + }, true); + this.on("submit", (e) => { + let phxEvent = e.target.getAttribute(this.binding("submit")); + if (!phxEvent) { + if (dom_default.isUnloadableFormSubmit(e)) { + this.unload(); + } + return; + } + e.preventDefault(); + e.target.disabled = true; + this.withinOwners(e.target, (view) => { + js_default.exec("submit", phxEvent, view, e.target, ["push", { submitter: e.submitter }]); + }); + }, false); + for (let type of ["change", "input"]) { + this.on(type, (e) => { + let phxChange = this.binding("change"); + let input = e.target; + let inputEvent = input.getAttribute(phxChange); + let formEvent = input.form && input.form.getAttribute(phxChange); + let phxEvent = inputEvent || formEvent; + if (!phxEvent) { + return; + } + if (input.type === "number" && input.validity && input.validity.badInput) { + return; + } + let dispatcher = inputEvent ? input : input.form; + let currentIterations = iterations; + iterations++; + let { at, type: lastType } = dom_default.private(input, "prev-iteration") || {}; + if (at === currentIterations - 1 && type === "change" && lastType === "input") { + return; + } + dom_default.putPrivate(input, "prev-iteration", { at: currentIterations, type }); + this.debounce(input, e, type, () => { + this.withinOwners(dispatcher, (view) => { + dom_default.putPrivate(input, PHX_HAS_FOCUSED, true); + if (!dom_default.isTextualInput(input)) { + this.setActiveElement(input); + } + js_default.exec("change", phxEvent, view, input, ["push", { _target: e.target.name, dispatcher }]); + }); + }); + }, false); + } + this.on("reset", (e) => { + let form = e.target; + dom_default.resetForm(form, this.binding(PHX_FEEDBACK_FOR)); + let input = Array.from(form.elements).find((el) => el.type === "reset"); + window.requestAnimationFrame(() => { + input.dispatchEvent(new Event("input", { bubbles: true, cancelable: false })); + }); + }); + } + debounce(el, event, eventType, callback) { + if (eventType === "blur" || eventType === "focusout") { + return callback(); + } + let phxDebounce = this.binding(PHX_DEBOUNCE); + let phxThrottle = this.binding(PHX_THROTTLE); + let defaultDebounce = this.defaults.debounce.toString(); + let defaultThrottle = this.defaults.throttle.toString(); + this.withinOwners(el, (view) => { + let asyncFilter = () => !view.isDestroyed() && document.body.contains(el); + dom_default.debounce(el, event, phxDebounce, defaultDebounce, phxThrottle, defaultThrottle, asyncFilter, () => { + callback(); + }); + }); + } + silenceEvents(callback) { + this.silenced = true; + callback(); + this.silenced = false; + } + on(event, callback) { + window.addEventListener(event, (e) => { + if (!this.silenced) { + callback(e); + } + }); + } + }; + var TransitionSet = class { + constructor() { + this.transitions = /* @__PURE__ */ new Set(); + this.pendingOps = []; + } + reset() { + this.transitions.forEach((timer) => { + clearTimeout(timer); + this.transitions.delete(timer); + }); + this.flushPendingOps(); + } + after(callback) { + if (this.size() === 0) { + callback(); + } else { + this.pushPendingOp(callback); + } + } + addTransition(time, onStart, onDone) { + onStart(); + let timer = setTimeout(() => { + this.transitions.delete(timer); + onDone(); + this.flushPendingOps(); + }, time); + this.transitions.add(timer); + } + pushPendingOp(op) { + this.pendingOps.push(op); + } + size() { + return this.transitions.size; + } + flushPendingOps() { + if (this.size() > 0) { + return; + } + let op = this.pendingOps.shift(); + if (op) { + op(); + this.flushPendingOps(); + } + } + }; + + // js/app.js + var import_topbar = __toESM(require_topbar()); + var csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content"); + var liveSocket = new LiveSocket("/live", Socket, { params: { _csrf_token: csrfToken } }); + import_topbar.default.config({ barColors: { 0: "#29d" }, shadowColor: "rgba(0, 0, 0, .3)" }); + window.addEventListener("phx:page-loading-start", (_info) => import_topbar.default.show(300)); + window.addEventListener("phx:page-loading-stop", (_info) => import_topbar.default.hide()); + liveSocket.connect(); + window.liveSocket = liveSocket; +})(); +/** + * @license MIT + * topbar 2.0.0, 2023-02-04 + * https://buunguyen.github.io/topbar + * Copyright (c) 2021 Buu Nguyen + */ +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vYXNzZXRzL3ZlbmRvci90b3BiYXIuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2h0bWwvcHJpdi9zdGF0aWMvcGhvZW5peF9odG1sLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peC9hc3NldHMvanMvcGhvZW5peC91dGlscy5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXgvYXNzZXRzL2pzL3Bob2VuaXgvY29uc3RhbnRzLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peC9hc3NldHMvanMvcGhvZW5peC9wdXNoLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peC9hc3NldHMvanMvcGhvZW5peC90aW1lci5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXgvYXNzZXRzL2pzL3Bob2VuaXgvY2hhbm5lbC5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXgvYXNzZXRzL2pzL3Bob2VuaXgvYWpheC5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXgvYXNzZXRzL2pzL3Bob2VuaXgvbG9uZ3BvbGwuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4L2Fzc2V0cy9qcy9waG9lbml4L3ByZXNlbmNlLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peC9hc3NldHMvanMvcGhvZW5peC9zZXJpYWxpemVyLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peC9hc3NldHMvanMvcGhvZW5peC9zb2NrZXQuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvanMvcGhvZW5peF9saXZlX3ZpZXcvY29uc3RhbnRzLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L2VudHJ5X3VwbG9hZGVyLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L3V0aWxzLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L2Jyb3dzZXIuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvanMvcGhvZW5peF9saXZlX3ZpZXcvZG9tLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L3VwbG9hZF9lbnRyeS5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy9saXZlX3VwbG9hZGVyLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L2FyaWEuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvanMvcGhvZW5peF9saXZlX3ZpZXcvaG9va3MuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvanMvcGhvZW5peF9saXZlX3ZpZXcvZG9tX3Bvc3RfbW9ycGhfcmVzdG9yZXIuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvbm9kZV9tb2R1bGVzL21vcnBoZG9tL2Rpc3QvbW9ycGhkb20tZXNtLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L2RvbV9wYXRjaC5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy9yZW5kZXJlZC5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy92aWV3X2hvb2suanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvanMvcGhvZW5peF9saXZlX3ZpZXcvanMuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvanMvcGhvZW5peF9saXZlX3ZpZXcvdmlldy5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy9saXZlX3NvY2tldC5qcyIsICIuLi8uLi8uLi9hc3NldHMvanMvYXBwLmpzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBsaWNlbnNlIE1JVFxuICogdG9wYmFyIDIuMC4wLCAyMDIzLTAyLTA0XG4gKiBodHRwczovL2J1dW5ndXllbi5naXRodWIuaW8vdG9wYmFyXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjEgQnV1IE5ndXllblxuICovXG4oZnVuY3Rpb24gKHdpbmRvdywgZG9jdW1lbnQpIHtcbiAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgLy8gaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vcGF1bGlyaXNoLzE1Nzk2NzFcbiAgKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbGFzdFRpbWUgPSAwO1xuICAgIHZhciB2ZW5kb3JzID0gW1wibXNcIiwgXCJtb3pcIiwgXCJ3ZWJraXRcIiwgXCJvXCJdO1xuICAgIGZvciAodmFyIHggPSAwOyB4IDwgdmVuZG9ycy5sZW5ndGggJiYgIXdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWU7ICsreCkge1xuICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSA9XG4gICAgICAgIHdpbmRvd1t2ZW5kb3JzW3hdICsgXCJSZXF1ZXN0QW5pbWF0aW9uRnJhbWVcIl07XG4gICAgICB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUgPVxuICAgICAgICB3aW5kb3dbdmVuZG9yc1t4XSArIFwiQ2FuY2VsQW5pbWF0aW9uRnJhbWVcIl0gfHxcbiAgICAgICAgd2luZG93W3ZlbmRvcnNbeF0gKyBcIkNhbmNlbFJlcXVlc3RBbmltYXRpb25GcmFtZVwiXTtcbiAgICB9XG4gICAgaWYgKCF3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKVxuICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSA9IGZ1bmN0aW9uIChjYWxsYmFjaywgZWxlbWVudCkge1xuICAgICAgICB2YXIgY3VyclRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAgICAgdmFyIHRpbWVUb0NhbGwgPSBNYXRoLm1heCgwLCAxNiAtIChjdXJyVGltZSAtIGxhc3RUaW1lKSk7XG4gICAgICAgIHZhciBpZCA9IHdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjYWxsYmFjayhjdXJyVGltZSArIHRpbWVUb0NhbGwpO1xuICAgICAgICB9LCB0aW1lVG9DYWxsKTtcbiAgICAgICAgbGFzdFRpbWUgPSBjdXJyVGltZSArIHRpbWVUb0NhbGw7XG4gICAgICAgIHJldHVybiBpZDtcbiAgICAgIH07XG4gICAgaWYgKCF3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUpXG4gICAgICB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KGlkKTtcbiAgICAgIH07XG4gIH0pKCk7XG5cbiAgdmFyIGNhbnZhcyxcbiAgICBjdXJyZW50UHJvZ3Jlc3MsXG4gICAgc2hvd2luZyxcbiAgICBwcm9ncmVzc1RpbWVySWQgPSBudWxsLFxuICAgIGZhZGVUaW1lcklkID0gbnVsbCxcbiAgICBkZWxheVRpbWVySWQgPSBudWxsLFxuICAgIGFkZEV2ZW50ID0gZnVuY3Rpb24gKGVsZW0sIHR5cGUsIGhhbmRsZXIpIHtcbiAgICAgIGlmIChlbGVtLmFkZEV2ZW50TGlzdGVuZXIpIGVsZW0uYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBoYW5kbGVyLCBmYWxzZSk7XG4gICAgICBlbHNlIGlmIChlbGVtLmF0dGFjaEV2ZW50KSBlbGVtLmF0dGFjaEV2ZW50KFwib25cIiArIHR5cGUsIGhhbmRsZXIpO1xuICAgICAgZWxzZSBlbGVtW1wib25cIiArIHR5cGVdID0gaGFuZGxlcjtcbiAgICB9LFxuICAgIG9wdGlvbnMgPSB7XG4gICAgICBhdXRvUnVuOiB0cnVlLFxuICAgICAgYmFyVGhpY2tuZXNzOiAzLFxuICAgICAgYmFyQ29sb3JzOiB7XG4gICAgICAgIDA6IFwicmdiYSgyNiwgIDE4OCwgMTU2LCAuOSlcIixcbiAgICAgICAgXCIuMjVcIjogXCJyZ2JhKDUyLCAgMTUyLCAyMTksIC45KVwiLFxuICAgICAgICBcIi41MFwiOiBcInJnYmEoMjQxLCAxOTYsIDE1LCAgLjkpXCIsXG4gICAgICAgIFwiLjc1XCI6IFwicmdiYSgyMzAsIDEyNiwgMzQsICAuOSlcIixcbiAgICAgICAgXCIxLjBcIjogXCJyZ2JhKDIxMSwgODQsICAwLCAgIC45KVwiLFxuICAgICAgfSxcbiAgICAgIHNoYWRvd0JsdXI6IDEwLFxuICAgICAgc2hhZG93Q29sb3I6IFwicmdiYSgwLCAgIDAsICAgMCwgICAuNilcIixcbiAgICAgIGNsYXNzTmFtZTogbnVsbCxcbiAgICB9LFxuICAgIHJlcGFpbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBjYW52YXMud2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgICAgIGNhbnZhcy5oZWlnaHQgPSBvcHRpb25zLmJhclRoaWNrbmVzcyAqIDU7IC8vIG5lZWQgc3BhY2UgZm9yIHNoYWRvd1xuXG4gICAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcbiAgICAgIGN0eC5zaGFkb3dCbHVyID0gb3B0aW9ucy5zaGFkb3dCbHVyO1xuICAgICAgY3R4LnNoYWRvd0NvbG9yID0gb3B0aW9ucy5zaGFkb3dDb2xvcjtcblxuICAgICAgdmFyIGxpbmVHcmFkaWVudCA9IGN0eC5jcmVhdGVMaW5lYXJHcmFkaWVudCgwLCAwLCBjYW52YXMud2lkdGgsIDApO1xuICAgICAgZm9yICh2YXIgc3RvcCBpbiBvcHRpb25zLmJhckNvbG9ycylcbiAgICAgICAgbGluZUdyYWRpZW50LmFkZENvbG9yU3RvcChzdG9wLCBvcHRpb25zLmJhckNvbG9yc1tzdG9wXSk7XG4gICAgICBjdHgubGluZVdpZHRoID0gb3B0aW9ucy5iYXJUaGlja25lc3M7XG4gICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICBjdHgubW92ZVRvKDAsIG9wdGlvbnMuYmFyVGhpY2tuZXNzIC8gMik7XG4gICAgICBjdHgubGluZVRvKFxuICAgICAgICBNYXRoLmNlaWwoY3VycmVudFByb2dyZXNzICogY2FudmFzLndpZHRoKSxcbiAgICAgICAgb3B0aW9ucy5iYXJUaGlja25lc3MgLyAyXG4gICAgICApO1xuICAgICAgY3R4LnN0cm9rZVN0eWxlID0gbGluZUdyYWRpZW50O1xuICAgICAgY3R4LnN0cm9rZSgpO1xuICAgIH0sXG4gICAgY3JlYXRlQ2FudmFzID0gZnVuY3Rpb24gKCkge1xuICAgICAgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICAgIHZhciBzdHlsZSA9IGNhbnZhcy5zdHlsZTtcbiAgICAgIHN0eWxlLnBvc2l0aW9uID0gXCJmaXhlZFwiO1xuICAgICAgc3R5bGUudG9wID0gc3R5bGUubGVmdCA9IHN0eWxlLnJpZ2h0ID0gc3R5bGUubWFyZ2luID0gc3R5bGUucGFkZGluZyA9IDA7XG4gICAgICBzdHlsZS56SW5kZXggPSAxMDAwMDE7XG4gICAgICBzdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XG4gICAgICBpZiAob3B0aW9ucy5jbGFzc05hbWUpIGNhbnZhcy5jbGFzc0xpc3QuYWRkKG9wdGlvbnMuY2xhc3NOYW1lKTtcbiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoY2FudmFzKTtcbiAgICAgIGFkZEV2ZW50KHdpbmRvdywgXCJyZXNpemVcIiwgcmVwYWludCk7XG4gICAgfSxcbiAgICB0b3BiYXIgPSB7XG4gICAgICBjb25maWc6IGZ1bmN0aW9uIChvcHRzKSB7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBvcHRzKVxuICAgICAgICAgIGlmIChvcHRpb25zLmhhc093blByb3BlcnR5KGtleSkpIG9wdGlvbnNba2V5XSA9IG9wdHNba2V5XTtcbiAgICAgIH0sXG4gICAgICBzaG93OiBmdW5jdGlvbiAoZGVsYXkpIHtcbiAgICAgICAgaWYgKHNob3dpbmcpIHJldHVybjtcbiAgICAgICAgaWYgKGRlbGF5KSB7XG4gICAgICAgICAgaWYgKGRlbGF5VGltZXJJZCkgcmV0dXJuO1xuICAgICAgICAgIGRlbGF5VGltZXJJZCA9IHNldFRpbWVvdXQoKCkgPT4gdG9wYmFyLnNob3coKSwgZGVsYXkpO1xuICAgICAgICB9IGVsc2UgIHtcbiAgICAgICAgICBzaG93aW5nID0gdHJ1ZTtcbiAgICAgICAgICBpZiAoZmFkZVRpbWVySWQgIT09IG51bGwpIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZShmYWRlVGltZXJJZCk7XG4gICAgICAgICAgaWYgKCFjYW52YXMpIGNyZWF0ZUNhbnZhcygpO1xuICAgICAgICAgIGNhbnZhcy5zdHlsZS5vcGFjaXR5ID0gMTtcbiAgICAgICAgICBjYW52YXMuc3R5bGUuZGlzcGxheSA9IFwiYmxvY2tcIjtcbiAgICAgICAgICB0b3BiYXIucHJvZ3Jlc3MoMCk7XG4gICAgICAgICAgaWYgKG9wdGlvbnMuYXV0b1J1bikge1xuICAgICAgICAgICAgKGZ1bmN0aW9uIGxvb3AoKSB7XG4gICAgICAgICAgICAgIHByb2dyZXNzVGltZXJJZCA9IHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUobG9vcCk7XG4gICAgICAgICAgICAgIHRvcGJhci5wcm9ncmVzcyhcbiAgICAgICAgICAgICAgICBcIitcIiArIDAuMDUgKiBNYXRoLnBvdygxIC0gTWF0aC5zcXJ0KGN1cnJlbnRQcm9ncmVzcyksIDIpXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHByb2dyZXNzOiBmdW5jdGlvbiAodG8pIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0byA9PT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIGN1cnJlbnRQcm9ncmVzcztcbiAgICAgICAgaWYgKHR5cGVvZiB0byA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgIHRvID1cbiAgICAgICAgICAgICh0by5pbmRleE9mKFwiK1wiKSA+PSAwIHx8IHRvLmluZGV4T2YoXCItXCIpID49IDBcbiAgICAgICAgICAgICAgPyBjdXJyZW50UHJvZ3Jlc3NcbiAgICAgICAgICAgICAgOiAwKSArIHBhcnNlRmxvYXQodG8pO1xuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnRQcm9ncmVzcyA9IHRvID4gMSA/IDEgOiB0bztcbiAgICAgICAgcmVwYWludCgpO1xuICAgICAgICByZXR1cm4gY3VycmVudFByb2dyZXNzO1xuICAgICAgfSxcbiAgICAgIGhpZGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KGRlbGF5VGltZXJJZCk7XG4gICAgICAgIGRlbGF5VGltZXJJZCA9IG51bGw7XG4gICAgICAgIGlmICghc2hvd2luZykgcmV0dXJuO1xuICAgICAgICBzaG93aW5nID0gZmFsc2U7XG4gICAgICAgIGlmIChwcm9ncmVzc1RpbWVySWQgIT0gbnVsbCkge1xuICAgICAgICAgIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZShwcm9ncmVzc1RpbWVySWQpO1xuICAgICAgICAgIHByb2dyZXNzVGltZXJJZCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgKGZ1bmN0aW9uIGxvb3AoKSB7XG4gICAgICAgICAgaWYgKHRvcGJhci5wcm9ncmVzcyhcIisuMVwiKSA+PSAxKSB7XG4gICAgICAgICAgICBjYW52YXMuc3R5bGUub3BhY2l0eSAtPSAwLjA1O1xuICAgICAgICAgICAgaWYgKGNhbnZhcy5zdHlsZS5vcGFjaXR5IDw9IDAuMDUpIHtcbiAgICAgICAgICAgICAgY2FudmFzLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcbiAgICAgICAgICAgICAgZmFkZVRpbWVySWQgPSBudWxsO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGZhZGVUaW1lcklkID0gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZShsb29wKTtcbiAgICAgICAgfSkoKTtcbiAgICAgIH0sXG4gICAgfTtcblxuICBpZiAodHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgbW9kdWxlLmV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IHRvcGJhcjtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuICAgIGRlZmluZShmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gdG9wYmFyO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHRoaXMudG9wYmFyID0gdG9wYmFyO1xuICB9XG59LmNhbGwodGhpcywgd2luZG93LCBkb2N1bWVudCkpO1xuIiwgIlwidXNlIHN0cmljdFwiO1xuXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBQb2x5ZmlsbEV2ZW50ID0gZXZlbnRDb25zdHJ1Y3RvcigpO1xuXG4gIGZ1bmN0aW9uIGV2ZW50Q29uc3RydWN0b3IoKSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cuQ3VzdG9tRXZlbnQgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHdpbmRvdy5DdXN0b21FdmVudDtcbiAgICAvLyBJRTw9OSBTdXBwb3J0XG4gICAgZnVuY3Rpb24gQ3VzdG9tRXZlbnQoZXZlbnQsIHBhcmFtcykge1xuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHtidWJibGVzOiBmYWxzZSwgY2FuY2VsYWJsZTogZmFsc2UsIGRldGFpbDogdW5kZWZpbmVkfTtcbiAgICAgIHZhciBldnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnQ3VzdG9tRXZlbnQnKTtcbiAgICAgIGV2dC5pbml0Q3VzdG9tRXZlbnQoZXZlbnQsIHBhcmFtcy5idWJibGVzLCBwYXJhbXMuY2FuY2VsYWJsZSwgcGFyYW1zLmRldGFpbCk7XG4gICAgICByZXR1cm4gZXZ0O1xuICAgIH1cbiAgICBDdXN0b21FdmVudC5wcm90b3R5cGUgPSB3aW5kb3cuRXZlbnQucHJvdG90eXBlO1xuICAgIHJldHVybiBDdXN0b21FdmVudDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGJ1aWxkSGlkZGVuSW5wdXQobmFtZSwgdmFsdWUpIHtcbiAgICB2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIik7XG4gICAgaW5wdXQudHlwZSA9IFwiaGlkZGVuXCI7XG4gICAgaW5wdXQubmFtZSA9IG5hbWU7XG4gICAgaW5wdXQudmFsdWUgPSB2YWx1ZTtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVDbGljayhlbGVtZW50LCB0YXJnZXRNb2RpZmllcktleSkge1xuICAgIHZhciB0byA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGF0YS10b1wiKSxcbiAgICAgICAgbWV0aG9kID0gYnVpbGRIaWRkZW5JbnB1dChcIl9tZXRob2RcIiwgZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJkYXRhLW1ldGhvZFwiKSksXG4gICAgICAgIGNzcmYgPSBidWlsZEhpZGRlbklucHV0KFwiX2NzcmZfdG9rZW5cIiwgZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJkYXRhLWNzcmZcIikpLFxuICAgICAgICBmb3JtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImZvcm1cIiksXG4gICAgICAgIHN1Ym1pdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbnB1dFwiKSxcbiAgICAgICAgdGFyZ2V0ID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJ0YXJnZXRcIik7XG5cbiAgICBmb3JtLm1ldGhvZCA9IChlbGVtZW50LmdldEF0dHJpYnV0ZShcImRhdGEtbWV0aG9kXCIpID09PSBcImdldFwiKSA/IFwiZ2V0XCIgOiBcInBvc3RcIjtcbiAgICBmb3JtLmFjdGlvbiA9IHRvO1xuICAgIGZvcm0uc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuXG4gICAgaWYgKHRhcmdldCkgZm9ybS50YXJnZXQgPSB0YXJnZXQ7XG4gICAgZWxzZSBpZiAodGFyZ2V0TW9kaWZpZXJLZXkpIGZvcm0udGFyZ2V0ID0gXCJfYmxhbmtcIjtcblxuICAgIGZvcm0uYXBwZW5kQ2hpbGQoY3NyZik7XG4gICAgZm9ybS5hcHBlbmRDaGlsZChtZXRob2QpO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZm9ybSk7XG5cbiAgICAvLyBJbnNlcnQgYSBidXR0b24gYW5kIGNsaWNrIGl0IGluc3RlYWQgb2YgdXNpbmcgYGZvcm0uc3VibWl0YFxuICAgIC8vIGJlY2F1c2UgdGhlIGBzdWJtaXRgIGZ1bmN0aW9uIGRvZXMgbm90IGVtaXQgYSBgc3VibWl0YCBldmVudC5cbiAgICBzdWJtaXQudHlwZSA9IFwic3VibWl0XCI7XG4gICAgZm9ybS5hcHBlbmRDaGlsZChzdWJtaXQpO1xuICAgIHN1Ym1pdC5jbGljaygpO1xuICB9XG5cbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBmdW5jdGlvbihlKSB7XG4gICAgdmFyIGVsZW1lbnQgPSBlLnRhcmdldDtcbiAgICBpZiAoZS5kZWZhdWx0UHJldmVudGVkKSByZXR1cm47XG5cbiAgICB3aGlsZSAoZWxlbWVudCAmJiBlbGVtZW50LmdldEF0dHJpYnV0ZSkge1xuICAgICAgdmFyIHBob2VuaXhMaW5rRXZlbnQgPSBuZXcgUG9seWZpbGxFdmVudCgncGhvZW5peC5saW5rLmNsaWNrJywge1xuICAgICAgICBcImJ1YmJsZXNcIjogdHJ1ZSwgXCJjYW5jZWxhYmxlXCI6IHRydWVcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoIWVsZW1lbnQuZGlzcGF0Y2hFdmVudChwaG9lbml4TGlua0V2ZW50KSkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGF0YS1tZXRob2RcIikpIHtcbiAgICAgICAgaGFuZGxlQ2xpY2soZWxlbWVudCwgZS5tZXRhS2V5IHx8IGUuc2hpZnRLZXkpO1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudE5vZGU7XG4gICAgICB9XG4gICAgfVxuICB9LCBmYWxzZSk7XG5cbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Bob2VuaXgubGluay5jbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgdmFyIG1lc3NhZ2UgPSBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoXCJkYXRhLWNvbmZpcm1cIik7XG4gICAgaWYobWVzc2FnZSAmJiAhd2luZG93LmNvbmZpcm0obWVzc2FnZSkpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gIH0sIGZhbHNlKTtcbn0pKCk7XG4iLCAiLy8gd3JhcHMgdmFsdWUgaW4gY2xvc3VyZSBvciByZXR1cm5zIGNsb3N1cmVcbmV4cG9ydCBsZXQgY2xvc3VyZSA9ICh2YWx1ZSkgPT4ge1xuICBpZih0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIil7XG4gICAgcmV0dXJuIHZhbHVlXG4gIH0gZWxzZSB7XG4gICAgbGV0IGNsb3N1cmUgPSBmdW5jdGlvbiAoKXsgcmV0dXJuIHZhbHVlIH1cbiAgICByZXR1cm4gY2xvc3VyZVxuICB9XG59XG4iLCAiZXhwb3J0IGNvbnN0IGdsb2JhbFNlbGYgPSB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiBudWxsXG5leHBvcnQgY29uc3QgcGh4V2luZG93ID0gdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IG51bGxcbmV4cG9ydCBjb25zdCBnbG9iYWwgPSBnbG9iYWxTZWxmIHx8IHBoeFdpbmRvdyB8fCBnbG9iYWxcbmV4cG9ydCBjb25zdCBERUZBVUxUX1ZTTiA9IFwiMi4wLjBcIlxuZXhwb3J0IGNvbnN0IFNPQ0tFVF9TVEFURVMgPSB7Y29ubmVjdGluZzogMCwgb3BlbjogMSwgY2xvc2luZzogMiwgY2xvc2VkOiAzfVxuZXhwb3J0IGNvbnN0IERFRkFVTFRfVElNRU9VVCA9IDEwMDAwXG5leHBvcnQgY29uc3QgV1NfQ0xPU0VfTk9STUFMID0gMTAwMFxuZXhwb3J0IGNvbnN0IENIQU5ORUxfU1RBVEVTID0ge1xuICBjbG9zZWQ6IFwiY2xvc2VkXCIsXG4gIGVycm9yZWQ6IFwiZXJyb3JlZFwiLFxuICBqb2luZWQ6IFwiam9pbmVkXCIsXG4gIGpvaW5pbmc6IFwiam9pbmluZ1wiLFxuICBsZWF2aW5nOiBcImxlYXZpbmdcIixcbn1cbmV4cG9ydCBjb25zdCBDSEFOTkVMX0VWRU5UUyA9IHtcbiAgY2xvc2U6IFwicGh4X2Nsb3NlXCIsXG4gIGVycm9yOiBcInBoeF9lcnJvclwiLFxuICBqb2luOiBcInBoeF9qb2luXCIsXG4gIHJlcGx5OiBcInBoeF9yZXBseVwiLFxuICBsZWF2ZTogXCJwaHhfbGVhdmVcIlxufVxuXG5leHBvcnQgY29uc3QgVFJBTlNQT1JUUyA9IHtcbiAgbG9uZ3BvbGw6IFwibG9uZ3BvbGxcIixcbiAgd2Vic29ja2V0OiBcIndlYnNvY2tldFwiXG59XG5leHBvcnQgY29uc3QgWEhSX1NUQVRFUyA9IHtcbiAgY29tcGxldGU6IDRcbn1cbiIsICIvKipcbiAqIEluaXRpYWxpemVzIHRoZSBQdXNoXG4gKiBAcGFyYW0ge0NoYW5uZWx9IGNoYW5uZWwgLSBUaGUgQ2hhbm5lbFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50IC0gVGhlIGV2ZW50LCBmb3IgZXhhbXBsZSBgXCJwaHhfam9pblwiYFxuICogQHBhcmFtIHtPYmplY3R9IHBheWxvYWQgLSBUaGUgcGF5bG9hZCwgZm9yIGV4YW1wbGUgYHt1c2VyX2lkOiAxMjN9YFxuICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXQgLSBUaGUgcHVzaCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kc1xuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQdXNoIHtcbiAgY29uc3RydWN0b3IoY2hhbm5lbCwgZXZlbnQsIHBheWxvYWQsIHRpbWVvdXQpe1xuICAgIHRoaXMuY2hhbm5lbCA9IGNoYW5uZWxcbiAgICB0aGlzLmV2ZW50ID0gZXZlbnRcbiAgICB0aGlzLnBheWxvYWQgPSBwYXlsb2FkIHx8IGZ1bmN0aW9uICgpeyByZXR1cm4ge30gfVxuICAgIHRoaXMucmVjZWl2ZWRSZXNwID0gbnVsbFxuICAgIHRoaXMudGltZW91dCA9IHRpbWVvdXRcbiAgICB0aGlzLnRpbWVvdXRUaW1lciA9IG51bGxcbiAgICB0aGlzLnJlY0hvb2tzID0gW11cbiAgICB0aGlzLnNlbnQgPSBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lb3V0XG4gICAqL1xuICByZXNlbmQodGltZW91dCl7XG4gICAgdGhpcy50aW1lb3V0ID0gdGltZW91dFxuICAgIHRoaXMucmVzZXQoKVxuICAgIHRoaXMuc2VuZCgpXG4gIH1cblxuICAvKipcbiAgICpcbiAgICovXG4gIHNlbmQoKXtcbiAgICBpZih0aGlzLmhhc1JlY2VpdmVkKFwidGltZW91dFwiKSl7IHJldHVybiB9XG4gICAgdGhpcy5zdGFydFRpbWVvdXQoKVxuICAgIHRoaXMuc2VudCA9IHRydWVcbiAgICB0aGlzLmNoYW5uZWwuc29ja2V0LnB1c2goe1xuICAgICAgdG9waWM6IHRoaXMuY2hhbm5lbC50b3BpYyxcbiAgICAgIGV2ZW50OiB0aGlzLmV2ZW50LFxuICAgICAgcGF5bG9hZDogdGhpcy5wYXlsb2FkKCksXG4gICAgICByZWY6IHRoaXMucmVmLFxuICAgICAgam9pbl9yZWY6IHRoaXMuY2hhbm5lbC5qb2luUmVmKClcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSB7Kn0gc3RhdHVzXG4gICAqIEBwYXJhbSB7Kn0gY2FsbGJhY2tcbiAgICovXG4gIHJlY2VpdmUoc3RhdHVzLCBjYWxsYmFjayl7XG4gICAgaWYodGhpcy5oYXNSZWNlaXZlZChzdGF0dXMpKXtcbiAgICAgIGNhbGxiYWNrKHRoaXMucmVjZWl2ZWRSZXNwLnJlc3BvbnNlKVxuICAgIH1cblxuICAgIHRoaXMucmVjSG9va3MucHVzaCh7c3RhdHVzLCBjYWxsYmFja30pXG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcmVzZXQoKXtcbiAgICB0aGlzLmNhbmNlbFJlZkV2ZW50KClcbiAgICB0aGlzLnJlZiA9IG51bGxcbiAgICB0aGlzLnJlZkV2ZW50ID0gbnVsbFxuICAgIHRoaXMucmVjZWl2ZWRSZXNwID0gbnVsbFxuICAgIHRoaXMuc2VudCA9IGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIG1hdGNoUmVjZWl2ZSh7c3RhdHVzLCByZXNwb25zZSwgX3JlZn0pe1xuICAgIHRoaXMucmVjSG9va3MuZmlsdGVyKGggPT4gaC5zdGF0dXMgPT09IHN0YXR1cylcbiAgICAgIC5mb3JFYWNoKGggPT4gaC5jYWxsYmFjayhyZXNwb25zZSkpXG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGNhbmNlbFJlZkV2ZW50KCl7XG4gICAgaWYoIXRoaXMucmVmRXZlbnQpeyByZXR1cm4gfVxuICAgIHRoaXMuY2hhbm5lbC5vZmYodGhpcy5yZWZFdmVudClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgY2FuY2VsVGltZW91dCgpe1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVvdXRUaW1lcilcbiAgICB0aGlzLnRpbWVvdXRUaW1lciA9IG51bGxcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgc3RhcnRUaW1lb3V0KCl7XG4gICAgaWYodGhpcy50aW1lb3V0VGltZXIpeyB0aGlzLmNhbmNlbFRpbWVvdXQoKSB9XG4gICAgdGhpcy5yZWYgPSB0aGlzLmNoYW5uZWwuc29ja2V0Lm1ha2VSZWYoKVxuICAgIHRoaXMucmVmRXZlbnQgPSB0aGlzLmNoYW5uZWwucmVwbHlFdmVudE5hbWUodGhpcy5yZWYpXG5cbiAgICB0aGlzLmNoYW5uZWwub24odGhpcy5yZWZFdmVudCwgcGF5bG9hZCA9PiB7XG4gICAgICB0aGlzLmNhbmNlbFJlZkV2ZW50KClcbiAgICAgIHRoaXMuY2FuY2VsVGltZW91dCgpXG4gICAgICB0aGlzLnJlY2VpdmVkUmVzcCA9IHBheWxvYWRcbiAgICAgIHRoaXMubWF0Y2hSZWNlaXZlKHBheWxvYWQpXG4gICAgfSlcblxuICAgIHRoaXMudGltZW91dFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnRyaWdnZXIoXCJ0aW1lb3V0XCIsIHt9KVxuICAgIH0sIHRoaXMudGltZW91dClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgaGFzUmVjZWl2ZWQoc3RhdHVzKXtcbiAgICByZXR1cm4gdGhpcy5yZWNlaXZlZFJlc3AgJiYgdGhpcy5yZWNlaXZlZFJlc3Auc3RhdHVzID09PSBzdGF0dXNcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgdHJpZ2dlcihzdGF0dXMsIHJlc3BvbnNlKXtcbiAgICB0aGlzLmNoYW5uZWwudHJpZ2dlcih0aGlzLnJlZkV2ZW50LCB7c3RhdHVzLCByZXNwb25zZX0pXG4gIH1cbn1cbiIsICIvKipcbiAqXG4gKiBDcmVhdGVzIGEgdGltZXIgdGhhdCBhY2NlcHRzIGEgYHRpbWVyQ2FsY2AgZnVuY3Rpb24gdG8gcGVyZm9ybVxuICogY2FsY3VsYXRlZCB0aW1lb3V0IHJldHJpZXMsIHN1Y2ggYXMgZXhwb25lbnRpYWwgYmFja29mZi5cbiAqXG4gKiBAZXhhbXBsZVxuICogbGV0IHJlY29ubmVjdFRpbWVyID0gbmV3IFRpbWVyKCgpID0+IHRoaXMuY29ubmVjdCgpLCBmdW5jdGlvbih0cmllcyl7XG4gKiAgIHJldHVybiBbMTAwMCwgNTAwMCwgMTAwMDBdW3RyaWVzIC0gMV0gfHwgMTAwMDBcbiAqIH0pXG4gKiByZWNvbm5lY3RUaW1lci5zY2hlZHVsZVRpbWVvdXQoKSAvLyBmaXJlcyBhZnRlciAxMDAwXG4gKiByZWNvbm5lY3RUaW1lci5zY2hlZHVsZVRpbWVvdXQoKSAvLyBmaXJlcyBhZnRlciA1MDAwXG4gKiByZWNvbm5lY3RUaW1lci5yZXNldCgpXG4gKiByZWNvbm5lY3RUaW1lci5zY2hlZHVsZVRpbWVvdXQoKSAvLyBmaXJlcyBhZnRlciAxMDAwXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHRpbWVyQ2FsY1xuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUaW1lciB7XG4gIGNvbnN0cnVjdG9yKGNhbGxiYWNrLCB0aW1lckNhbGMpe1xuICAgIHRoaXMuY2FsbGJhY2sgPSBjYWxsYmFja1xuICAgIHRoaXMudGltZXJDYWxjID0gdGltZXJDYWxjXG4gICAgdGhpcy50aW1lciA9IG51bGxcbiAgICB0aGlzLnRyaWVzID0gMFxuICB9XG5cbiAgcmVzZXQoKXtcbiAgICB0aGlzLnRyaWVzID0gMFxuICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVyKVxuICB9XG5cbiAgLyoqXG4gICAqIENhbmNlbHMgYW55IHByZXZpb3VzIHNjaGVkdWxlVGltZW91dCBhbmQgc2NoZWR1bGVzIGNhbGxiYWNrXG4gICAqL1xuICBzY2hlZHVsZVRpbWVvdXQoKXtcbiAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lcilcblxuICAgIHRoaXMudGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMudHJpZXMgPSB0aGlzLnRyaWVzICsgMVxuICAgICAgdGhpcy5jYWxsYmFjaygpXG4gICAgfSwgdGhpcy50aW1lckNhbGModGhpcy50cmllcyArIDEpKVxuICB9XG59XG4iLCAiaW1wb3J0IHtjbG9zdXJlfSBmcm9tIFwiLi91dGlsc1wiXG5pbXBvcnQge1xuICBDSEFOTkVMX0VWRU5UUyxcbiAgQ0hBTk5FTF9TVEFURVMsXG59IGZyb20gXCIuL2NvbnN0YW50c1wiXG5cbmltcG9ydCBQdXNoIGZyb20gXCIuL3B1c2hcIlxuaW1wb3J0IFRpbWVyIGZyb20gXCIuL3RpbWVyXCJcblxuLyoqXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRvcGljXG4gKiBAcGFyYW0geyhPYmplY3R8ZnVuY3Rpb24pfSBwYXJhbXNcbiAqIEBwYXJhbSB7U29ja2V0fSBzb2NrZXRcbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ2hhbm5lbCB7XG4gIGNvbnN0cnVjdG9yKHRvcGljLCBwYXJhbXMsIHNvY2tldCl7XG4gICAgdGhpcy5zdGF0ZSA9IENIQU5ORUxfU1RBVEVTLmNsb3NlZFxuICAgIHRoaXMudG9waWMgPSB0b3BpY1xuICAgIHRoaXMucGFyYW1zID0gY2xvc3VyZShwYXJhbXMgfHwge30pXG4gICAgdGhpcy5zb2NrZXQgPSBzb2NrZXRcbiAgICB0aGlzLmJpbmRpbmdzID0gW11cbiAgICB0aGlzLmJpbmRpbmdSZWYgPSAwXG4gICAgdGhpcy50aW1lb3V0ID0gdGhpcy5zb2NrZXQudGltZW91dFxuICAgIHRoaXMuam9pbmVkT25jZSA9IGZhbHNlXG4gICAgdGhpcy5qb2luUHVzaCA9IG5ldyBQdXNoKHRoaXMsIENIQU5ORUxfRVZFTlRTLmpvaW4sIHRoaXMucGFyYW1zLCB0aGlzLnRpbWVvdXQpXG4gICAgdGhpcy5wdXNoQnVmZmVyID0gW11cbiAgICB0aGlzLnN0YXRlQ2hhbmdlUmVmcyA9IFtdXG5cbiAgICB0aGlzLnJlam9pblRpbWVyID0gbmV3IFRpbWVyKCgpID0+IHtcbiAgICAgIGlmKHRoaXMuc29ja2V0LmlzQ29ubmVjdGVkKCkpeyB0aGlzLnJlam9pbigpIH1cbiAgICB9LCB0aGlzLnNvY2tldC5yZWpvaW5BZnRlck1zKVxuICAgIHRoaXMuc3RhdGVDaGFuZ2VSZWZzLnB1c2godGhpcy5zb2NrZXQub25FcnJvcigoKSA9PiB0aGlzLnJlam9pblRpbWVyLnJlc2V0KCkpKVxuICAgIHRoaXMuc3RhdGVDaGFuZ2VSZWZzLnB1c2godGhpcy5zb2NrZXQub25PcGVuKCgpID0+IHtcbiAgICAgIHRoaXMucmVqb2luVGltZXIucmVzZXQoKVxuICAgICAgaWYodGhpcy5pc0Vycm9yZWQoKSl7IHRoaXMucmVqb2luKCkgfVxuICAgIH0pXG4gICAgKVxuICAgIHRoaXMuam9pblB1c2gucmVjZWl2ZShcIm9rXCIsICgpID0+IHtcbiAgICAgIHRoaXMuc3RhdGUgPSBDSEFOTkVMX1NUQVRFUy5qb2luZWRcbiAgICAgIHRoaXMucmVqb2luVGltZXIucmVzZXQoKVxuICAgICAgdGhpcy5wdXNoQnVmZmVyLmZvckVhY2gocHVzaEV2ZW50ID0+IHB1c2hFdmVudC5zZW5kKCkpXG4gICAgICB0aGlzLnB1c2hCdWZmZXIgPSBbXVxuICAgIH0pXG4gICAgdGhpcy5qb2luUHVzaC5yZWNlaXZlKFwiZXJyb3JcIiwgKCkgPT4ge1xuICAgICAgdGhpcy5zdGF0ZSA9IENIQU5ORUxfU1RBVEVTLmVycm9yZWRcbiAgICAgIGlmKHRoaXMuc29ja2V0LmlzQ29ubmVjdGVkKCkpeyB0aGlzLnJlam9pblRpbWVyLnNjaGVkdWxlVGltZW91dCgpIH1cbiAgICB9KVxuICAgIHRoaXMub25DbG9zZSgoKSA9PiB7XG4gICAgICB0aGlzLnJlam9pblRpbWVyLnJlc2V0KClcbiAgICAgIGlmKHRoaXMuc29ja2V0Lmhhc0xvZ2dlcigpKSB0aGlzLnNvY2tldC5sb2coXCJjaGFubmVsXCIsIGBjbG9zZSAke3RoaXMudG9waWN9ICR7dGhpcy5qb2luUmVmKCl9YClcbiAgICAgIHRoaXMuc3RhdGUgPSBDSEFOTkVMX1NUQVRFUy5jbG9zZWRcbiAgICAgIHRoaXMuc29ja2V0LnJlbW92ZSh0aGlzKVxuICAgIH0pXG4gICAgdGhpcy5vbkVycm9yKHJlYXNvbiA9PiB7XG4gICAgICBpZih0aGlzLnNvY2tldC5oYXNMb2dnZXIoKSkgdGhpcy5zb2NrZXQubG9nKFwiY2hhbm5lbFwiLCBgZXJyb3IgJHt0aGlzLnRvcGljfWAsIHJlYXNvbilcbiAgICAgIGlmKHRoaXMuaXNKb2luaW5nKCkpeyB0aGlzLmpvaW5QdXNoLnJlc2V0KCkgfVxuICAgICAgdGhpcy5zdGF0ZSA9IENIQU5ORUxfU1RBVEVTLmVycm9yZWRcbiAgICAgIGlmKHRoaXMuc29ja2V0LmlzQ29ubmVjdGVkKCkpeyB0aGlzLnJlam9pblRpbWVyLnNjaGVkdWxlVGltZW91dCgpIH1cbiAgICB9KVxuICAgIHRoaXMuam9pblB1c2gucmVjZWl2ZShcInRpbWVvdXRcIiwgKCkgPT4ge1xuICAgICAgaWYodGhpcy5zb2NrZXQuaGFzTG9nZ2VyKCkpIHRoaXMuc29ja2V0LmxvZyhcImNoYW5uZWxcIiwgYHRpbWVvdXQgJHt0aGlzLnRvcGljfSAoJHt0aGlzLmpvaW5SZWYoKX0pYCwgdGhpcy5qb2luUHVzaC50aW1lb3V0KVxuICAgICAgbGV0IGxlYXZlUHVzaCA9IG5ldyBQdXNoKHRoaXMsIENIQU5ORUxfRVZFTlRTLmxlYXZlLCBjbG9zdXJlKHt9KSwgdGhpcy50aW1lb3V0KVxuICAgICAgbGVhdmVQdXNoLnNlbmQoKVxuICAgICAgdGhpcy5zdGF0ZSA9IENIQU5ORUxfU1RBVEVTLmVycm9yZWRcbiAgICAgIHRoaXMuam9pblB1c2gucmVzZXQoKVxuICAgICAgaWYodGhpcy5zb2NrZXQuaXNDb25uZWN0ZWQoKSl7IHRoaXMucmVqb2luVGltZXIuc2NoZWR1bGVUaW1lb3V0KCkgfVxuICAgIH0pXG4gICAgdGhpcy5vbihDSEFOTkVMX0VWRU5UUy5yZXBseSwgKHBheWxvYWQsIHJlZikgPT4ge1xuICAgICAgdGhpcy50cmlnZ2VyKHRoaXMucmVwbHlFdmVudE5hbWUocmVmKSwgcGF5bG9hZClcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIEpvaW4gdGhlIGNoYW5uZWxcbiAgICogQHBhcmFtIHtpbnRlZ2VyfSB0aW1lb3V0XG4gICAqIEByZXR1cm5zIHtQdXNofVxuICAgKi9cbiAgam9pbih0aW1lb3V0ID0gdGhpcy50aW1lb3V0KXtcbiAgICBpZih0aGlzLmpvaW5lZE9uY2Upe1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwidHJpZWQgdG8gam9pbiBtdWx0aXBsZSB0aW1lcy4gJ2pvaW4nIGNhbiBvbmx5IGJlIGNhbGxlZCBhIHNpbmdsZSB0aW1lIHBlciBjaGFubmVsIGluc3RhbmNlXCIpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGltZW91dCA9IHRpbWVvdXRcbiAgICAgIHRoaXMuam9pbmVkT25jZSA9IHRydWVcbiAgICAgIHRoaXMucmVqb2luKClcbiAgICAgIHJldHVybiB0aGlzLmpvaW5QdXNoXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEhvb2sgaW50byBjaGFubmVsIGNsb3NlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBvbkNsb3NlKGNhbGxiYWNrKXtcbiAgICB0aGlzLm9uKENIQU5ORUxfRVZFTlRTLmNsb3NlLCBjYWxsYmFjaylcbiAgfVxuXG4gIC8qKlxuICAgKiBIb29rIGludG8gY2hhbm5lbCBlcnJvcnNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIG9uRXJyb3IoY2FsbGJhY2spe1xuICAgIHJldHVybiB0aGlzLm9uKENIQU5ORUxfRVZFTlRTLmVycm9yLCByZWFzb24gPT4gY2FsbGJhY2socmVhc29uKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWJzY3JpYmVzIG9uIGNoYW5uZWwgZXZlbnRzXG4gICAqXG4gICAqIFN1YnNjcmlwdGlvbiByZXR1cm5zIGEgcmVmIGNvdW50ZXIsIHdoaWNoIGNhbiBiZSB1c2VkIGxhdGVyIHRvXG4gICAqIHVuc3Vic2NyaWJlIHRoZSBleGFjdCBldmVudCBsaXN0ZW5lclxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBjb25zdCByZWYxID0gY2hhbm5lbC5vbihcImV2ZW50XCIsIGRvX3N0dWZmKVxuICAgKiBjb25zdCByZWYyID0gY2hhbm5lbC5vbihcImV2ZW50XCIsIGRvX290aGVyX3N0dWZmKVxuICAgKiBjaGFubmVsLm9mZihcImV2ZW50XCIsIHJlZjEpXG4gICAqIC8vIFNpbmNlIHVuc3Vic2NyaXB0aW9uLCBkb19zdHVmZiB3b24ndCBmaXJlLFxuICAgKiAvLyB3aGlsZSBkb19vdGhlcl9zdHVmZiB3aWxsIGtlZXAgZmlyaW5nIG9uIHRoZSBcImV2ZW50XCJcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqIEByZXR1cm5zIHtpbnRlZ2VyfSByZWZcbiAgICovXG4gIG9uKGV2ZW50LCBjYWxsYmFjayl7XG4gICAgbGV0IHJlZiA9IHRoaXMuYmluZGluZ1JlZisrXG4gICAgdGhpcy5iaW5kaW5ncy5wdXNoKHtldmVudCwgcmVmLCBjYWxsYmFja30pXG4gICAgcmV0dXJuIHJlZlxuICB9XG5cbiAgLyoqXG4gICAqIFVuc3Vic2NyaWJlcyBvZmYgb2YgY2hhbm5lbCBldmVudHNcbiAgICpcbiAgICogVXNlIHRoZSByZWYgcmV0dXJuZWQgZnJvbSBhIGNoYW5uZWwub24oKSB0byB1bnN1YnNjcmliZSBvbmVcbiAgICogaGFuZGxlciwgb3IgcGFzcyBub3RoaW5nIGZvciB0aGUgcmVmIHRvIHVuc3Vic2NyaWJlIGFsbFxuICAgKiBoYW5kbGVycyBmb3IgdGhlIGdpdmVuIGV2ZW50LlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiAvLyBVbnN1YnNjcmliZSB0aGUgZG9fc3R1ZmYgaGFuZGxlclxuICAgKiBjb25zdCByZWYxID0gY2hhbm5lbC5vbihcImV2ZW50XCIsIGRvX3N0dWZmKVxuICAgKiBjaGFubmVsLm9mZihcImV2ZW50XCIsIHJlZjEpXG4gICAqXG4gICAqIC8vIFVuc3Vic2NyaWJlIGFsbCBoYW5kbGVycyBmcm9tIGV2ZW50XG4gICAqIGNoYW5uZWwub2ZmKFwiZXZlbnRcIilcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG4gICAqIEBwYXJhbSB7aW50ZWdlcn0gcmVmXG4gICAqL1xuICBvZmYoZXZlbnQsIHJlZil7XG4gICAgdGhpcy5iaW5kaW5ncyA9IHRoaXMuYmluZGluZ3MuZmlsdGVyKChiaW5kKSA9PiB7XG4gICAgICByZXR1cm4gIShiaW5kLmV2ZW50ID09PSBldmVudCAmJiAodHlwZW9mIHJlZiA9PT0gXCJ1bmRlZmluZWRcIiB8fCByZWYgPT09IGJpbmQucmVmKSlcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBjYW5QdXNoKCl7IHJldHVybiB0aGlzLnNvY2tldC5pc0Nvbm5lY3RlZCgpICYmIHRoaXMuaXNKb2luZWQoKSB9XG5cbiAgLyoqXG4gICAqIFNlbmRzIGEgbWVzc2FnZSBgZXZlbnRgIHRvIHBob2VuaXggd2l0aCB0aGUgcGF5bG9hZCBgcGF5bG9hZGAuXG4gICAqIFBob2VuaXggcmVjZWl2ZXMgdGhpcyBpbiB0aGUgYGhhbmRsZV9pbihldmVudCwgcGF5bG9hZCwgc29ja2V0KWBcbiAgICogZnVuY3Rpb24uIGlmIHBob2VuaXggcmVwbGllcyBvciBpdCB0aW1lcyBvdXQgKGRlZmF1bHQgMTAwMDBtcyksXG4gICAqIHRoZW4gb3B0aW9uYWxseSB0aGUgcmVwbHkgY2FuIGJlIHJlY2VpdmVkLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBjaGFubmVsLnB1c2goXCJldmVudFwiKVxuICAgKiAgIC5yZWNlaXZlKFwib2tcIiwgcGF5bG9hZCA9PiBjb25zb2xlLmxvZyhcInBob2VuaXggcmVwbGllZDpcIiwgcGF5bG9hZCkpXG4gICAqICAgLnJlY2VpdmUoXCJlcnJvclwiLCBlcnIgPT4gY29uc29sZS5sb2coXCJwaG9lbml4IGVycm9yZWRcIiwgZXJyKSlcbiAgICogICAucmVjZWl2ZShcInRpbWVvdXRcIiwgKCkgPT4gY29uc29sZS5sb2coXCJ0aW1lZCBvdXQgcHVzaGluZ1wiKSlcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwYXlsb2FkXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbdGltZW91dF1cbiAgICogQHJldHVybnMge1B1c2h9XG4gICAqL1xuICBwdXNoKGV2ZW50LCBwYXlsb2FkLCB0aW1lb3V0ID0gdGhpcy50aW1lb3V0KXtcbiAgICBwYXlsb2FkID0gcGF5bG9hZCB8fCB7fVxuICAgIGlmKCF0aGlzLmpvaW5lZE9uY2Upe1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGB0cmllZCB0byBwdXNoICcke2V2ZW50fScgdG8gJyR7dGhpcy50b3BpY30nIGJlZm9yZSBqb2luaW5nLiBVc2UgY2hhbm5lbC5qb2luKCkgYmVmb3JlIHB1c2hpbmcgZXZlbnRzYClcbiAgICB9XG4gICAgbGV0IHB1c2hFdmVudCA9IG5ldyBQdXNoKHRoaXMsIGV2ZW50LCBmdW5jdGlvbiAoKXsgcmV0dXJuIHBheWxvYWQgfSwgdGltZW91dClcbiAgICBpZih0aGlzLmNhblB1c2goKSl7XG4gICAgICBwdXNoRXZlbnQuc2VuZCgpXG4gICAgfSBlbHNlIHtcbiAgICAgIHB1c2hFdmVudC5zdGFydFRpbWVvdXQoKVxuICAgICAgdGhpcy5wdXNoQnVmZmVyLnB1c2gocHVzaEV2ZW50KVxuICAgIH1cblxuICAgIHJldHVybiBwdXNoRXZlbnRcbiAgfVxuXG4gIC8qKiBMZWF2ZXMgdGhlIGNoYW5uZWxcbiAgICpcbiAgICogVW5zdWJzY3JpYmVzIGZyb20gc2VydmVyIGV2ZW50cywgYW5kXG4gICAqIGluc3RydWN0cyBjaGFubmVsIHRvIHRlcm1pbmF0ZSBvbiBzZXJ2ZXJcbiAgICpcbiAgICogVHJpZ2dlcnMgb25DbG9zZSgpIGhvb2tzXG4gICAqXG4gICAqIFRvIHJlY2VpdmUgbGVhdmUgYWNrbm93bGVkZ2VtZW50cywgdXNlIHRoZSBgcmVjZWl2ZWBcbiAgICogaG9vayB0byBiaW5kIHRvIHRoZSBzZXJ2ZXIgYWNrLCBpZTpcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogY2hhbm5lbC5sZWF2ZSgpLnJlY2VpdmUoXCJva1wiLCAoKSA9PiBhbGVydChcImxlZnQhXCIpIClcbiAgICpcbiAgICogQHBhcmFtIHtpbnRlZ2VyfSB0aW1lb3V0XG4gICAqIEByZXR1cm5zIHtQdXNofVxuICAgKi9cbiAgbGVhdmUodGltZW91dCA9IHRoaXMudGltZW91dCl7XG4gICAgdGhpcy5yZWpvaW5UaW1lci5yZXNldCgpXG4gICAgdGhpcy5qb2luUHVzaC5jYW5jZWxUaW1lb3V0KClcblxuICAgIHRoaXMuc3RhdGUgPSBDSEFOTkVMX1NUQVRFUy5sZWF2aW5nXG4gICAgbGV0IG9uQ2xvc2UgPSAoKSA9PiB7XG4gICAgICBpZih0aGlzLnNvY2tldC5oYXNMb2dnZXIoKSkgdGhpcy5zb2NrZXQubG9nKFwiY2hhbm5lbFwiLCBgbGVhdmUgJHt0aGlzLnRvcGljfWApXG4gICAgICB0aGlzLnRyaWdnZXIoQ0hBTk5FTF9FVkVOVFMuY2xvc2UsIFwibGVhdmVcIilcbiAgICB9XG4gICAgbGV0IGxlYXZlUHVzaCA9IG5ldyBQdXNoKHRoaXMsIENIQU5ORUxfRVZFTlRTLmxlYXZlLCBjbG9zdXJlKHt9KSwgdGltZW91dClcbiAgICBsZWF2ZVB1c2gucmVjZWl2ZShcIm9rXCIsICgpID0+IG9uQ2xvc2UoKSlcbiAgICAgIC5yZWNlaXZlKFwidGltZW91dFwiLCAoKSA9PiBvbkNsb3NlKCkpXG4gICAgbGVhdmVQdXNoLnNlbmQoKVxuICAgIGlmKCF0aGlzLmNhblB1c2goKSl7IGxlYXZlUHVzaC50cmlnZ2VyKFwib2tcIiwge30pIH1cblxuICAgIHJldHVybiBsZWF2ZVB1c2hcbiAgfVxuXG4gIC8qKlxuICAgKiBPdmVycmlkYWJsZSBtZXNzYWdlIGhvb2tcbiAgICpcbiAgICogUmVjZWl2ZXMgYWxsIGV2ZW50cyBmb3Igc3BlY2lhbGl6ZWQgbWVzc2FnZSBoYW5kbGluZ1xuICAgKiBiZWZvcmUgZGlzcGF0Y2hpbmcgdG8gdGhlIGNoYW5uZWwgY2FsbGJhY2tzLlxuICAgKlxuICAgKiBNdXN0IHJldHVybiB0aGUgcGF5bG9hZCwgbW9kaWZpZWQgb3IgdW5tb2RpZmllZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcbiAgICogQHBhcmFtIHtPYmplY3R9IHBheWxvYWRcbiAgICogQHBhcmFtIHtpbnRlZ2VyfSByZWZcbiAgICogQHJldHVybnMge09iamVjdH1cbiAgICovXG4gIG9uTWVzc2FnZShfZXZlbnQsIHBheWxvYWQsIF9yZWYpeyByZXR1cm4gcGF5bG9hZCB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBpc01lbWJlcih0b3BpYywgZXZlbnQsIHBheWxvYWQsIGpvaW5SZWYpe1xuICAgIGlmKHRoaXMudG9waWMgIT09IHRvcGljKXsgcmV0dXJuIGZhbHNlIH1cblxuICAgIGlmKGpvaW5SZWYgJiYgam9pblJlZiAhPT0gdGhpcy5qb2luUmVmKCkpe1xuICAgICAgaWYodGhpcy5zb2NrZXQuaGFzTG9nZ2VyKCkpIHRoaXMuc29ja2V0LmxvZyhcImNoYW5uZWxcIiwgXCJkcm9wcGluZyBvdXRkYXRlZCBtZXNzYWdlXCIsIHt0b3BpYywgZXZlbnQsIHBheWxvYWQsIGpvaW5SZWZ9KVxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBqb2luUmVmKCl7IHJldHVybiB0aGlzLmpvaW5QdXNoLnJlZiB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICByZWpvaW4odGltZW91dCA9IHRoaXMudGltZW91dCl7XG4gICAgaWYodGhpcy5pc0xlYXZpbmcoKSl7IHJldHVybiB9XG4gICAgdGhpcy5zb2NrZXQubGVhdmVPcGVuVG9waWModGhpcy50b3BpYylcbiAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMuam9pbmluZ1xuICAgIHRoaXMuam9pblB1c2gucmVzZW5kKHRpbWVvdXQpXG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHRyaWdnZXIoZXZlbnQsIHBheWxvYWQsIHJlZiwgam9pblJlZil7XG4gICAgbGV0IGhhbmRsZWRQYXlsb2FkID0gdGhpcy5vbk1lc3NhZ2UoZXZlbnQsIHBheWxvYWQsIHJlZiwgam9pblJlZilcbiAgICBpZihwYXlsb2FkICYmICFoYW5kbGVkUGF5bG9hZCl7IHRocm93IG5ldyBFcnJvcihcImNoYW5uZWwgb25NZXNzYWdlIGNhbGxiYWNrcyBtdXN0IHJldHVybiB0aGUgcGF5bG9hZCwgbW9kaWZpZWQgb3IgdW5tb2RpZmllZFwiKSB9XG5cbiAgICBsZXQgZXZlbnRCaW5kaW5ncyA9IHRoaXMuYmluZGluZ3MuZmlsdGVyKGJpbmQgPT4gYmluZC5ldmVudCA9PT0gZXZlbnQpXG5cbiAgICBmb3IobGV0IGkgPSAwOyBpIDwgZXZlbnRCaW5kaW5ncy5sZW5ndGg7IGkrKyl7XG4gICAgICBsZXQgYmluZCA9IGV2ZW50QmluZGluZ3NbaV1cbiAgICAgIGJpbmQuY2FsbGJhY2soaGFuZGxlZFBheWxvYWQsIHJlZiwgam9pblJlZiB8fCB0aGlzLmpvaW5SZWYoKSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHJlcGx5RXZlbnROYW1lKHJlZil7IHJldHVybiBgY2hhbl9yZXBseV8ke3JlZn1gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGlzQ2xvc2VkKCl7IHJldHVybiB0aGlzLnN0YXRlID09PSBDSEFOTkVMX1NUQVRFUy5jbG9zZWQgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgaXNFcnJvcmVkKCl7IHJldHVybiB0aGlzLnN0YXRlID09PSBDSEFOTkVMX1NUQVRFUy5lcnJvcmVkIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGlzSm9pbmVkKCl7IHJldHVybiB0aGlzLnN0YXRlID09PSBDSEFOTkVMX1NUQVRFUy5qb2luZWQgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgaXNKb2luaW5nKCl7IHJldHVybiB0aGlzLnN0YXRlID09PSBDSEFOTkVMX1NUQVRFUy5qb2luaW5nIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGlzTGVhdmluZygpeyByZXR1cm4gdGhpcy5zdGF0ZSA9PT0gQ0hBTk5FTF9TVEFURVMubGVhdmluZyB9XG59XG4iLCAiaW1wb3J0IHtcbiAgZ2xvYmFsLFxuICBYSFJfU1RBVEVTXG59IGZyb20gXCIuL2NvbnN0YW50c1wiXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFqYXgge1xuXG4gIHN0YXRpYyByZXF1ZXN0KG1ldGhvZCwgZW5kUG9pbnQsIGFjY2VwdCwgYm9keSwgdGltZW91dCwgb250aW1lb3V0LCBjYWxsYmFjayl7XG4gICAgaWYoZ2xvYmFsLlhEb21haW5SZXF1ZXN0KXtcbiAgICAgIGxldCByZXEgPSBuZXcgZ2xvYmFsLlhEb21haW5SZXF1ZXN0KCkgLy8gSUU4LCBJRTlcbiAgICAgIHJldHVybiB0aGlzLnhkb21haW5SZXF1ZXN0KHJlcSwgbWV0aG9kLCBlbmRQb2ludCwgYm9keSwgdGltZW91dCwgb250aW1lb3V0LCBjYWxsYmFjaylcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IHJlcSA9IG5ldyBnbG9iYWwuWE1MSHR0cFJlcXVlc3QoKSAvLyBJRTcrLCBGaXJlZm94LCBDaHJvbWUsIE9wZXJhLCBTYWZhcmlcbiAgICAgIHJldHVybiB0aGlzLnhoclJlcXVlc3QocmVxLCBtZXRob2QsIGVuZFBvaW50LCBhY2NlcHQsIGJvZHksIHRpbWVvdXQsIG9udGltZW91dCwgY2FsbGJhY2spXG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHhkb21haW5SZXF1ZXN0KHJlcSwgbWV0aG9kLCBlbmRQb2ludCwgYm9keSwgdGltZW91dCwgb250aW1lb3V0LCBjYWxsYmFjayl7XG4gICAgcmVxLnRpbWVvdXQgPSB0aW1lb3V0XG4gICAgcmVxLm9wZW4obWV0aG9kLCBlbmRQb2ludClcbiAgICByZXEub25sb2FkID0gKCkgPT4ge1xuICAgICAgbGV0IHJlc3BvbnNlID0gdGhpcy5wYXJzZUpTT04ocmVxLnJlc3BvbnNlVGV4dClcbiAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKHJlc3BvbnNlKVxuICAgIH1cbiAgICBpZihvbnRpbWVvdXQpeyByZXEub250aW1lb3V0ID0gb250aW1lb3V0IH1cblxuICAgIC8vIFdvcmsgYXJvdW5kIGJ1ZyBpbiBJRTkgdGhhdCByZXF1aXJlcyBhbiBhdHRhY2hlZCBvbnByb2dyZXNzIGhhbmRsZXJcbiAgICByZXEub25wcm9ncmVzcyA9ICgpID0+IHsgfVxuXG4gICAgcmVxLnNlbmQoYm9keSlcbiAgICByZXR1cm4gcmVxXG4gIH1cblxuICBzdGF0aWMgeGhyUmVxdWVzdChyZXEsIG1ldGhvZCwgZW5kUG9pbnQsIGFjY2VwdCwgYm9keSwgdGltZW91dCwgb250aW1lb3V0LCBjYWxsYmFjayl7XG4gICAgcmVxLm9wZW4obWV0aG9kLCBlbmRQb2ludCwgdHJ1ZSlcbiAgICByZXEudGltZW91dCA9IHRpbWVvdXRcbiAgICByZXEuc2V0UmVxdWVzdEhlYWRlcihcIkNvbnRlbnQtVHlwZVwiLCBhY2NlcHQpXG4gICAgcmVxLm9uZXJyb3IgPSAoKSA9PiBjYWxsYmFjayAmJiBjYWxsYmFjayhudWxsKVxuICAgIHJlcS5vbnJlYWR5c3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICBpZihyZXEucmVhZHlTdGF0ZSA9PT0gWEhSX1NUQVRFUy5jb21wbGV0ZSAmJiBjYWxsYmFjayl7XG4gICAgICAgIGxldCByZXNwb25zZSA9IHRoaXMucGFyc2VKU09OKHJlcS5yZXNwb25zZVRleHQpXG4gICAgICAgIGNhbGxiYWNrKHJlc3BvbnNlKVxuICAgICAgfVxuICAgIH1cbiAgICBpZihvbnRpbWVvdXQpeyByZXEub250aW1lb3V0ID0gb250aW1lb3V0IH1cblxuICAgIHJlcS5zZW5kKGJvZHkpXG4gICAgcmV0dXJuIHJlcVxuICB9XG5cbiAgc3RhdGljIHBhcnNlSlNPTihyZXNwKXtcbiAgICBpZighcmVzcCB8fCByZXNwID09PSBcIlwiKXsgcmV0dXJuIG51bGwgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBKU09OLnBhcnNlKHJlc3ApXG4gICAgfSBjYXRjaCAoZSl7XG4gICAgICBjb25zb2xlICYmIGNvbnNvbGUubG9nKFwiZmFpbGVkIHRvIHBhcnNlIEpTT04gcmVzcG9uc2VcIiwgcmVzcClcbiAgICAgIHJldHVybiBudWxsXG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHNlcmlhbGl6ZShvYmosIHBhcmVudEtleSl7XG4gICAgbGV0IHF1ZXJ5U3RyID0gW11cbiAgICBmb3IodmFyIGtleSBpbiBvYmope1xuICAgICAgaWYoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpeyBjb250aW51ZSB9XG4gICAgICBsZXQgcGFyYW1LZXkgPSBwYXJlbnRLZXkgPyBgJHtwYXJlbnRLZXl9WyR7a2V5fV1gIDoga2V5XG4gICAgICBsZXQgcGFyYW1WYWwgPSBvYmpba2V5XVxuICAgICAgaWYodHlwZW9mIHBhcmFtVmFsID09PSBcIm9iamVjdFwiKXtcbiAgICAgICAgcXVlcnlTdHIucHVzaCh0aGlzLnNlcmlhbGl6ZShwYXJhbVZhbCwgcGFyYW1LZXkpKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcXVlcnlTdHIucHVzaChlbmNvZGVVUklDb21wb25lbnQocGFyYW1LZXkpICsgXCI9XCIgKyBlbmNvZGVVUklDb21wb25lbnQocGFyYW1WYWwpKVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcXVlcnlTdHIuam9pbihcIiZcIilcbiAgfVxuXG4gIHN0YXRpYyBhcHBlbmRQYXJhbXModXJsLCBwYXJhbXMpe1xuICAgIGlmKE9iamVjdC5rZXlzKHBhcmFtcykubGVuZ3RoID09PSAwKXsgcmV0dXJuIHVybCB9XG5cbiAgICBsZXQgcHJlZml4ID0gdXJsLm1hdGNoKC9cXD8vKSA/IFwiJlwiIDogXCI/XCJcbiAgICByZXR1cm4gYCR7dXJsfSR7cHJlZml4fSR7dGhpcy5zZXJpYWxpemUocGFyYW1zKX1gXG4gIH1cbn1cbiIsICJpbXBvcnQge1xuICBTT0NLRVRfU1RBVEVTLFxuICBUUkFOU1BPUlRTXG59IGZyb20gXCIuL2NvbnN0YW50c1wiXG5cbmltcG9ydCBBamF4IGZyb20gXCIuL2FqYXhcIlxuXG5sZXQgYXJyYXlCdWZmZXJUb0Jhc2U2NCA9IChidWZmZXIpID0+IHtcbiAgbGV0IGJpbmFyeSA9IFwiXCJcbiAgbGV0IGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKVxuICBsZXQgbGVuID0gYnl0ZXMuYnl0ZUxlbmd0aFxuICBmb3IobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspeyBiaW5hcnkgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSkgfVxuICByZXR1cm4gYnRvYShiaW5hcnkpXG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExvbmdQb2xsIHtcblxuICBjb25zdHJ1Y3RvcihlbmRQb2ludCl7XG4gICAgdGhpcy5lbmRQb2ludCA9IG51bGxcbiAgICB0aGlzLnRva2VuID0gbnVsbFxuICAgIHRoaXMuc2tpcEhlYXJ0YmVhdCA9IHRydWVcbiAgICB0aGlzLnJlcXMgPSBuZXcgU2V0KClcbiAgICB0aGlzLmF3YWl0aW5nQmF0Y2hBY2sgPSBmYWxzZVxuICAgIHRoaXMuY3VycmVudEJhdGNoID0gbnVsbFxuICAgIHRoaXMuY3VycmVudEJhdGNoVGltZXIgPSBudWxsXG4gICAgdGhpcy5iYXRjaEJ1ZmZlciA9IFtdXG4gICAgdGhpcy5vbm9wZW4gPSBmdW5jdGlvbiAoKXsgfSAvLyBub29wXG4gICAgdGhpcy5vbmVycm9yID0gZnVuY3Rpb24gKCl7IH0gLy8gbm9vcFxuICAgIHRoaXMub25tZXNzYWdlID0gZnVuY3Rpb24gKCl7IH0gLy8gbm9vcFxuICAgIHRoaXMub25jbG9zZSA9IGZ1bmN0aW9uICgpeyB9IC8vIG5vb3BcbiAgICB0aGlzLnBvbGxFbmRwb2ludCA9IHRoaXMubm9ybWFsaXplRW5kcG9pbnQoZW5kUG9pbnQpXG4gICAgdGhpcy5yZWFkeVN0YXRlID0gU09DS0VUX1NUQVRFUy5jb25uZWN0aW5nXG4gICAgdGhpcy5wb2xsKClcbiAgfVxuXG4gIG5vcm1hbGl6ZUVuZHBvaW50KGVuZFBvaW50KXtcbiAgICByZXR1cm4gKGVuZFBvaW50XG4gICAgICAucmVwbGFjZShcIndzOi8vXCIsIFwiaHR0cDovL1wiKVxuICAgICAgLnJlcGxhY2UoXCJ3c3M6Ly9cIiwgXCJodHRwczovL1wiKVxuICAgICAgLnJlcGxhY2UobmV3IFJlZ0V4cChcIiguKilcXC9cIiArIFRSQU5TUE9SVFMud2Vic29ja2V0KSwgXCIkMS9cIiArIFRSQU5TUE9SVFMubG9uZ3BvbGwpKVxuICB9XG5cbiAgZW5kcG9pbnRVUkwoKXtcbiAgICByZXR1cm4gQWpheC5hcHBlbmRQYXJhbXModGhpcy5wb2xsRW5kcG9pbnQsIHt0b2tlbjogdGhpcy50b2tlbn0pXG4gIH1cblxuICBjbG9zZUFuZFJldHJ5KGNvZGUsIHJlYXNvbiwgd2FzQ2xlYW4pe1xuICAgIHRoaXMuY2xvc2UoY29kZSwgcmVhc29uLCB3YXNDbGVhbilcbiAgICB0aGlzLnJlYWR5U3RhdGUgPSBTT0NLRVRfU1RBVEVTLmNvbm5lY3RpbmdcbiAgfVxuXG4gIG9udGltZW91dCgpe1xuICAgIHRoaXMub25lcnJvcihcInRpbWVvdXRcIilcbiAgICB0aGlzLmNsb3NlQW5kUmV0cnkoMTAwNSwgXCJ0aW1lb3V0XCIsIGZhbHNlKVxuICB9XG5cbiAgaXNBY3RpdmUoKXsgcmV0dXJuIHRoaXMucmVhZHlTdGF0ZSA9PT0gU09DS0VUX1NUQVRFUy5vcGVuIHx8IHRoaXMucmVhZHlTdGF0ZSA9PT0gU09DS0VUX1NUQVRFUy5jb25uZWN0aW5nIH1cblxuICBwb2xsKCl7XG4gICAgdGhpcy5hamF4KFwiR0VUXCIsIFwiYXBwbGljYXRpb24vanNvblwiLCBudWxsLCAoKSA9PiB0aGlzLm9udGltZW91dCgpLCByZXNwID0+IHtcbiAgICAgIGlmKHJlc3Ape1xuICAgICAgICB2YXIge3N0YXR1cywgdG9rZW4sIG1lc3NhZ2VzfSA9IHJlc3BcbiAgICAgICAgdGhpcy50b2tlbiA9IHRva2VuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0dXMgPSAwXG4gICAgICB9XG5cbiAgICAgIHN3aXRjaChzdGF0dXMpe1xuICAgICAgICBjYXNlIDIwMDpcbiAgICAgICAgICBtZXNzYWdlcy5mb3JFYWNoKG1zZyA9PiB7XG4gICAgICAgICAgICAvLyBUYXNrcyBhcmUgd2hhdCB0aGluZ3MgbGlrZSBldmVudCBoYW5kbGVycywgc2V0VGltZW91dCBjYWxsYmFja3MsXG4gICAgICAgICAgICAvLyBwcm9taXNlIHJlc29sdmVzIGFuZCBtb3JlIGFyZSBydW4gd2l0aGluLlxuICAgICAgICAgICAgLy8gSW4gbW9kZXJuIGJyb3dzZXJzLCB0aGVyZSBhcmUgdHdvIGRpZmZlcmVudCBraW5kcyBvZiB0YXNrcyxcbiAgICAgICAgICAgIC8vIG1pY3JvdGFza3MgYW5kIG1hY3JvdGFza3MuXG4gICAgICAgICAgICAvLyBNaWNyb3Rhc2tzIGFyZSBtYWlubHkgdXNlZCBmb3IgUHJvbWlzZXMsIHdoaWxlIG1hY3JvdGFza3MgYXJlXG4gICAgICAgICAgICAvLyB1c2VkIGZvciBldmVyeXRoaW5nIGVsc2UuXG4gICAgICAgICAgICAvLyBNaWNyb3Rhc2tzIGFsd2F5cyBoYXZlIHByaW9yaXR5IG92ZXIgbWFjcm90YXNrcy4gSWYgdGhlIEpTIGVuZ2luZVxuICAgICAgICAgICAgLy8gaXMgbG9va2luZyBmb3IgYSB0YXNrIHRvIHJ1biwgaXQgd2lsbCBhbHdheXMgdHJ5IHRvIGVtcHR5IHRoZVxuICAgICAgICAgICAgLy8gbWljcm90YXNrIHF1ZXVlIGJlZm9yZSBhdHRlbXB0aW5nIHRvIHJ1biBhbnl0aGluZyBmcm9tIHRoZVxuICAgICAgICAgICAgLy8gbWFjcm90YXNrIHF1ZXVlLlxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIEZvciB0aGUgV2ViU29ja2V0IHRyYW5zcG9ydCwgbWVzc2FnZXMgYWx3YXlzIGFycml2ZSBpbiB0aGVpciBvd25cbiAgICAgICAgICAgIC8vIGV2ZW50LiBUaGlzIG1lYW5zIHRoYXQgaWYgYW55IHByb21pc2VzIGFyZSByZXNvbHZlZCBmcm9tIHdpdGhpbixcbiAgICAgICAgICAgIC8vIHRoZWlyIGNhbGxiYWNrcyB3aWxsIGFsd2F5cyBmaW5pc2ggZXhlY3V0aW9uIGJ5IHRoZSB0aW1lIHRoZVxuICAgICAgICAgICAgLy8gbmV4dCBtZXNzYWdlIGV2ZW50IGhhbmRsZXIgaXMgcnVuLlxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIEluIG9yZGVyIHRvIGVtdWxhdGUgdGhpcyBiZWhhdmlvdXIsIHdlIG5lZWQgdG8gbWFrZSBzdXJlIGVhY2hcbiAgICAgICAgICAgIC8vIG9ubWVzc2FnZSBoYW5kbGVyIGlzIHJ1biB3aXRoaW4gaXRzIG93biBtYWNyb3Rhc2suXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMub25tZXNzYWdlKHtkYXRhOiBtc2d9KSwgMClcbiAgICAgICAgICB9KVxuICAgICAgICAgIHRoaXMucG9sbCgpXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAyMDQ6XG4gICAgICAgICAgdGhpcy5wb2xsKClcbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDQxMDpcbiAgICAgICAgICB0aGlzLnJlYWR5U3RhdGUgPSBTT0NLRVRfU1RBVEVTLm9wZW5cbiAgICAgICAgICB0aGlzLm9ub3Blbih7fSlcbiAgICAgICAgICB0aGlzLnBvbGwoKVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgNDAzOlxuICAgICAgICAgIHRoaXMub25lcnJvcig0MDMpXG4gICAgICAgICAgdGhpcy5jbG9zZSgxMDA4LCBcImZvcmJpZGRlblwiLCBmYWxzZSlcbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDA6XG4gICAgICAgIGNhc2UgNTAwOlxuICAgICAgICAgIHRoaXMub25lcnJvcig1MDApXG4gICAgICAgICAgdGhpcy5jbG9zZUFuZFJldHJ5KDEwMTEsIFwiaW50ZXJuYWwgc2VydmVyIGVycm9yXCIsIDUwMClcbiAgICAgICAgICBicmVha1xuICAgICAgICBkZWZhdWx0OiB0aHJvdyBuZXcgRXJyb3IoYHVuaGFuZGxlZCBwb2xsIHN0YXR1cyAke3N0YXR1c31gKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICAvLyB3ZSBjb2xsZWN0IGFsbCBwdXNoZXMgd2l0aGluIHRoZSBjdXJyZW50IGV2ZW50IGxvb3AgYnlcbiAgLy8gc2V0VGltZW91dCAwLCB3aGljaCBvcHRpbWl6ZXMgYmFjay10by1iYWNrIHByb2NlZHVyYWxcbiAgLy8gcHVzaGVzIGFnYWluc3QgYW4gZW1wdHkgYnVmZmVyXG5cbiAgc2VuZChib2R5KXtcbiAgICBpZih0eXBlb2YoYm9keSkgIT09IFwic3RyaW5nXCIpeyBib2R5ID0gYXJyYXlCdWZmZXJUb0Jhc2U2NChib2R5KSB9XG4gICAgaWYodGhpcy5jdXJyZW50QmF0Y2gpe1xuICAgICAgdGhpcy5jdXJyZW50QmF0Y2gucHVzaChib2R5KVxuICAgIH0gZWxzZSBpZih0aGlzLmF3YWl0aW5nQmF0Y2hBY2spe1xuICAgICAgdGhpcy5iYXRjaEJ1ZmZlci5wdXNoKGJvZHkpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3VycmVudEJhdGNoID0gW2JvZHldXG4gICAgICB0aGlzLmN1cnJlbnRCYXRjaFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuYmF0Y2hTZW5kKHRoaXMuY3VycmVudEJhdGNoKVxuICAgICAgICB0aGlzLmN1cnJlbnRCYXRjaCA9IG51bGxcbiAgICAgIH0sIDApXG4gICAgfVxuICB9XG5cbiAgYmF0Y2hTZW5kKG1lc3NhZ2VzKXtcbiAgICB0aGlzLmF3YWl0aW5nQmF0Y2hBY2sgPSB0cnVlXG4gICAgdGhpcy5hamF4KFwiUE9TVFwiLCBcImFwcGxpY2F0aW9uL3gtbmRqc29uXCIsIG1lc3NhZ2VzLmpvaW4oXCJcXG5cIiksICgpID0+IHRoaXMub25lcnJvcihcInRpbWVvdXRcIiksIHJlc3AgPT4ge1xuICAgICAgdGhpcy5hd2FpdGluZ0JhdGNoQWNrID0gZmFsc2VcbiAgICAgIGlmKCFyZXNwIHx8IHJlc3Auc3RhdHVzICE9PSAyMDApe1xuICAgICAgICB0aGlzLm9uZXJyb3IocmVzcCAmJiByZXNwLnN0YXR1cylcbiAgICAgICAgdGhpcy5jbG9zZUFuZFJldHJ5KDEwMTEsIFwiaW50ZXJuYWwgc2VydmVyIGVycm9yXCIsIGZhbHNlKVxuICAgICAgfSBlbHNlIGlmKHRoaXMuYmF0Y2hCdWZmZXIubGVuZ3RoID4gMCl7XG4gICAgICAgIHRoaXMuYmF0Y2hTZW5kKHRoaXMuYmF0Y2hCdWZmZXIpXG4gICAgICAgIHRoaXMuYmF0Y2hCdWZmZXIgPSBbXVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICBjbG9zZShjb2RlLCByZWFzb24sIHdhc0NsZWFuKXtcbiAgICBmb3IobGV0IHJlcSBvZiB0aGlzLnJlcXMpeyByZXEuYWJvcnQoKSB9XG4gICAgdGhpcy5yZWFkeVN0YXRlID0gU09DS0VUX1NUQVRFUy5jbG9zZWRcbiAgICBsZXQgb3B0cyA9IE9iamVjdC5hc3NpZ24oe2NvZGU6IDEwMDAsIHJlYXNvbjogdW5kZWZpbmVkLCB3YXNDbGVhbjogdHJ1ZX0sIHtjb2RlLCByZWFzb24sIHdhc0NsZWFufSlcbiAgICB0aGlzLmJhdGNoQnVmZmVyID0gW11cbiAgICBjbGVhclRpbWVvdXQodGhpcy5jdXJyZW50QmF0Y2hUaW1lcilcbiAgICB0aGlzLmN1cnJlbnRCYXRjaFRpbWVyID0gbnVsbFxuICAgIGlmKHR5cGVvZihDbG9zZUV2ZW50KSAhPT0gXCJ1bmRlZmluZWRcIil7XG4gICAgICB0aGlzLm9uY2xvc2UobmV3IENsb3NlRXZlbnQoXCJjbG9zZVwiLCBvcHRzKSlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vbmNsb3NlKG9wdHMpXG4gICAgfVxuICB9XG5cbiAgYWpheChtZXRob2QsIGNvbnRlbnRUeXBlLCBib2R5LCBvbkNhbGxlclRpbWVvdXQsIGNhbGxiYWNrKXtcbiAgICBsZXQgcmVxXG4gICAgbGV0IG9udGltZW91dCA9ICgpID0+IHtcbiAgICAgIHRoaXMucmVxcy5kZWxldGUocmVxKVxuICAgICAgb25DYWxsZXJUaW1lb3V0KClcbiAgICB9XG4gICAgcmVxID0gQWpheC5yZXF1ZXN0KG1ldGhvZCwgdGhpcy5lbmRwb2ludFVSTCgpLCBjb250ZW50VHlwZSwgYm9keSwgdGhpcy50aW1lb3V0LCBvbnRpbWVvdXQsIHJlc3AgPT4ge1xuICAgICAgdGhpcy5yZXFzLmRlbGV0ZShyZXEpXG4gICAgICBpZih0aGlzLmlzQWN0aXZlKCkpeyBjYWxsYmFjayhyZXNwKSB9XG4gICAgfSlcbiAgICB0aGlzLnJlcXMuYWRkKHJlcSlcbiAgfVxufVxuIiwgIi8qKlxuICogSW5pdGlhbGl6ZXMgdGhlIFByZXNlbmNlXG4gKiBAcGFyYW0ge0NoYW5uZWx9IGNoYW5uZWwgLSBUaGUgQ2hhbm5lbFxuICogQHBhcmFtIHtPYmplY3R9IG9wdHMgLSBUaGUgb3B0aW9ucyxcbiAqICAgICAgICBmb3IgZXhhbXBsZSBge2V2ZW50czoge3N0YXRlOiBcInN0YXRlXCIsIGRpZmY6IFwiZGlmZlwifX1gXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFByZXNlbmNlIHtcblxuICBjb25zdHJ1Y3RvcihjaGFubmVsLCBvcHRzID0ge30pe1xuICAgIGxldCBldmVudHMgPSBvcHRzLmV2ZW50cyB8fCB7c3RhdGU6IFwicHJlc2VuY2Vfc3RhdGVcIiwgZGlmZjogXCJwcmVzZW5jZV9kaWZmXCJ9XG4gICAgdGhpcy5zdGF0ZSA9IHt9XG4gICAgdGhpcy5wZW5kaW5nRGlmZnMgPSBbXVxuICAgIHRoaXMuY2hhbm5lbCA9IGNoYW5uZWxcbiAgICB0aGlzLmpvaW5SZWYgPSBudWxsXG4gICAgdGhpcy5jYWxsZXIgPSB7XG4gICAgICBvbkpvaW46IGZ1bmN0aW9uICgpeyB9LFxuICAgICAgb25MZWF2ZTogZnVuY3Rpb24gKCl7IH0sXG4gICAgICBvblN5bmM6IGZ1bmN0aW9uICgpeyB9XG4gICAgfVxuXG4gICAgdGhpcy5jaGFubmVsLm9uKGV2ZW50cy5zdGF0ZSwgbmV3U3RhdGUgPT4ge1xuICAgICAgbGV0IHtvbkpvaW4sIG9uTGVhdmUsIG9uU3luY30gPSB0aGlzLmNhbGxlclxuXG4gICAgICB0aGlzLmpvaW5SZWYgPSB0aGlzLmNoYW5uZWwuam9pblJlZigpXG4gICAgICB0aGlzLnN0YXRlID0gUHJlc2VuY2Uuc3luY1N0YXRlKHRoaXMuc3RhdGUsIG5ld1N0YXRlLCBvbkpvaW4sIG9uTGVhdmUpXG5cbiAgICAgIHRoaXMucGVuZGluZ0RpZmZzLmZvckVhY2goZGlmZiA9PiB7XG4gICAgICAgIHRoaXMuc3RhdGUgPSBQcmVzZW5jZS5zeW5jRGlmZih0aGlzLnN0YXRlLCBkaWZmLCBvbkpvaW4sIG9uTGVhdmUpXG4gICAgICB9KVxuICAgICAgdGhpcy5wZW5kaW5nRGlmZnMgPSBbXVxuICAgICAgb25TeW5jKClcbiAgICB9KVxuXG4gICAgdGhpcy5jaGFubmVsLm9uKGV2ZW50cy5kaWZmLCBkaWZmID0+IHtcbiAgICAgIGxldCB7b25Kb2luLCBvbkxlYXZlLCBvblN5bmN9ID0gdGhpcy5jYWxsZXJcblxuICAgICAgaWYodGhpcy5pblBlbmRpbmdTeW5jU3RhdGUoKSl7XG4gICAgICAgIHRoaXMucGVuZGluZ0RpZmZzLnB1c2goZGlmZilcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc3RhdGUgPSBQcmVzZW5jZS5zeW5jRGlmZih0aGlzLnN0YXRlLCBkaWZmLCBvbkpvaW4sIG9uTGVhdmUpXG4gICAgICAgIG9uU3luYygpXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIG9uSm9pbihjYWxsYmFjayl7IHRoaXMuY2FsbGVyLm9uSm9pbiA9IGNhbGxiYWNrIH1cblxuICBvbkxlYXZlKGNhbGxiYWNrKXsgdGhpcy5jYWxsZXIub25MZWF2ZSA9IGNhbGxiYWNrIH1cblxuICBvblN5bmMoY2FsbGJhY2speyB0aGlzLmNhbGxlci5vblN5bmMgPSBjYWxsYmFjayB9XG5cbiAgbGlzdChieSl7IHJldHVybiBQcmVzZW5jZS5saXN0KHRoaXMuc3RhdGUsIGJ5KSB9XG5cbiAgaW5QZW5kaW5nU3luY1N0YXRlKCl7XG4gICAgcmV0dXJuICF0aGlzLmpvaW5SZWYgfHwgKHRoaXMuam9pblJlZiAhPT0gdGhpcy5jaGFubmVsLmpvaW5SZWYoKSlcbiAgfVxuXG4gIC8vIGxvd2VyLWxldmVsIHB1YmxpYyBzdGF0aWMgQVBJXG5cbiAgLyoqXG4gICAqIFVzZWQgdG8gc3luYyB0aGUgbGlzdCBvZiBwcmVzZW5jZXMgb24gdGhlIHNlcnZlclxuICAgKiB3aXRoIHRoZSBjbGllbnQncyBzdGF0ZS4gQW4gb3B0aW9uYWwgYG9uSm9pbmAgYW5kIGBvbkxlYXZlYCBjYWxsYmFjayBjYW5cbiAgICogYmUgcHJvdmlkZWQgdG8gcmVhY3QgdG8gY2hhbmdlcyBpbiB0aGUgY2xpZW50J3MgbG9jYWwgcHJlc2VuY2VzIGFjcm9zc1xuICAgKiBkaXNjb25uZWN0cyBhbmQgcmVjb25uZWN0cyB3aXRoIHRoZSBzZXJ2ZXIuXG4gICAqXG4gICAqIEByZXR1cm5zIHtQcmVzZW5jZX1cbiAgICovXG4gIHN0YXRpYyBzeW5jU3RhdGUoY3VycmVudFN0YXRlLCBuZXdTdGF0ZSwgb25Kb2luLCBvbkxlYXZlKXtcbiAgICBsZXQgc3RhdGUgPSB0aGlzLmNsb25lKGN1cnJlbnRTdGF0ZSlcbiAgICBsZXQgam9pbnMgPSB7fVxuICAgIGxldCBsZWF2ZXMgPSB7fVxuXG4gICAgdGhpcy5tYXAoc3RhdGUsIChrZXksIHByZXNlbmNlKSA9PiB7XG4gICAgICBpZighbmV3U3RhdGVba2V5XSl7XG4gICAgICAgIGxlYXZlc1trZXldID0gcHJlc2VuY2VcbiAgICAgIH1cbiAgICB9KVxuICAgIHRoaXMubWFwKG5ld1N0YXRlLCAoa2V5LCBuZXdQcmVzZW5jZSkgPT4ge1xuICAgICAgbGV0IGN1cnJlbnRQcmVzZW5jZSA9IHN0YXRlW2tleV1cbiAgICAgIGlmKGN1cnJlbnRQcmVzZW5jZSl7XG4gICAgICAgIGxldCBuZXdSZWZzID0gbmV3UHJlc2VuY2UubWV0YXMubWFwKG0gPT4gbS5waHhfcmVmKVxuICAgICAgICBsZXQgY3VyUmVmcyA9IGN1cnJlbnRQcmVzZW5jZS5tZXRhcy5tYXAobSA9PiBtLnBoeF9yZWYpXG4gICAgICAgIGxldCBqb2luZWRNZXRhcyA9IG5ld1ByZXNlbmNlLm1ldGFzLmZpbHRlcihtID0+IGN1clJlZnMuaW5kZXhPZihtLnBoeF9yZWYpIDwgMClcbiAgICAgICAgbGV0IGxlZnRNZXRhcyA9IGN1cnJlbnRQcmVzZW5jZS5tZXRhcy5maWx0ZXIobSA9PiBuZXdSZWZzLmluZGV4T2YobS5waHhfcmVmKSA8IDApXG4gICAgICAgIGlmKGpvaW5lZE1ldGFzLmxlbmd0aCA+IDApe1xuICAgICAgICAgIGpvaW5zW2tleV0gPSBuZXdQcmVzZW5jZVxuICAgICAgICAgIGpvaW5zW2tleV0ubWV0YXMgPSBqb2luZWRNZXRhc1xuICAgICAgICB9XG4gICAgICAgIGlmKGxlZnRNZXRhcy5sZW5ndGggPiAwKXtcbiAgICAgICAgICBsZWF2ZXNba2V5XSA9IHRoaXMuY2xvbmUoY3VycmVudFByZXNlbmNlKVxuICAgICAgICAgIGxlYXZlc1trZXldLm1ldGFzID0gbGVmdE1ldGFzXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGpvaW5zW2tleV0gPSBuZXdQcmVzZW5jZVxuICAgICAgfVxuICAgIH0pXG4gICAgcmV0dXJuIHRoaXMuc3luY0RpZmYoc3RhdGUsIHtqb2luczogam9pbnMsIGxlYXZlczogbGVhdmVzfSwgb25Kb2luLCBvbkxlYXZlKVxuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIFVzZWQgdG8gc3luYyBhIGRpZmYgb2YgcHJlc2VuY2Ugam9pbiBhbmQgbGVhdmVcbiAgICogZXZlbnRzIGZyb20gdGhlIHNlcnZlciwgYXMgdGhleSBoYXBwZW4uIExpa2UgYHN5bmNTdGF0ZWAsIGBzeW5jRGlmZmBcbiAgICogYWNjZXB0cyBvcHRpb25hbCBgb25Kb2luYCBhbmQgYG9uTGVhdmVgIGNhbGxiYWNrcyB0byByZWFjdCB0byBhIHVzZXJcbiAgICogam9pbmluZyBvciBsZWF2aW5nIGZyb20gYSBkZXZpY2UuXG4gICAqXG4gICAqIEByZXR1cm5zIHtQcmVzZW5jZX1cbiAgICovXG4gIHN0YXRpYyBzeW5jRGlmZihzdGF0ZSwgZGlmZiwgb25Kb2luLCBvbkxlYXZlKXtcbiAgICBsZXQge2pvaW5zLCBsZWF2ZXN9ID0gdGhpcy5jbG9uZShkaWZmKVxuICAgIGlmKCFvbkpvaW4peyBvbkpvaW4gPSBmdW5jdGlvbiAoKXsgfSB9XG4gICAgaWYoIW9uTGVhdmUpeyBvbkxlYXZlID0gZnVuY3Rpb24gKCl7IH0gfVxuXG4gICAgdGhpcy5tYXAoam9pbnMsIChrZXksIG5ld1ByZXNlbmNlKSA9PiB7XG4gICAgICBsZXQgY3VycmVudFByZXNlbmNlID0gc3RhdGVba2V5XVxuICAgICAgc3RhdGVba2V5XSA9IHRoaXMuY2xvbmUobmV3UHJlc2VuY2UpXG4gICAgICBpZihjdXJyZW50UHJlc2VuY2Upe1xuICAgICAgICBsZXQgam9pbmVkUmVmcyA9IHN0YXRlW2tleV0ubWV0YXMubWFwKG0gPT4gbS5waHhfcmVmKVxuICAgICAgICBsZXQgY3VyTWV0YXMgPSBjdXJyZW50UHJlc2VuY2UubWV0YXMuZmlsdGVyKG0gPT4gam9pbmVkUmVmcy5pbmRleE9mKG0ucGh4X3JlZikgPCAwKVxuICAgICAgICBzdGF0ZVtrZXldLm1ldGFzLnVuc2hpZnQoLi4uY3VyTWV0YXMpXG4gICAgICB9XG4gICAgICBvbkpvaW4oa2V5LCBjdXJyZW50UHJlc2VuY2UsIG5ld1ByZXNlbmNlKVxuICAgIH0pXG4gICAgdGhpcy5tYXAobGVhdmVzLCAoa2V5LCBsZWZ0UHJlc2VuY2UpID0+IHtcbiAgICAgIGxldCBjdXJyZW50UHJlc2VuY2UgPSBzdGF0ZVtrZXldXG4gICAgICBpZighY3VycmVudFByZXNlbmNlKXsgcmV0dXJuIH1cbiAgICAgIGxldCByZWZzVG9SZW1vdmUgPSBsZWZ0UHJlc2VuY2UubWV0YXMubWFwKG0gPT4gbS5waHhfcmVmKVxuICAgICAgY3VycmVudFByZXNlbmNlLm1ldGFzID0gY3VycmVudFByZXNlbmNlLm1ldGFzLmZpbHRlcihwID0+IHtcbiAgICAgICAgcmV0dXJuIHJlZnNUb1JlbW92ZS5pbmRleE9mKHAucGh4X3JlZikgPCAwXG4gICAgICB9KVxuICAgICAgb25MZWF2ZShrZXksIGN1cnJlbnRQcmVzZW5jZSwgbGVmdFByZXNlbmNlKVxuICAgICAgaWYoY3VycmVudFByZXNlbmNlLm1ldGFzLmxlbmd0aCA9PT0gMCl7XG4gICAgICAgIGRlbGV0ZSBzdGF0ZVtrZXldXG4gICAgICB9XG4gICAgfSlcbiAgICByZXR1cm4gc3RhdGVcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcmVzZW5jZXMsIHdpdGggc2VsZWN0ZWQgbWV0YWRhdGEuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwcmVzZW5jZXNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2hvb3NlclxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJlc2VuY2V9XG4gICAqL1xuICBzdGF0aWMgbGlzdChwcmVzZW5jZXMsIGNob29zZXIpe1xuICAgIGlmKCFjaG9vc2VyKXsgY2hvb3NlciA9IGZ1bmN0aW9uIChrZXksIHByZXMpeyByZXR1cm4gcHJlcyB9IH1cblxuICAgIHJldHVybiB0aGlzLm1hcChwcmVzZW5jZXMsIChrZXksIHByZXNlbmNlKSA9PiB7XG4gICAgICByZXR1cm4gY2hvb3NlcihrZXksIHByZXNlbmNlKVxuICAgIH0pXG4gIH1cblxuICAvLyBwcml2YXRlXG5cbiAgc3RhdGljIG1hcChvYmosIGZ1bmMpe1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopLm1hcChrZXkgPT4gZnVuYyhrZXksIG9ialtrZXldKSlcbiAgfVxuXG4gIHN0YXRpYyBjbG9uZShvYmopeyByZXR1cm4gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShvYmopKSB9XG59XG4iLCAiLyogVGhlIGRlZmF1bHQgc2VyaWFsaXplciBmb3IgZW5jb2RpbmcgYW5kIGRlY29kaW5nIG1lc3NhZ2VzICovXG5pbXBvcnQge1xuICBDSEFOTkVMX0VWRU5UU1xufSBmcm9tIFwiLi9jb25zdGFudHNcIlxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIEhFQURFUl9MRU5HVEg6IDEsXG4gIE1FVEFfTEVOR1RIOiA0LFxuICBLSU5EUzoge3B1c2g6IDAsIHJlcGx5OiAxLCBicm9hZGNhc3Q6IDJ9LFxuXG4gIGVuY29kZShtc2csIGNhbGxiYWNrKXtcbiAgICBpZihtc2cucGF5bG9hZC5jb25zdHJ1Y3RvciA9PT0gQXJyYXlCdWZmZXIpe1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKHRoaXMuYmluYXJ5RW5jb2RlKG1zZykpXG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBwYXlsb2FkID0gW21zZy5qb2luX3JlZiwgbXNnLnJlZiwgbXNnLnRvcGljLCBtc2cuZXZlbnQsIG1zZy5wYXlsb2FkXVxuICAgICAgcmV0dXJuIGNhbGxiYWNrKEpTT04uc3RyaW5naWZ5KHBheWxvYWQpKVxuICAgIH1cbiAgfSxcblxuICBkZWNvZGUocmF3UGF5bG9hZCwgY2FsbGJhY2spe1xuICAgIGlmKHJhd1BheWxvYWQuY29uc3RydWN0b3IgPT09IEFycmF5QnVmZmVyKXtcbiAgICAgIHJldHVybiBjYWxsYmFjayh0aGlzLmJpbmFyeURlY29kZShyYXdQYXlsb2FkKSlcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IFtqb2luX3JlZiwgcmVmLCB0b3BpYywgZXZlbnQsIHBheWxvYWRdID0gSlNPTi5wYXJzZShyYXdQYXlsb2FkKVxuICAgICAgcmV0dXJuIGNhbGxiYWNrKHtqb2luX3JlZiwgcmVmLCB0b3BpYywgZXZlbnQsIHBheWxvYWR9KVxuICAgIH1cbiAgfSxcblxuICAvLyBwcml2YXRlXG5cbiAgYmluYXJ5RW5jb2RlKG1lc3NhZ2Upe1xuICAgIGxldCB7am9pbl9yZWYsIHJlZiwgZXZlbnQsIHRvcGljLCBwYXlsb2FkfSA9IG1lc3NhZ2VcbiAgICBsZXQgbWV0YUxlbmd0aCA9IHRoaXMuTUVUQV9MRU5HVEggKyBqb2luX3JlZi5sZW5ndGggKyByZWYubGVuZ3RoICsgdG9waWMubGVuZ3RoICsgZXZlbnQubGVuZ3RoXG4gICAgbGV0IGhlYWRlciA9IG5ldyBBcnJheUJ1ZmZlcih0aGlzLkhFQURFUl9MRU5HVEggKyBtZXRhTGVuZ3RoKVxuICAgIGxldCB2aWV3ID0gbmV3IERhdGFWaWV3KGhlYWRlcilcbiAgICBsZXQgb2Zmc2V0ID0gMFxuXG4gICAgdmlldy5zZXRVaW50OChvZmZzZXQrKywgdGhpcy5LSU5EUy5wdXNoKSAvLyBraW5kXG4gICAgdmlldy5zZXRVaW50OChvZmZzZXQrKywgam9pbl9yZWYubGVuZ3RoKVxuICAgIHZpZXcuc2V0VWludDgob2Zmc2V0KyssIHJlZi5sZW5ndGgpXG4gICAgdmlldy5zZXRVaW50OChvZmZzZXQrKywgdG9waWMubGVuZ3RoKVxuICAgIHZpZXcuc2V0VWludDgob2Zmc2V0KyssIGV2ZW50Lmxlbmd0aClcbiAgICBBcnJheS5mcm9tKGpvaW5fcmVmLCBjaGFyID0+IHZpZXcuc2V0VWludDgob2Zmc2V0KyssIGNoYXIuY2hhckNvZGVBdCgwKSkpXG4gICAgQXJyYXkuZnJvbShyZWYsIGNoYXIgPT4gdmlldy5zZXRVaW50OChvZmZzZXQrKywgY2hhci5jaGFyQ29kZUF0KDApKSlcbiAgICBBcnJheS5mcm9tKHRvcGljLCBjaGFyID0+IHZpZXcuc2V0VWludDgob2Zmc2V0KyssIGNoYXIuY2hhckNvZGVBdCgwKSkpXG4gICAgQXJyYXkuZnJvbShldmVudCwgY2hhciA9PiB2aWV3LnNldFVpbnQ4KG9mZnNldCsrLCBjaGFyLmNoYXJDb2RlQXQoMCkpKVxuXG4gICAgdmFyIGNvbWJpbmVkID0gbmV3IFVpbnQ4QXJyYXkoaGVhZGVyLmJ5dGVMZW5ndGggKyBwYXlsb2FkLmJ5dGVMZW5ndGgpXG4gICAgY29tYmluZWQuc2V0KG5ldyBVaW50OEFycmF5KGhlYWRlciksIDApXG4gICAgY29tYmluZWQuc2V0KG5ldyBVaW50OEFycmF5KHBheWxvYWQpLCBoZWFkZXIuYnl0ZUxlbmd0aClcblxuICAgIHJldHVybiBjb21iaW5lZC5idWZmZXJcbiAgfSxcblxuICBiaW5hcnlEZWNvZGUoYnVmZmVyKXtcbiAgICBsZXQgdmlldyA9IG5ldyBEYXRhVmlldyhidWZmZXIpXG4gICAgbGV0IGtpbmQgPSB2aWV3LmdldFVpbnQ4KDApXG4gICAgbGV0IGRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoKVxuICAgIHN3aXRjaChraW5kKXtcbiAgICAgIGNhc2UgdGhpcy5LSU5EUy5wdXNoOiByZXR1cm4gdGhpcy5kZWNvZGVQdXNoKGJ1ZmZlciwgdmlldywgZGVjb2RlcilcbiAgICAgIGNhc2UgdGhpcy5LSU5EUy5yZXBseTogcmV0dXJuIHRoaXMuZGVjb2RlUmVwbHkoYnVmZmVyLCB2aWV3LCBkZWNvZGVyKVxuICAgICAgY2FzZSB0aGlzLktJTkRTLmJyb2FkY2FzdDogcmV0dXJuIHRoaXMuZGVjb2RlQnJvYWRjYXN0KGJ1ZmZlciwgdmlldywgZGVjb2RlcilcbiAgICB9XG4gIH0sXG5cbiAgZGVjb2RlUHVzaChidWZmZXIsIHZpZXcsIGRlY29kZXIpe1xuICAgIGxldCBqb2luUmVmU2l6ZSA9IHZpZXcuZ2V0VWludDgoMSlcbiAgICBsZXQgdG9waWNTaXplID0gdmlldy5nZXRVaW50OCgyKVxuICAgIGxldCBldmVudFNpemUgPSB2aWV3LmdldFVpbnQ4KDMpXG4gICAgbGV0IG9mZnNldCA9IHRoaXMuSEVBREVSX0xFTkdUSCArIHRoaXMuTUVUQV9MRU5HVEggLSAxIC8vIHB1c2hlcyBoYXZlIG5vIHJlZlxuICAgIGxldCBqb2luUmVmID0gZGVjb2Rlci5kZWNvZGUoYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgam9pblJlZlNpemUpKVxuICAgIG9mZnNldCA9IG9mZnNldCArIGpvaW5SZWZTaXplXG4gICAgbGV0IHRvcGljID0gZGVjb2Rlci5kZWNvZGUoYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgdG9waWNTaXplKSlcbiAgICBvZmZzZXQgPSBvZmZzZXQgKyB0b3BpY1NpemVcbiAgICBsZXQgZXZlbnQgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBldmVudFNpemUpKVxuICAgIG9mZnNldCA9IG9mZnNldCArIGV2ZW50U2l6ZVxuICAgIGxldCBkYXRhID0gYnVmZmVyLnNsaWNlKG9mZnNldCwgYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgcmV0dXJuIHtqb2luX3JlZjogam9pblJlZiwgcmVmOiBudWxsLCB0b3BpYzogdG9waWMsIGV2ZW50OiBldmVudCwgcGF5bG9hZDogZGF0YX1cbiAgfSxcblxuICBkZWNvZGVSZXBseShidWZmZXIsIHZpZXcsIGRlY29kZXIpe1xuICAgIGxldCBqb2luUmVmU2l6ZSA9IHZpZXcuZ2V0VWludDgoMSlcbiAgICBsZXQgcmVmU2l6ZSA9IHZpZXcuZ2V0VWludDgoMilcbiAgICBsZXQgdG9waWNTaXplID0gdmlldy5nZXRVaW50OCgzKVxuICAgIGxldCBldmVudFNpemUgPSB2aWV3LmdldFVpbnQ4KDQpXG4gICAgbGV0IG9mZnNldCA9IHRoaXMuSEVBREVSX0xFTkdUSCArIHRoaXMuTUVUQV9MRU5HVEhcbiAgICBsZXQgam9pblJlZiA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIGpvaW5SZWZTaXplKSlcbiAgICBvZmZzZXQgPSBvZmZzZXQgKyBqb2luUmVmU2l6ZVxuICAgIGxldCByZWYgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyByZWZTaXplKSlcbiAgICBvZmZzZXQgPSBvZmZzZXQgKyByZWZTaXplXG4gICAgbGV0IHRvcGljID0gZGVjb2Rlci5kZWNvZGUoYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgdG9waWNTaXplKSlcbiAgICBvZmZzZXQgPSBvZmZzZXQgKyB0b3BpY1NpemVcbiAgICBsZXQgZXZlbnQgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBldmVudFNpemUpKVxuICAgIG9mZnNldCA9IG9mZnNldCArIGV2ZW50U2l6ZVxuICAgIGxldCBkYXRhID0gYnVmZmVyLnNsaWNlKG9mZnNldCwgYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgbGV0IHBheWxvYWQgPSB7c3RhdHVzOiBldmVudCwgcmVzcG9uc2U6IGRhdGF9XG4gICAgcmV0dXJuIHtqb2luX3JlZjogam9pblJlZiwgcmVmOiByZWYsIHRvcGljOiB0b3BpYywgZXZlbnQ6IENIQU5ORUxfRVZFTlRTLnJlcGx5LCBwYXlsb2FkOiBwYXlsb2FkfVxuICB9LFxuXG4gIGRlY29kZUJyb2FkY2FzdChidWZmZXIsIHZpZXcsIGRlY29kZXIpe1xuICAgIGxldCB0b3BpY1NpemUgPSB2aWV3LmdldFVpbnQ4KDEpXG4gICAgbGV0IGV2ZW50U2l6ZSA9IHZpZXcuZ2V0VWludDgoMilcbiAgICBsZXQgb2Zmc2V0ID0gdGhpcy5IRUFERVJfTEVOR1RIICsgMlxuICAgIGxldCB0b3BpYyA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIHRvcGljU2l6ZSkpXG4gICAgb2Zmc2V0ID0gb2Zmc2V0ICsgdG9waWNTaXplXG4gICAgbGV0IGV2ZW50ID0gZGVjb2Rlci5kZWNvZGUoYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgZXZlbnRTaXplKSlcbiAgICBvZmZzZXQgPSBvZmZzZXQgKyBldmVudFNpemVcbiAgICBsZXQgZGF0YSA9IGJ1ZmZlci5zbGljZShvZmZzZXQsIGJ1ZmZlci5ieXRlTGVuZ3RoKVxuXG4gICAgcmV0dXJuIHtqb2luX3JlZjogbnVsbCwgcmVmOiBudWxsLCB0b3BpYzogdG9waWMsIGV2ZW50OiBldmVudCwgcGF5bG9hZDogZGF0YX1cbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIGdsb2JhbCxcbiAgcGh4V2luZG93LFxuICBDSEFOTkVMX0VWRU5UUyxcbiAgREVGQVVMVF9USU1FT1VULFxuICBERUZBVUxUX1ZTTixcbiAgU09DS0VUX1NUQVRFUyxcbiAgVFJBTlNQT1JUUyxcbiAgV1NfQ0xPU0VfTk9STUFMXG59IGZyb20gXCIuL2NvbnN0YW50c1wiXG5cbmltcG9ydCB7XG4gIGNsb3N1cmVcbn0gZnJvbSBcIi4vdXRpbHNcIlxuXG5pbXBvcnQgQWpheCBmcm9tIFwiLi9hamF4XCJcbmltcG9ydCBDaGFubmVsIGZyb20gXCIuL2NoYW5uZWxcIlxuaW1wb3J0IExvbmdQb2xsIGZyb20gXCIuL2xvbmdwb2xsXCJcbmltcG9ydCBTZXJpYWxpemVyIGZyb20gXCIuL3NlcmlhbGl6ZXJcIlxuaW1wb3J0IFRpbWVyIGZyb20gXCIuL3RpbWVyXCJcblxuLyoqIEluaXRpYWxpemVzIHRoZSBTb2NrZXQgKlxuICpcbiAqIEZvciBJRTggc3VwcG9ydCB1c2UgYW4gRVM1LXNoaW0gKGh0dHBzOi8vZ2l0aHViLmNvbS9lcy1zaGltcy9lczUtc2hpbSlcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZW5kUG9pbnQgLSBUaGUgc3RyaW5nIFdlYlNvY2tldCBlbmRwb2ludCwgaWUsIGBcIndzOi8vZXhhbXBsZS5jb20vc29ja2V0XCJgLFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBcIndzczovL2V4YW1wbGUuY29tXCJgXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYFwiL3NvY2tldFwiYCAoaW5oZXJpdGVkIGhvc3QgJiBwcm90b2NvbClcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0c10gLSBPcHRpb25hbCBjb25maWd1cmF0aW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0cy50cmFuc3BvcnRdIC0gVGhlIFdlYnNvY2tldCBUcmFuc3BvcnQsIGZvciBleGFtcGxlIFdlYlNvY2tldCBvciBQaG9lbml4LkxvbmdQb2xsLlxuICpcbiAqIERlZmF1bHRzIHRvIFdlYlNvY2tldCB3aXRoIGF1dG9tYXRpYyBMb25nUG9sbCBmYWxsYmFjay5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRzLmVuY29kZV0gLSBUaGUgZnVuY3Rpb24gdG8gZW5jb2RlIG91dGdvaW5nIG1lc3NhZ2VzLlxuICpcbiAqIERlZmF1bHRzIHRvIEpTT04gZW5jb2Rlci5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0cy5kZWNvZGVdIC0gVGhlIGZ1bmN0aW9uIHRvIGRlY29kZSBpbmNvbWluZyBtZXNzYWdlcy5cbiAqXG4gKiBEZWZhdWx0cyB0byBKU09OOlxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIChwYXlsb2FkLCBjYWxsYmFjaykgPT4gY2FsbGJhY2soSlNPTi5wYXJzZShwYXlsb2FkKSlcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy50aW1lb3V0XSAtIFRoZSBkZWZhdWx0IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIHRvIHRyaWdnZXIgcHVzaCB0aW1lb3V0cy5cbiAqXG4gKiBEZWZhdWx0cyBgREVGQVVMVF9USU1FT1VUYFxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmhlYXJ0YmVhdEludGVydmFsTXNdIC0gVGhlIG1pbGxpc2VjIGludGVydmFsIHRvIHNlbmQgYSBoZWFydGJlYXQgbWVzc2FnZVxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLnJlY29ubmVjdEFmdGVyTXNdIC0gVGhlIG9wdGlvbmFsIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgbWlsbGlzZWNcbiAqIHNvY2tldCByZWNvbm5lY3QgaW50ZXJ2YWwuXG4gKlxuICogRGVmYXVsdHMgdG8gc3RlcHBlZCBiYWNrb2ZmIG9mOlxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIGZ1bmN0aW9uKHRyaWVzKXtcbiAqICAgcmV0dXJuIFsxMCwgNTAsIDEwMCwgMTUwLCAyMDAsIDI1MCwgNTAwLCAxMDAwLCAyMDAwXVt0cmllcyAtIDFdIHx8IDUwMDBcbiAqIH1cbiAqIGBgYGBcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdHMucmVqb2luQWZ0ZXJNc10gLSBUaGUgb3B0aW9uYWwgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSBtaWxsaXNlY1xuICogcmVqb2luIGludGVydmFsIGZvciBpbmRpdmlkdWFsIGNoYW5uZWxzLlxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIGZ1bmN0aW9uKHRyaWVzKXtcbiAqICAgcmV0dXJuIFsxMDAwLCAyMDAwLCA1MDAwXVt0cmllcyAtIDFdIHx8IDEwMDAwXG4gKiB9XG4gKiBgYGBgXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdHMubG9nZ2VyXSAtIFRoZSBvcHRpb25hbCBmdW5jdGlvbiBmb3Igc3BlY2lhbGl6ZWQgbG9nZ2luZywgaWU6XG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogZnVuY3Rpb24oa2luZCwgbXNnLCBkYXRhKSB7XG4gKiAgIGNvbnNvbGUubG9nKGAke2tpbmR9OiAke21zZ31gLCBkYXRhKVxuICogfVxuICogYGBgXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmxvbmdwb2xsZXJUaW1lb3V0XSAtIFRoZSBtYXhpbXVtIHRpbWVvdXQgb2YgYSBsb25nIHBvbGwgQUpBWCByZXF1ZXN0LlxuICpcbiAqIERlZmF1bHRzIHRvIDIwcyAoZG91YmxlIHRoZSBzZXJ2ZXIgbG9uZyBwb2xsIHRpbWVyKS5cbiAqXG4gKiBAcGFyYW0geyhPYmplY3R8ZnVuY3Rpb24pfSBbb3B0cy5wYXJhbXNdIC0gVGhlIG9wdGlvbmFsIHBhcmFtcyB0byBwYXNzIHdoZW4gY29ubmVjdGluZ1xuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmJpbmFyeVR5cGVdIC0gVGhlIGJpbmFyeSB0eXBlIHRvIHVzZSBmb3IgYmluYXJ5IFdlYlNvY2tldCBmcmFtZXMuXG4gKlxuICogRGVmYXVsdHMgdG8gXCJhcnJheWJ1ZmZlclwiXG4gKlxuICogQHBhcmFtIHt2c259IFtvcHRzLnZzbl0gLSBUaGUgc2VyaWFsaXplcidzIHByb3RvY29sIHZlcnNpb24gdG8gc2VuZCBvbiBjb25uZWN0LlxuICpcbiAqIERlZmF1bHRzIHRvIERFRkFVTFRfVlNOLlxuKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNvY2tldCB7XG4gIGNvbnN0cnVjdG9yKGVuZFBvaW50LCBvcHRzID0ge30pe1xuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3MgPSB7b3BlbjogW10sIGNsb3NlOiBbXSwgZXJyb3I6IFtdLCBtZXNzYWdlOiBbXX1cbiAgICB0aGlzLmNoYW5uZWxzID0gW11cbiAgICB0aGlzLnNlbmRCdWZmZXIgPSBbXVxuICAgIHRoaXMucmVmID0gMFxuICAgIHRoaXMudGltZW91dCA9IG9wdHMudGltZW91dCB8fCBERUZBVUxUX1RJTUVPVVRcbiAgICB0aGlzLnRyYW5zcG9ydCA9IG9wdHMudHJhbnNwb3J0IHx8IGdsb2JhbC5XZWJTb2NrZXQgfHwgTG9uZ1BvbGxcbiAgICB0aGlzLmVzdGFibGlzaGVkQ29ubmVjdGlvbnMgPSAwXG4gICAgdGhpcy5kZWZhdWx0RW5jb2RlciA9IFNlcmlhbGl6ZXIuZW5jb2RlLmJpbmQoU2VyaWFsaXplcilcbiAgICB0aGlzLmRlZmF1bHREZWNvZGVyID0gU2VyaWFsaXplci5kZWNvZGUuYmluZChTZXJpYWxpemVyKVxuICAgIHRoaXMuY2xvc2VXYXNDbGVhbiA9IGZhbHNlXG4gICAgdGhpcy5iaW5hcnlUeXBlID0gb3B0cy5iaW5hcnlUeXBlIHx8IFwiYXJyYXlidWZmZXJcIlxuICAgIHRoaXMuY29ubmVjdENsb2NrID0gMVxuICAgIGlmKHRoaXMudHJhbnNwb3J0ICE9PSBMb25nUG9sbCl7XG4gICAgICB0aGlzLmVuY29kZSA9IG9wdHMuZW5jb2RlIHx8IHRoaXMuZGVmYXVsdEVuY29kZXJcbiAgICAgIHRoaXMuZGVjb2RlID0gb3B0cy5kZWNvZGUgfHwgdGhpcy5kZWZhdWx0RGVjb2RlclxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmVuY29kZSA9IHRoaXMuZGVmYXVsdEVuY29kZXJcbiAgICAgIHRoaXMuZGVjb2RlID0gdGhpcy5kZWZhdWx0RGVjb2RlclxuICAgIH1cbiAgICBsZXQgYXdhaXRpbmdDb25uZWN0aW9uT25QYWdlU2hvdyA9IG51bGxcbiAgICBpZihwaHhXaW5kb3cgJiYgcGh4V2luZG93LmFkZEV2ZW50TGlzdGVuZXIpe1xuICAgICAgcGh4V2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJwYWdlaGlkZVwiLCBfZSA9PiB7XG4gICAgICAgIGlmKHRoaXMuY29ubil7XG4gICAgICAgICAgdGhpcy5kaXNjb25uZWN0KClcbiAgICAgICAgICBhd2FpdGluZ0Nvbm5lY3Rpb25PblBhZ2VTaG93ID0gdGhpcy5jb25uZWN0Q2xvY2tcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIHBoeFdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicGFnZXNob3dcIiwgX2UgPT4ge1xuICAgICAgICBpZihhd2FpdGluZ0Nvbm5lY3Rpb25PblBhZ2VTaG93ID09PSB0aGlzLmNvbm5lY3RDbG9jayl7XG4gICAgICAgICAgYXdhaXRpbmdDb25uZWN0aW9uT25QYWdlU2hvdyA9IG51bGxcbiAgICAgICAgICB0aGlzLmNvbm5lY3QoKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgICB0aGlzLmhlYXJ0YmVhdEludGVydmFsTXMgPSBvcHRzLmhlYXJ0YmVhdEludGVydmFsTXMgfHwgMzAwMDBcbiAgICB0aGlzLnJlam9pbkFmdGVyTXMgPSAodHJpZXMpID0+IHtcbiAgICAgIGlmKG9wdHMucmVqb2luQWZ0ZXJNcyl7XG4gICAgICAgIHJldHVybiBvcHRzLnJlam9pbkFmdGVyTXModHJpZXMpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gWzEwMDAsIDIwMDAsIDUwMDBdW3RyaWVzIC0gMV0gfHwgMTAwMDBcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5yZWNvbm5lY3RBZnRlck1zID0gKHRyaWVzKSA9PiB7XG4gICAgICBpZihvcHRzLnJlY29ubmVjdEFmdGVyTXMpe1xuICAgICAgICByZXR1cm4gb3B0cy5yZWNvbm5lY3RBZnRlck1zKHRyaWVzKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFsxMCwgNTAsIDEwMCwgMTUwLCAyMDAsIDI1MCwgNTAwLCAxMDAwLCAyMDAwXVt0cmllcyAtIDFdIHx8IDUwMDBcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5sb2dnZXIgPSBvcHRzLmxvZ2dlciB8fCBudWxsXG4gICAgdGhpcy5sb25ncG9sbGVyVGltZW91dCA9IG9wdHMubG9uZ3BvbGxlclRpbWVvdXQgfHwgMjAwMDBcbiAgICB0aGlzLnBhcmFtcyA9IGNsb3N1cmUob3B0cy5wYXJhbXMgfHwge30pXG4gICAgdGhpcy5lbmRQb2ludCA9IGAke2VuZFBvaW50fS8ke1RSQU5TUE9SVFMud2Vic29ja2V0fWBcbiAgICB0aGlzLnZzbiA9IG9wdHMudnNuIHx8IERFRkFVTFRfVlNOXG4gICAgdGhpcy5oZWFydGJlYXRUaW1lb3V0VGltZXIgPSBudWxsXG4gICAgdGhpcy5oZWFydGJlYXRUaW1lciA9IG51bGxcbiAgICB0aGlzLnBlbmRpbmdIZWFydGJlYXRSZWYgPSBudWxsXG4gICAgdGhpcy5yZWNvbm5lY3RUaW1lciA9IG5ldyBUaW1lcigoKSA9PiB7XG4gICAgICB0aGlzLnRlYXJkb3duKCgpID0+IHRoaXMuY29ubmVjdCgpKVxuICAgIH0sIHRoaXMucmVjb25uZWN0QWZ0ZXJNcylcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBMb25nUG9sbCB0cmFuc3BvcnQgcmVmZXJlbmNlXG4gICAqL1xuICBnZXRMb25nUG9sbFRyYW5zcG9ydCgpeyByZXR1cm4gTG9uZ1BvbGwgfVxuXG4gIC8qKlxuICAgKiBEaXNjb25uZWN0cyBhbmQgcmVwbGFjZXMgdGhlIGFjdGl2ZSB0cmFuc3BvcnRcbiAgICpcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gbmV3VHJhbnNwb3J0IC0gVGhlIG5ldyB0cmFuc3BvcnQgY2xhc3MgdG8gaW5zdGFudGlhdGVcbiAgICpcbiAgICovXG4gIHJlcGxhY2VUcmFuc3BvcnQobmV3VHJhbnNwb3J0KXtcbiAgICB0aGlzLmNvbm5lY3RDbG9jaysrXG4gICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gdHJ1ZVxuICAgIHRoaXMucmVjb25uZWN0VGltZXIucmVzZXQoKVxuICAgIHRoaXMuc2VuZEJ1ZmZlciA9IFtdXG4gICAgaWYodGhpcy5jb25uKXtcbiAgICAgIHRoaXMuY29ubi5jbG9zZSgpXG4gICAgICB0aGlzLmNvbm4gPSBudWxsXG4gICAgfVxuICAgIHRoaXMudHJhbnNwb3J0ID0gbmV3VHJhbnNwb3J0XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgc29ja2V0IHByb3RvY29sXG4gICAqXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAqL1xuICBwcm90b2NvbCgpeyByZXR1cm4gbG9jYXRpb24ucHJvdG9jb2wubWF0Y2goL15odHRwcy8pID8gXCJ3c3NcIiA6IFwid3NcIiB9XG5cbiAgLyoqXG4gICAqIFRoZSBmdWxseSBxdWFsaWZpZWQgc29ja2V0IHVybFxuICAgKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgKi9cbiAgZW5kUG9pbnRVUkwoKXtcbiAgICBsZXQgdXJpID0gQWpheC5hcHBlbmRQYXJhbXMoXG4gICAgICBBamF4LmFwcGVuZFBhcmFtcyh0aGlzLmVuZFBvaW50LCB0aGlzLnBhcmFtcygpKSwge3ZzbjogdGhpcy52c259KVxuICAgIGlmKHVyaS5jaGFyQXQoMCkgIT09IFwiL1wiKXsgcmV0dXJuIHVyaSB9XG4gICAgaWYodXJpLmNoYXJBdCgxKSA9PT0gXCIvXCIpeyByZXR1cm4gYCR7dGhpcy5wcm90b2NvbCgpfToke3VyaX1gIH1cblxuICAgIHJldHVybiBgJHt0aGlzLnByb3RvY29sKCl9Oi8vJHtsb2NhdGlvbi5ob3N0fSR7dXJpfWBcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNjb25uZWN0cyB0aGUgc29ja2V0XG4gICAqXG4gICAqIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvQ2xvc2VFdmVudCNTdGF0dXNfY29kZXMgZm9yIHZhbGlkIHN0YXR1cyBjb2Rlcy5cbiAgICpcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgLSBPcHRpb25hbCBjYWxsYmFjayB3aGljaCBpcyBjYWxsZWQgYWZ0ZXIgc29ja2V0IGlzIGRpc2Nvbm5lY3RlZC5cbiAgICogQHBhcmFtIHtpbnRlZ2VyfSBjb2RlIC0gQSBzdGF0dXMgY29kZSBmb3IgZGlzY29ubmVjdGlvbiAoT3B0aW9uYWwpLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmVhc29uIC0gQSB0ZXh0dWFsIGRlc2NyaXB0aW9uIG9mIHRoZSByZWFzb24gdG8gZGlzY29ubmVjdC4gKE9wdGlvbmFsKVxuICAgKi9cbiAgZGlzY29ubmVjdChjYWxsYmFjaywgY29kZSwgcmVhc29uKXtcbiAgICB0aGlzLmNvbm5lY3RDbG9jaysrXG4gICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gdHJ1ZVxuICAgIHRoaXMucmVjb25uZWN0VGltZXIucmVzZXQoKVxuICAgIHRoaXMudGVhcmRvd24oY2FsbGJhY2ssIGNvZGUsIHJlYXNvbilcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtcyB0byBzZW5kIHdoZW4gY29ubmVjdGluZywgZm9yIGV4YW1wbGUgYHt1c2VyX2lkOiB1c2VyVG9rZW59YFxuICAgKlxuICAgKiBQYXNzaW5nIHBhcmFtcyB0byBjb25uZWN0IGlzIGRlcHJlY2F0ZWQ7IHBhc3MgdGhlbSBpbiB0aGUgU29ja2V0IGNvbnN0cnVjdG9yIGluc3RlYWQ6XG4gICAqIGBuZXcgU29ja2V0KFwiL3NvY2tldFwiLCB7cGFyYW1zOiB7dXNlcl9pZDogdXNlclRva2VufX0pYC5cbiAgICovXG4gIGNvbm5lY3QocGFyYW1zKXtcbiAgICBpZihwYXJhbXMpe1xuICAgICAgY29uc29sZSAmJiBjb25zb2xlLmxvZyhcInBhc3NpbmcgcGFyYW1zIHRvIGNvbm5lY3QgaXMgZGVwcmVjYXRlZC4gSW5zdGVhZCBwYXNzIDpwYXJhbXMgdG8gdGhlIFNvY2tldCBjb25zdHJ1Y3RvclwiKVxuICAgICAgdGhpcy5wYXJhbXMgPSBjbG9zdXJlKHBhcmFtcylcbiAgICB9XG4gICAgaWYodGhpcy5jb25uKXsgcmV0dXJuIH1cblxuICAgIHRoaXMuY29ubmVjdENsb2NrKytcbiAgICB0aGlzLmNsb3NlV2FzQ2xlYW4gPSBmYWxzZVxuICAgIHRoaXMuY29ubiA9IG5ldyB0aGlzLnRyYW5zcG9ydCh0aGlzLmVuZFBvaW50VVJMKCkpXG4gICAgdGhpcy5jb25uLmJpbmFyeVR5cGUgPSB0aGlzLmJpbmFyeVR5cGVcbiAgICB0aGlzLmNvbm4udGltZW91dCA9IHRoaXMubG9uZ3BvbGxlclRpbWVvdXRcbiAgICB0aGlzLmNvbm4ub25vcGVuID0gKCkgPT4gdGhpcy5vbkNvbm5PcGVuKClcbiAgICB0aGlzLmNvbm4ub25lcnJvciA9IGVycm9yID0+IHRoaXMub25Db25uRXJyb3IoZXJyb3IpXG4gICAgdGhpcy5jb25uLm9ubWVzc2FnZSA9IGV2ZW50ID0+IHRoaXMub25Db25uTWVzc2FnZShldmVudClcbiAgICB0aGlzLmNvbm4ub25jbG9zZSA9IGV2ZW50ID0+IHRoaXMub25Db25uQ2xvc2UoZXZlbnQpXG4gIH1cblxuICAvKipcbiAgICogTG9ncyB0aGUgbWVzc2FnZS4gT3ZlcnJpZGUgYHRoaXMubG9nZ2VyYCBmb3Igc3BlY2lhbGl6ZWQgbG9nZ2luZy4gbm9vcHMgYnkgZGVmYXVsdFxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2luZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gbXNnXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhXG4gICAqL1xuICBsb2coa2luZCwgbXNnLCBkYXRhKXsgdGhpcy5sb2dnZXIoa2luZCwgbXNnLCBkYXRhKSB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiBhIGxvZ2dlciBoYXMgYmVlbiBzZXQgb24gdGhpcyBzb2NrZXQuXG4gICAqL1xuICBoYXNMb2dnZXIoKXsgcmV0dXJuIHRoaXMubG9nZ2VyICE9PSBudWxsIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGNhbGxiYWNrcyBmb3IgY29ubmVjdGlvbiBvcGVuIGV2ZW50c1xuICAgKlxuICAgKiBAZXhhbXBsZSBzb2NrZXQub25PcGVuKGZ1bmN0aW9uKCl7IGNvbnNvbGUuaW5mbyhcInRoZSBzb2NrZXQgd2FzIG9wZW5lZFwiKSB9KVxuICAgKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgb25PcGVuKGNhbGxiYWNrKXtcbiAgICBsZXQgcmVmID0gdGhpcy5tYWtlUmVmKClcbiAgICB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzLm9wZW4ucHVzaChbcmVmLCBjYWxsYmFja10pXG4gICAgcmV0dXJuIHJlZlxuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyBjYWxsYmFja3MgZm9yIGNvbm5lY3Rpb24gY2xvc2UgZXZlbnRzXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBvbkNsb3NlKGNhbGxiYWNrKXtcbiAgICBsZXQgcmVmID0gdGhpcy5tYWtlUmVmKClcbiAgICB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzLmNsb3NlLnB1c2goW3JlZiwgY2FsbGJhY2tdKVxuICAgIHJldHVybiByZWZcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgY2FsbGJhY2tzIGZvciBjb25uZWN0aW9uIGVycm9yIGV2ZW50c1xuICAgKlxuICAgKiBAZXhhbXBsZSBzb2NrZXQub25FcnJvcihmdW5jdGlvbihlcnJvcil7IGFsZXJ0KFwiQW4gZXJyb3Igb2NjdXJyZWRcIikgfSlcbiAgICpcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIG9uRXJyb3IoY2FsbGJhY2spe1xuICAgIGxldCByZWYgPSB0aGlzLm1ha2VSZWYoKVxuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3MuZXJyb3IucHVzaChbcmVmLCBjYWxsYmFja10pXG4gICAgcmV0dXJuIHJlZlxuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyBjYWxsYmFja3MgZm9yIGNvbm5lY3Rpb24gbWVzc2FnZSBldmVudHNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIG9uTWVzc2FnZShjYWxsYmFjayl7XG4gICAgbGV0IHJlZiA9IHRoaXMubWFrZVJlZigpXG4gICAgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcy5tZXNzYWdlLnB1c2goW3JlZiwgY2FsbGJhY2tdKVxuICAgIHJldHVybiByZWZcbiAgfVxuXG4gIC8qKlxuICAgKiBQaW5ncyB0aGUgc2VydmVyIGFuZCBpbnZva2VzIHRoZSBjYWxsYmFjayB3aXRoIHRoZSBSVFQgaW4gbWlsbGlzZWNvbmRzXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgcGluZyB3YXMgcHVzaGVkIG9yIGZhbHNlIGlmIHVuYWJsZSB0byBiZSBwdXNoZWQuXG4gICAqL1xuICBwaW5nKGNhbGxiYWNrKXtcbiAgICBpZighdGhpcy5pc0Nvbm5lY3RlZCgpKXsgcmV0dXJuIGZhbHNlIH1cbiAgICBsZXQgcmVmID0gdGhpcy5tYWtlUmVmKClcbiAgICBsZXQgc3RhcnRUaW1lID0gRGF0ZS5ub3coKVxuICAgIHRoaXMucHVzaCh7dG9waWM6IFwicGhvZW5peFwiLCBldmVudDogXCJoZWFydGJlYXRcIiwgcGF5bG9hZDoge30sIHJlZjogcmVmfSlcbiAgICBsZXQgb25Nc2dSZWYgPSB0aGlzLm9uTWVzc2FnZShtc2cgPT4ge1xuICAgICAgaWYobXNnLnJlZiA9PT0gcmVmKXtcbiAgICAgICAgdGhpcy5vZmYoW29uTXNnUmVmXSlcbiAgICAgICAgY2FsbGJhY2soRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSlcbiAgICAgIH1cbiAgICB9KVxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cbiAgY2xlYXJIZWFydGJlYXRzKCl7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuaGVhcnRiZWF0VGltZXIpXG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuaGVhcnRiZWF0VGltZW91dFRpbWVyKVxuICB9XG5cbiAgb25Db25uT3Blbigpe1xuICAgIGlmKHRoaXMuaGFzTG9nZ2VyKCkpIHRoaXMubG9nKFwidHJhbnNwb3J0XCIsIGBjb25uZWN0ZWQgdG8gJHt0aGlzLmVuZFBvaW50VVJMKCl9YClcbiAgICB0aGlzLmNsb3NlV2FzQ2xlYW4gPSBmYWxzZVxuICAgIHRoaXMuZXN0YWJsaXNoZWRDb25uZWN0aW9ucysrXG4gICAgdGhpcy5mbHVzaFNlbmRCdWZmZXIoKVxuICAgIHRoaXMucmVjb25uZWN0VGltZXIucmVzZXQoKVxuICAgIHRoaXMucmVzZXRIZWFydGJlYXQoKVxuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3Mub3Blbi5mb3JFYWNoKChbLCBjYWxsYmFja10pID0+IGNhbGxiYWNrKCkpXG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cbiAgaGVhcnRiZWF0VGltZW91dCgpe1xuICAgIGlmKHRoaXMucGVuZGluZ0hlYXJ0YmVhdFJlZil7XG4gICAgICB0aGlzLnBlbmRpbmdIZWFydGJlYXRSZWYgPSBudWxsXG4gICAgICBpZih0aGlzLmhhc0xvZ2dlcigpKXsgdGhpcy5sb2coXCJ0cmFuc3BvcnRcIiwgXCJoZWFydGJlYXQgdGltZW91dC4gQXR0ZW1wdGluZyB0byByZS1lc3RhYmxpc2ggY29ubmVjdGlvblwiKSB9XG4gICAgICB0aGlzLnRyaWdnZXJDaGFuRXJyb3IoKVxuICAgICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gZmFsc2VcbiAgICAgIHRoaXMudGVhcmRvd24oKCkgPT4gdGhpcy5yZWNvbm5lY3RUaW1lci5zY2hlZHVsZVRpbWVvdXQoKSwgV1NfQ0xPU0VfTk9STUFMLCBcImhlYXJ0YmVhdCB0aW1lb3V0XCIpXG4gICAgfVxuICB9XG5cbiAgcmVzZXRIZWFydGJlYXQoKXtcbiAgICBpZih0aGlzLmNvbm4gJiYgdGhpcy5jb25uLnNraXBIZWFydGJlYXQpeyByZXR1cm4gfVxuICAgIHRoaXMucGVuZGluZ0hlYXJ0YmVhdFJlZiA9IG51bGxcbiAgICB0aGlzLmNsZWFySGVhcnRiZWF0cygpXG4gICAgdGhpcy5oZWFydGJlYXRUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zZW5kSGVhcnRiZWF0KCksIHRoaXMuaGVhcnRiZWF0SW50ZXJ2YWxNcylcbiAgfVxuXG4gIHRlYXJkb3duKGNhbGxiYWNrLCBjb2RlLCByZWFzb24pe1xuICAgIGlmKCF0aGlzLmNvbm4pe1xuICAgICAgcmV0dXJuIGNhbGxiYWNrICYmIGNhbGxiYWNrKClcbiAgICB9XG5cbiAgICB0aGlzLndhaXRGb3JCdWZmZXJEb25lKCgpID0+IHtcbiAgICAgIGlmKHRoaXMuY29ubil7XG4gICAgICAgIGlmKGNvZGUpeyB0aGlzLmNvbm4uY2xvc2UoY29kZSwgcmVhc29uIHx8IFwiXCIpIH0gZWxzZSB7IHRoaXMuY29ubi5jbG9zZSgpIH1cbiAgICAgIH1cblxuICAgICAgdGhpcy53YWl0Rm9yU29ja2V0Q2xvc2VkKCgpID0+IHtcbiAgICAgICAgaWYodGhpcy5jb25uKXtcbiAgICAgICAgICB0aGlzLmNvbm4ub25vcGVuID0gZnVuY3Rpb24gKCl7IH0gLy8gbm9vcFxuICAgICAgICAgIHRoaXMuY29ubi5vbmVycm9yID0gZnVuY3Rpb24gKCl7IH0gLy8gbm9vcFxuICAgICAgICAgIHRoaXMuY29ubi5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAoKXsgfSAvLyBub29wXG4gICAgICAgICAgdGhpcy5jb25uLm9uY2xvc2UgPSBmdW5jdGlvbiAoKXsgfSAvLyBub29wXG4gICAgICAgICAgdGhpcy5jb25uID0gbnVsbFxuICAgICAgICB9XG5cbiAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgd2FpdEZvckJ1ZmZlckRvbmUoY2FsbGJhY2ssIHRyaWVzID0gMSl7XG4gICAgaWYodHJpZXMgPT09IDUgfHwgIXRoaXMuY29ubiB8fCAhdGhpcy5jb25uLmJ1ZmZlcmVkQW1vdW50KXtcbiAgICAgIGNhbGxiYWNrKClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy53YWl0Rm9yQnVmZmVyRG9uZShjYWxsYmFjaywgdHJpZXMgKyAxKVxuICAgIH0sIDE1MCAqIHRyaWVzKVxuICB9XG5cbiAgd2FpdEZvclNvY2tldENsb3NlZChjYWxsYmFjaywgdHJpZXMgPSAxKXtcbiAgICBpZih0cmllcyA9PT0gNSB8fCAhdGhpcy5jb25uIHx8IHRoaXMuY29ubi5yZWFkeVN0YXRlID09PSBTT0NLRVRfU1RBVEVTLmNsb3NlZCl7XG4gICAgICBjYWxsYmFjaygpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMud2FpdEZvclNvY2tldENsb3NlZChjYWxsYmFjaywgdHJpZXMgKyAxKVxuICAgIH0sIDE1MCAqIHRyaWVzKVxuICB9XG5cbiAgb25Db25uQ2xvc2UoZXZlbnQpe1xuICAgIGxldCBjbG9zZUNvZGUgPSBldmVudCAmJiBldmVudC5jb2RlXG4gICAgaWYodGhpcy5oYXNMb2dnZXIoKSkgdGhpcy5sb2coXCJ0cmFuc3BvcnRcIiwgXCJjbG9zZVwiLCBldmVudClcbiAgICB0aGlzLnRyaWdnZXJDaGFuRXJyb3IoKVxuICAgIHRoaXMuY2xlYXJIZWFydGJlYXRzKClcbiAgICBpZighdGhpcy5jbG9zZVdhc0NsZWFuICYmIGNsb3NlQ29kZSAhPT0gMTAwMCl7XG4gICAgICB0aGlzLnJlY29ubmVjdFRpbWVyLnNjaGVkdWxlVGltZW91dCgpXG4gICAgfVxuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3MuY2xvc2UuZm9yRWFjaCgoWywgY2FsbGJhY2tdKSA9PiBjYWxsYmFjayhldmVudCkpXG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIG9uQ29ubkVycm9yKGVycm9yKXtcbiAgICBpZih0aGlzLmhhc0xvZ2dlcigpKSB0aGlzLmxvZyhcInRyYW5zcG9ydFwiLCBlcnJvcilcbiAgICBsZXQgdHJhbnNwb3J0QmVmb3JlID0gdGhpcy50cmFuc3BvcnRcbiAgICBsZXQgZXN0YWJsaXNoZWRCZWZvcmUgPSB0aGlzLmVzdGFibGlzaGVkQ29ubmVjdGlvbnNcbiAgICB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzLmVycm9yLmZvckVhY2goKFssIGNhbGxiYWNrXSkgPT4ge1xuICAgICAgY2FsbGJhY2soZXJyb3IsIHRyYW5zcG9ydEJlZm9yZSwgZXN0YWJsaXNoZWRCZWZvcmUpXG4gICAgfSlcbiAgICBpZih0cmFuc3BvcnRCZWZvcmUgPT09IHRoaXMudHJhbnNwb3J0IHx8IGVzdGFibGlzaGVkQmVmb3JlID4gMCl7XG4gICAgICB0aGlzLnRyaWdnZXJDaGFuRXJyb3IoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgdHJpZ2dlckNoYW5FcnJvcigpe1xuICAgIHRoaXMuY2hhbm5lbHMuZm9yRWFjaChjaGFubmVsID0+IHtcbiAgICAgIGlmKCEoY2hhbm5lbC5pc0Vycm9yZWQoKSB8fCBjaGFubmVsLmlzTGVhdmluZygpIHx8IGNoYW5uZWwuaXNDbG9zZWQoKSkpe1xuICAgICAgICBjaGFubmVsLnRyaWdnZXIoQ0hBTk5FTF9FVkVOVFMuZXJyb3IpXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgKi9cbiAgY29ubmVjdGlvblN0YXRlKCl7XG4gICAgc3dpdGNoKHRoaXMuY29ubiAmJiB0aGlzLmNvbm4ucmVhZHlTdGF0ZSl7XG4gICAgICBjYXNlIFNPQ0tFVF9TVEFURVMuY29ubmVjdGluZzogcmV0dXJuIFwiY29ubmVjdGluZ1wiXG4gICAgICBjYXNlIFNPQ0tFVF9TVEFURVMub3BlbjogcmV0dXJuIFwib3BlblwiXG4gICAgICBjYXNlIFNPQ0tFVF9TVEFURVMuY2xvc2luZzogcmV0dXJuIFwiY2xvc2luZ1wiXG4gICAgICBkZWZhdWx0OiByZXR1cm4gXCJjbG9zZWRcIlxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICovXG4gIGlzQ29ubmVjdGVkKCl7IHJldHVybiB0aGlzLmNvbm5lY3Rpb25TdGF0ZSgpID09PSBcIm9wZW5cIiB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqXG4gICAqIEBwYXJhbSB7Q2hhbm5lbH1cbiAgICovXG4gIHJlbW92ZShjaGFubmVsKXtcbiAgICB0aGlzLm9mZihjaGFubmVsLnN0YXRlQ2hhbmdlUmVmcylcbiAgICB0aGlzLmNoYW5uZWxzID0gdGhpcy5jaGFubmVscy5maWx0ZXIoYyA9PiBjLmpvaW5SZWYoKSAhPT0gY2hhbm5lbC5qb2luUmVmKCkpXG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBgb25PcGVuYCwgYG9uQ2xvc2VgLCBgb25FcnJvcixgIGFuZCBgb25NZXNzYWdlYCByZWdpc3RyYXRpb25zLlxuICAgKlxuICAgKiBAcGFyYW0ge3JlZnN9IC0gbGlzdCBvZiByZWZzIHJldHVybmVkIGJ5IGNhbGxzIHRvXG4gICAqICAgICAgICAgICAgICAgICBgb25PcGVuYCwgYG9uQ2xvc2VgLCBgb25FcnJvcixgIGFuZCBgb25NZXNzYWdlYFxuICAgKi9cbiAgb2ZmKHJlZnMpe1xuICAgIGZvcihsZXQga2V5IGluIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3Mpe1xuICAgICAgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrc1trZXldID0gdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrc1trZXldLmZpbHRlcigoW3JlZl0pID0+IHtcbiAgICAgICAgcmV0dXJuIHJlZnMuaW5kZXhPZihyZWYpID09PSAtMVxuICAgICAgfSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhdGVzIGEgbmV3IGNoYW5uZWwgZm9yIHRoZSBnaXZlbiB0b3BpY1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9waWNcbiAgICogQHBhcmFtIHtPYmplY3R9IGNoYW5QYXJhbXMgLSBQYXJhbWV0ZXJzIGZvciB0aGUgY2hhbm5lbFxuICAgKiBAcmV0dXJucyB7Q2hhbm5lbH1cbiAgICovXG4gIGNoYW5uZWwodG9waWMsIGNoYW5QYXJhbXMgPSB7fSl7XG4gICAgbGV0IGNoYW4gPSBuZXcgQ2hhbm5lbCh0b3BpYywgY2hhblBhcmFtcywgdGhpcylcbiAgICB0aGlzLmNoYW5uZWxzLnB1c2goY2hhbilcbiAgICByZXR1cm4gY2hhblxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhXG4gICAqL1xuICBwdXNoKGRhdGEpe1xuICAgIGlmKHRoaXMuaGFzTG9nZ2VyKCkpe1xuICAgICAgbGV0IHt0b3BpYywgZXZlbnQsIHBheWxvYWQsIHJlZiwgam9pbl9yZWZ9ID0gZGF0YVxuICAgICAgdGhpcy5sb2coXCJwdXNoXCIsIGAke3RvcGljfSAke2V2ZW50fSAoJHtqb2luX3JlZn0sICR7cmVmfSlgLCBwYXlsb2FkKVxuICAgIH1cblxuICAgIGlmKHRoaXMuaXNDb25uZWN0ZWQoKSl7XG4gICAgICB0aGlzLmVuY29kZShkYXRhLCByZXN1bHQgPT4gdGhpcy5jb25uLnNlbmQocmVzdWx0KSlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZW5kQnVmZmVyLnB1c2goKCkgPT4gdGhpcy5lbmNvZGUoZGF0YSwgcmVzdWx0ID0+IHRoaXMuY29ubi5zZW5kKHJlc3VsdCkpKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIG5leHQgbWVzc2FnZSByZWYsIGFjY291bnRpbmcgZm9yIG92ZXJmbG93c1xuICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgKi9cbiAgbWFrZVJlZigpe1xuICAgIGxldCBuZXdSZWYgPSB0aGlzLnJlZiArIDFcbiAgICBpZihuZXdSZWYgPT09IHRoaXMucmVmKXsgdGhpcy5yZWYgPSAwIH0gZWxzZSB7IHRoaXMucmVmID0gbmV3UmVmIH1cblxuICAgIHJldHVybiB0aGlzLnJlZi50b1N0cmluZygpXG4gIH1cblxuICBzZW5kSGVhcnRiZWF0KCl7XG4gICAgaWYodGhpcy5wZW5kaW5nSGVhcnRiZWF0UmVmICYmICF0aGlzLmlzQ29ubmVjdGVkKCkpeyByZXR1cm4gfVxuICAgIHRoaXMucGVuZGluZ0hlYXJ0YmVhdFJlZiA9IHRoaXMubWFrZVJlZigpXG4gICAgdGhpcy5wdXNoKHt0b3BpYzogXCJwaG9lbml4XCIsIGV2ZW50OiBcImhlYXJ0YmVhdFwiLCBwYXlsb2FkOiB7fSwgcmVmOiB0aGlzLnBlbmRpbmdIZWFydGJlYXRSZWZ9KVxuICAgIHRoaXMuaGVhcnRiZWF0VGltZW91dFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB0aGlzLmhlYXJ0YmVhdFRpbWVvdXQoKSwgdGhpcy5oZWFydGJlYXRJbnRlcnZhbE1zKVxuICB9XG5cbiAgZmx1c2hTZW5kQnVmZmVyKCl7XG4gICAgaWYodGhpcy5pc0Nvbm5lY3RlZCgpICYmIHRoaXMuc2VuZEJ1ZmZlci5sZW5ndGggPiAwKXtcbiAgICAgIHRoaXMuc2VuZEJ1ZmZlci5mb3JFYWNoKGNhbGxiYWNrID0+IGNhbGxiYWNrKCkpXG4gICAgICB0aGlzLnNlbmRCdWZmZXIgPSBbXVxuICAgIH1cbiAgfVxuXG4gIG9uQ29ubk1lc3NhZ2UocmF3TWVzc2FnZSl7XG4gICAgdGhpcy5kZWNvZGUocmF3TWVzc2FnZS5kYXRhLCBtc2cgPT4ge1xuICAgICAgbGV0IHt0b3BpYywgZXZlbnQsIHBheWxvYWQsIHJlZiwgam9pbl9yZWZ9ID0gbXNnXG4gICAgICBpZihyZWYgJiYgcmVmID09PSB0aGlzLnBlbmRpbmdIZWFydGJlYXRSZWYpe1xuICAgICAgICB0aGlzLmNsZWFySGVhcnRiZWF0cygpXG4gICAgICAgIHRoaXMucGVuZGluZ0hlYXJ0YmVhdFJlZiA9IG51bGxcbiAgICAgICAgdGhpcy5oZWFydGJlYXRUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zZW5kSGVhcnRiZWF0KCksIHRoaXMuaGVhcnRiZWF0SW50ZXJ2YWxNcylcbiAgICAgIH1cblxuICAgICAgaWYodGhpcy5oYXNMb2dnZXIoKSkgdGhpcy5sb2coXCJyZWNlaXZlXCIsIGAke3BheWxvYWQuc3RhdHVzIHx8IFwiXCJ9ICR7dG9waWN9ICR7ZXZlbnR9ICR7cmVmICYmIFwiKFwiICsgcmVmICsgXCIpXCIgfHwgXCJcIn1gLCBwYXlsb2FkKVxuXG4gICAgICBmb3IobGV0IGkgPSAwOyBpIDwgdGhpcy5jaGFubmVscy5sZW5ndGg7IGkrKyl7XG4gICAgICAgIGNvbnN0IGNoYW5uZWwgPSB0aGlzLmNoYW5uZWxzW2ldXG4gICAgICAgIGlmKCFjaGFubmVsLmlzTWVtYmVyKHRvcGljLCBldmVudCwgcGF5bG9hZCwgam9pbl9yZWYpKXsgY29udGludWUgfVxuICAgICAgICBjaGFubmVsLnRyaWdnZXIoZXZlbnQsIHBheWxvYWQsIHJlZiwgam9pbl9yZWYpXG4gICAgICB9XG5cbiAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzLm1lc3NhZ2UubGVuZ3RoOyBpKyspe1xuICAgICAgICBsZXQgWywgY2FsbGJhY2tdID0gdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcy5tZXNzYWdlW2ldXG4gICAgICAgIGNhbGxiYWNrKG1zZylcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgbGVhdmVPcGVuVG9waWModG9waWMpe1xuICAgIGxldCBkdXBDaGFubmVsID0gdGhpcy5jaGFubmVscy5maW5kKGMgPT4gYy50b3BpYyA9PT0gdG9waWMgJiYgKGMuaXNKb2luZWQoKSB8fCBjLmlzSm9pbmluZygpKSlcbiAgICBpZihkdXBDaGFubmVsKXtcbiAgICAgIGlmKHRoaXMuaGFzTG9nZ2VyKCkpIHRoaXMubG9nKFwidHJhbnNwb3J0XCIsIGBsZWF2aW5nIGR1cGxpY2F0ZSB0b3BpYyBcIiR7dG9waWN9XCJgKVxuICAgICAgZHVwQ2hhbm5lbC5sZWF2ZSgpXG4gICAgfVxuICB9XG59XG4iLCAiZXhwb3J0IGNvbnN0IENPTlNFQ1VUSVZFX1JFTE9BRFMgPSBcImNvbnNlY3V0aXZlLXJlbG9hZHNcIlxuZXhwb3J0IGNvbnN0IE1BWF9SRUxPQURTID0gMTBcbmV4cG9ydCBjb25zdCBSRUxPQURfSklUVEVSX01JTiA9IDUwMDBcbmV4cG9ydCBjb25zdCBSRUxPQURfSklUVEVSX01BWCA9IDEwMDAwXG5leHBvcnQgY29uc3QgRkFJTFNBRkVfSklUVEVSID0gMzAwMDBcbmV4cG9ydCBjb25zdCBQSFhfRVZFTlRfQ0xBU1NFUyA9IFtcbiAgXCJwaHgtY2xpY2stbG9hZGluZ1wiLCBcInBoeC1jaGFuZ2UtbG9hZGluZ1wiLCBcInBoeC1zdWJtaXQtbG9hZGluZ1wiLFxuICBcInBoeC1rZXlkb3duLWxvYWRpbmdcIiwgXCJwaHgta2V5dXAtbG9hZGluZ1wiLCBcInBoeC1ibHVyLWxvYWRpbmdcIiwgXCJwaHgtZm9jdXMtbG9hZGluZ1wiXG5dXG5leHBvcnQgY29uc3QgUEhYX0NPTVBPTkVOVCA9IFwiZGF0YS1waHgtY29tcG9uZW50XCJcbmV4cG9ydCBjb25zdCBQSFhfTElWRV9MSU5LID0gXCJkYXRhLXBoeC1saW5rXCJcbmV4cG9ydCBjb25zdCBQSFhfVFJBQ0tfU1RBVElDID0gXCJ0cmFjay1zdGF0aWNcIlxuZXhwb3J0IGNvbnN0IFBIWF9MSU5LX1NUQVRFID0gXCJkYXRhLXBoeC1saW5rLXN0YXRlXCJcbmV4cG9ydCBjb25zdCBQSFhfUkVGID0gXCJkYXRhLXBoeC1yZWZcIlxuZXhwb3J0IGNvbnN0IFBIWF9SRUZfU1JDID0gXCJkYXRhLXBoeC1yZWYtc3JjXCJcbmV4cG9ydCBjb25zdCBQSFhfVFJBQ0tfVVBMT0FEUyA9IFwidHJhY2stdXBsb2Fkc1wiXG5leHBvcnQgY29uc3QgUEhYX1VQTE9BRF9SRUYgPSBcImRhdGEtcGh4LXVwbG9hZC1yZWZcIlxuZXhwb3J0IGNvbnN0IFBIWF9QUkVGTElHSFRFRF9SRUZTID0gXCJkYXRhLXBoeC1wcmVmbGlnaHRlZC1yZWZzXCJcbmV4cG9ydCBjb25zdCBQSFhfRE9ORV9SRUZTID0gXCJkYXRhLXBoeC1kb25lLXJlZnNcIlxuZXhwb3J0IGNvbnN0IFBIWF9EUk9QX1RBUkdFVCA9IFwiZHJvcC10YXJnZXRcIlxuZXhwb3J0IGNvbnN0IFBIWF9BQ1RJVkVfRU5UUllfUkVGUyA9IFwiZGF0YS1waHgtYWN0aXZlLXJlZnNcIlxuZXhwb3J0IGNvbnN0IFBIWF9MSVZFX0ZJTEVfVVBEQVRFRCA9IFwicGh4OmxpdmUtZmlsZTp1cGRhdGVkXCJcbmV4cG9ydCBjb25zdCBQSFhfU0tJUCA9IFwiZGF0YS1waHgtc2tpcFwiXG5leHBvcnQgY29uc3QgUEhYX1BSVU5FID0gXCJkYXRhLXBoeC1wcnVuZVwiXG5leHBvcnQgY29uc3QgUEhYX1BBR0VfTE9BRElORyA9IFwicGFnZS1sb2FkaW5nXCJcbmV4cG9ydCBjb25zdCBQSFhfQ09OTkVDVEVEX0NMQVNTID0gXCJwaHgtY29ubmVjdGVkXCJcbmV4cG9ydCBjb25zdCBQSFhfTE9BRElOR19DTEFTUyA9IFwicGh4LWxvYWRpbmdcIlxuZXhwb3J0IGNvbnN0IFBIWF9OT19GRUVEQkFDS19DTEFTUyA9IFwicGh4LW5vLWZlZWRiYWNrXCJcbmV4cG9ydCBjb25zdCBQSFhfRVJST1JfQ0xBU1MgPSBcInBoeC1lcnJvclwiXG5leHBvcnQgY29uc3QgUEhYX0NMSUVOVF9FUlJPUl9DTEFTUyA9IFwicGh4LWNsaWVudC1lcnJvclwiXG5leHBvcnQgY29uc3QgUEhYX1NFUlZFUl9FUlJPUl9DTEFTUyA9IFwicGh4LXNlcnZlci1lcnJvclwiXG5leHBvcnQgY29uc3QgUEhYX1BBUkVOVF9JRCA9IFwiZGF0YS1waHgtcGFyZW50LWlkXCJcbmV4cG9ydCBjb25zdCBQSFhfTUFJTiA9IFwiZGF0YS1waHgtbWFpblwiXG5leHBvcnQgY29uc3QgUEhYX1JPT1RfSUQgPSBcImRhdGEtcGh4LXJvb3QtaWRcIlxuZXhwb3J0IGNvbnN0IFBIWF9WSUVXUE9SVF9UT1AgPSBcInZpZXdwb3J0LXRvcFwiXG5leHBvcnQgY29uc3QgUEhYX1ZJRVdQT1JUX0JPVFRPTSA9IFwidmlld3BvcnQtYm90dG9tXCJcbmV4cG9ydCBjb25zdCBQSFhfVFJJR0dFUl9BQ1RJT04gPSBcInRyaWdnZXItYWN0aW9uXCJcbmV4cG9ydCBjb25zdCBQSFhfRkVFREJBQ0tfRk9SID0gXCJmZWVkYmFjay1mb3JcIlxuZXhwb3J0IGNvbnN0IFBIWF9IQVNfRk9DVVNFRCA9IFwicGh4LWhhcy1mb2N1c2VkXCJcbmV4cG9ydCBjb25zdCBGT0NVU0FCTEVfSU5QVVRTID0gW1widGV4dFwiLCBcInRleHRhcmVhXCIsIFwibnVtYmVyXCIsIFwiZW1haWxcIiwgXCJwYXNzd29yZFwiLCBcInNlYXJjaFwiLCBcInRlbFwiLCBcInVybFwiLCBcImRhdGVcIiwgXCJ0aW1lXCIsIFwiZGF0ZXRpbWUtbG9jYWxcIiwgXCJjb2xvclwiLCBcInJhbmdlXCJdXG5leHBvcnQgY29uc3QgQ0hFQ0tBQkxFX0lOUFVUUyA9IFtcImNoZWNrYm94XCIsIFwicmFkaW9cIl1cbmV4cG9ydCBjb25zdCBQSFhfSEFTX1NVQk1JVFRFRCA9IFwicGh4LWhhcy1zdWJtaXR0ZWRcIlxuZXhwb3J0IGNvbnN0IFBIWF9TRVNTSU9OID0gXCJkYXRhLXBoeC1zZXNzaW9uXCJcbmV4cG9ydCBjb25zdCBQSFhfVklFV19TRUxFQ1RPUiA9IGBbJHtQSFhfU0VTU0lPTn1dYFxuZXhwb3J0IGNvbnN0IFBIWF9TVElDS1kgPSBcImRhdGEtcGh4LXN0aWNreVwiXG5leHBvcnQgY29uc3QgUEhYX1NUQVRJQyA9IFwiZGF0YS1waHgtc3RhdGljXCJcbmV4cG9ydCBjb25zdCBQSFhfUkVBRE9OTFkgPSBcImRhdGEtcGh4LXJlYWRvbmx5XCJcbmV4cG9ydCBjb25zdCBQSFhfRElTQUJMRUQgPSBcImRhdGEtcGh4LWRpc2FibGVkXCJcbmV4cG9ydCBjb25zdCBQSFhfRElTQUJMRV9XSVRIID0gXCJkaXNhYmxlLXdpdGhcIlxuZXhwb3J0IGNvbnN0IFBIWF9ESVNBQkxFX1dJVEhfUkVTVE9SRSA9IFwiZGF0YS1waHgtZGlzYWJsZS13aXRoLXJlc3RvcmVcIlxuZXhwb3J0IGNvbnN0IFBIWF9IT09LID0gXCJob29rXCJcbmV4cG9ydCBjb25zdCBQSFhfREVCT1VOQ0UgPSBcImRlYm91bmNlXCJcbmV4cG9ydCBjb25zdCBQSFhfVEhST1RUTEUgPSBcInRocm90dGxlXCJcbmV4cG9ydCBjb25zdCBQSFhfVVBEQVRFID0gXCJ1cGRhdGVcIlxuZXhwb3J0IGNvbnN0IFBIWF9TVFJFQU0gPSBcInN0cmVhbVwiXG5leHBvcnQgY29uc3QgUEhYX1NUUkVBTV9SRUYgPSBcImRhdGEtcGh4LXN0cmVhbVwiXG5leHBvcnQgY29uc3QgUEhYX0tFWSA9IFwia2V5XCJcbmV4cG9ydCBjb25zdCBQSFhfUFJJVkFURSA9IFwicGh4UHJpdmF0ZVwiXG5leHBvcnQgY29uc3QgUEhYX0FVVE9fUkVDT1ZFUiA9IFwiYXV0by1yZWNvdmVyXCJcbmV4cG9ydCBjb25zdCBQSFhfTFZfREVCVUcgPSBcInBoeDpsaXZlLXNvY2tldDpkZWJ1Z1wiXG5leHBvcnQgY29uc3QgUEhYX0xWX1BST0ZJTEUgPSBcInBoeDpsaXZlLXNvY2tldDpwcm9maWxpbmdcIlxuZXhwb3J0IGNvbnN0IFBIWF9MVl9MQVRFTkNZX1NJTSA9IFwicGh4OmxpdmUtc29ja2V0OmxhdGVuY3ktc2ltXCJcbmV4cG9ydCBjb25zdCBQSFhfUFJPR1JFU1MgPSBcInByb2dyZXNzXCJcbmV4cG9ydCBjb25zdCBQSFhfTU9VTlRFRCA9IFwibW91bnRlZFwiXG5leHBvcnQgY29uc3QgTE9BREVSX1RJTUVPVVQgPSAxXG5leHBvcnQgY29uc3QgQkVGT1JFX1VOTE9BRF9MT0FERVJfVElNRU9VVCA9IDIwMFxuZXhwb3J0IGNvbnN0IEJJTkRJTkdfUFJFRklYID0gXCJwaHgtXCJcbmV4cG9ydCBjb25zdCBQVVNIX1RJTUVPVVQgPSAzMDAwMFxuZXhwb3J0IGNvbnN0IExJTktfSEVBREVSID0gXCJ4LXJlcXVlc3RlZC13aXRoXCJcbmV4cG9ydCBjb25zdCBSRVNQT05TRV9VUkxfSEVBREVSID0gXCJ4LXJlc3BvbnNlLXVybFwiXG5leHBvcnQgY29uc3QgREVCT1VOQ0VfVFJJR0dFUiA9IFwiZGVib3VuY2UtdHJpZ2dlclwiXG5leHBvcnQgY29uc3QgVEhST1RUTEVEID0gXCJ0aHJvdHRsZWRcIlxuZXhwb3J0IGNvbnN0IERFQk9VTkNFX1BSRVZfS0VZID0gXCJkZWJvdW5jZS1wcmV2LWtleVwiXG5leHBvcnQgY29uc3QgREVGQVVMVFMgPSB7XG4gIGRlYm91bmNlOiAzMDAsXG4gIHRocm90dGxlOiAzMDBcbn1cblxuLy8gUmVuZGVyZWRcbmV4cG9ydCBjb25zdCBEWU5BTUlDUyA9IFwiZFwiXG5leHBvcnQgY29uc3QgU1RBVElDID0gXCJzXCJcbmV4cG9ydCBjb25zdCBDT01QT05FTlRTID0gXCJjXCJcbmV4cG9ydCBjb25zdCBFVkVOVFMgPSBcImVcIlxuZXhwb3J0IGNvbnN0IFJFUExZID0gXCJyXCJcbmV4cG9ydCBjb25zdCBUSVRMRSA9IFwidFwiXG5leHBvcnQgY29uc3QgVEVNUExBVEVTID0gXCJwXCJcbmV4cG9ydCBjb25zdCBTVFJFQU0gPSBcInN0cmVhbVwiXG4iLCAiaW1wb3J0IHtcbiAgbG9nRXJyb3Jcbn0gZnJvbSBcIi4vdXRpbHNcIlxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBFbnRyeVVwbG9hZGVyIHtcbiAgY29uc3RydWN0b3IoZW50cnksIGNodW5rU2l6ZSwgbGl2ZVNvY2tldCl7XG4gICAgdGhpcy5saXZlU29ja2V0ID0gbGl2ZVNvY2tldFxuICAgIHRoaXMuZW50cnkgPSBlbnRyeVxuICAgIHRoaXMub2Zmc2V0ID0gMFxuICAgIHRoaXMuY2h1bmtTaXplID0gY2h1bmtTaXplXG4gICAgdGhpcy5jaHVua1RpbWVyID0gbnVsbFxuICAgIHRoaXMuZXJyb3JlZCA9IGZhbHNlXG4gICAgdGhpcy51cGxvYWRDaGFubmVsID0gbGl2ZVNvY2tldC5jaGFubmVsKGBsdnU6JHtlbnRyeS5yZWZ9YCwge3Rva2VuOiBlbnRyeS5tZXRhZGF0YSgpfSlcbiAgfVxuXG4gIGVycm9yKHJlYXNvbil7XG4gICAgaWYodGhpcy5lcnJvcmVkKXsgcmV0dXJuIH1cbiAgICB0aGlzLmVycm9yZWQgPSB0cnVlXG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuY2h1bmtUaW1lcilcbiAgICB0aGlzLmVudHJ5LmVycm9yKHJlYXNvbilcbiAgfVxuXG4gIHVwbG9hZCgpe1xuICAgIHRoaXMudXBsb2FkQ2hhbm5lbC5vbkVycm9yKHJlYXNvbiA9PiB0aGlzLmVycm9yKHJlYXNvbikpXG4gICAgdGhpcy51cGxvYWRDaGFubmVsLmpvaW4oKVxuICAgICAgLnJlY2VpdmUoXCJva1wiLCBfZGF0YSA9PiB0aGlzLnJlYWROZXh0Q2h1bmsoKSlcbiAgICAgIC5yZWNlaXZlKFwiZXJyb3JcIiwgcmVhc29uID0+IHRoaXMuZXJyb3IocmVhc29uKSlcbiAgfVxuXG4gIGlzRG9uZSgpeyByZXR1cm4gdGhpcy5vZmZzZXQgPj0gdGhpcy5lbnRyeS5maWxlLnNpemUgfVxuXG4gIHJlYWROZXh0Q2h1bmsoKXtcbiAgICBsZXQgcmVhZGVyID0gbmV3IHdpbmRvdy5GaWxlUmVhZGVyKClcbiAgICBsZXQgYmxvYiA9IHRoaXMuZW50cnkuZmlsZS5zbGljZSh0aGlzLm9mZnNldCwgdGhpcy5jaHVua1NpemUgKyB0aGlzLm9mZnNldClcbiAgICByZWFkZXIub25sb2FkID0gKGUpID0+IHtcbiAgICAgIGlmKGUudGFyZ2V0LmVycm9yID09PSBudWxsKXtcbiAgICAgICAgdGhpcy5vZmZzZXQgKz0gZS50YXJnZXQucmVzdWx0LmJ5dGVMZW5ndGhcbiAgICAgICAgdGhpcy5wdXNoQ2h1bmsoZS50YXJnZXQucmVzdWx0KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGxvZ0Vycm9yKFwiUmVhZCBlcnJvcjogXCIgKyBlLnRhcmdldC5lcnJvcilcbiAgICAgIH1cbiAgICB9XG4gICAgcmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKGJsb2IpXG4gIH1cblxuICBwdXNoQ2h1bmsoY2h1bmspe1xuICAgIGlmKCF0aGlzLnVwbG9hZENoYW5uZWwuaXNKb2luZWQoKSl7IHJldHVybiB9XG4gICAgdGhpcy51cGxvYWRDaGFubmVsLnB1c2goXCJjaHVua1wiLCBjaHVuaylcbiAgICAgIC5yZWNlaXZlKFwib2tcIiwgKCkgPT4ge1xuICAgICAgICB0aGlzLmVudHJ5LnByb2dyZXNzKCh0aGlzLm9mZnNldCAvIHRoaXMuZW50cnkuZmlsZS5zaXplKSAqIDEwMClcbiAgICAgICAgaWYoIXRoaXMuaXNEb25lKCkpe1xuICAgICAgICAgIHRoaXMuY2h1bmtUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4gdGhpcy5yZWFkTmV4dENodW5rKCksIHRoaXMubGl2ZVNvY2tldC5nZXRMYXRlbmN5U2ltKCkgfHwgMClcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIC5yZWNlaXZlKFwiZXJyb3JcIiwgKHtyZWFzb259KSA9PiB0aGlzLmVycm9yKHJlYXNvbikpXG4gIH1cbn1cbiIsICJpbXBvcnQge1xuICBQSFhfVklFV19TRUxFQ1RPUlxufSBmcm9tIFwiLi9jb25zdGFudHNcIlxuXG5pbXBvcnQgRW50cnlVcGxvYWRlciBmcm9tIFwiLi9lbnRyeV91cGxvYWRlclwiXG5cbmV4cG9ydCBsZXQgbG9nRXJyb3IgPSAobXNnLCBvYmopID0+IGNvbnNvbGUuZXJyb3IgJiYgY29uc29sZS5lcnJvcihtc2csIG9iailcblxuZXhwb3J0IGxldCBpc0NpZCA9IChjaWQpID0+IHtcbiAgbGV0IHR5cGUgPSB0eXBlb2YoY2lkKVxuICByZXR1cm4gdHlwZSA9PT0gXCJudW1iZXJcIiB8fCAodHlwZSA9PT0gXCJzdHJpbmdcIiAmJiAvXigwfFsxLTldXFxkKikkLy50ZXN0KGNpZCkpXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZXRlY3REdXBsaWNhdGVJZHMoKXtcbiAgbGV0IGlkcyA9IG5ldyBTZXQoKVxuICBsZXQgZWxlbXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiKltpZF1cIilcbiAgZm9yKGxldCBpID0gMCwgbGVuID0gZWxlbXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspe1xuICAgIGlmKGlkcy5oYXMoZWxlbXNbaV0uaWQpKXtcbiAgICAgIGNvbnNvbGUuZXJyb3IoYE11bHRpcGxlIElEcyBkZXRlY3RlZDogJHtlbGVtc1tpXS5pZH0uIEVuc3VyZSB1bmlxdWUgZWxlbWVudCBpZHMuYClcbiAgICB9IGVsc2Uge1xuICAgICAgaWRzLmFkZChlbGVtc1tpXS5pZClcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGxldCBkZWJ1ZyA9ICh2aWV3LCBraW5kLCBtc2csIG9iaikgPT4ge1xuICBpZih2aWV3LmxpdmVTb2NrZXQuaXNEZWJ1Z0VuYWJsZWQoKSl7XG4gICAgY29uc29sZS5sb2coYCR7dmlldy5pZH0gJHtraW5kfTogJHttc2d9IC0gYCwgb2JqKVxuICB9XG59XG5cbi8vIHdyYXBzIHZhbHVlIGluIGNsb3N1cmUgb3IgcmV0dXJucyBjbG9zdXJlXG5leHBvcnQgbGV0IGNsb3N1cmUgPSAodmFsKSA9PiB0eXBlb2YgdmFsID09PSBcImZ1bmN0aW9uXCIgPyB2YWwgOiBmdW5jdGlvbiAoKXsgcmV0dXJuIHZhbCB9XG5cbmV4cG9ydCBsZXQgY2xvbmUgPSAob2JqKSA9PiB7IHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG9iaikpIH1cblxuZXhwb3J0IGxldCBjbG9zZXN0UGh4QmluZGluZyA9IChlbCwgYmluZGluZywgYm9yZGVyRWwpID0+IHtcbiAgZG8ge1xuICAgIGlmKGVsLm1hdGNoZXMoYFske2JpbmRpbmd9XWApICYmICFlbC5kaXNhYmxlZCl7IHJldHVybiBlbCB9XG4gICAgZWwgPSBlbC5wYXJlbnRFbGVtZW50IHx8IGVsLnBhcmVudE5vZGVcbiAgfSB3aGlsZShlbCAhPT0gbnVsbCAmJiBlbC5ub2RlVHlwZSA9PT0gMSAmJiAhKChib3JkZXJFbCAmJiBib3JkZXJFbC5pc1NhbWVOb2RlKGVsKSkgfHwgZWwubWF0Y2hlcyhQSFhfVklFV19TRUxFQ1RPUikpKVxuICByZXR1cm4gbnVsbFxufVxuXG5leHBvcnQgbGV0IGlzT2JqZWN0ID0gKG9iaikgPT4ge1xuICByZXR1cm4gb2JqICE9PSBudWxsICYmIHR5cGVvZiBvYmogPT09IFwib2JqZWN0XCIgJiYgIShvYmogaW5zdGFuY2VvZiBBcnJheSlcbn1cblxuZXhwb3J0IGxldCBpc0VxdWFsT2JqID0gKG9iajEsIG9iajIpID0+IEpTT04uc3RyaW5naWZ5KG9iajEpID09PSBKU09OLnN0cmluZ2lmeShvYmoyKVxuXG5leHBvcnQgbGV0IGlzRW1wdHkgPSAob2JqKSA9PiB7XG4gIGZvcihsZXQgeCBpbiBvYmopeyByZXR1cm4gZmFsc2UgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG5leHBvcnQgbGV0IG1heWJlID0gKGVsLCBjYWxsYmFjaykgPT4gZWwgJiYgY2FsbGJhY2soZWwpXG5cbmV4cG9ydCBsZXQgY2hhbm5lbFVwbG9hZGVyID0gZnVuY3Rpb24gKGVudHJpZXMsIG9uRXJyb3IsIHJlc3AsIGxpdmVTb2NrZXQpe1xuICBlbnRyaWVzLmZvckVhY2goZW50cnkgPT4ge1xuICAgIGxldCBlbnRyeVVwbG9hZGVyID0gbmV3IEVudHJ5VXBsb2FkZXIoZW50cnksIHJlc3AuY29uZmlnLmNodW5rX3NpemUsIGxpdmVTb2NrZXQpXG4gICAgZW50cnlVcGxvYWRlci51cGxvYWQoKVxuICB9KVxufVxuIiwgImxldCBCcm93c2VyID0ge1xuICBjYW5QdXNoU3RhdGUoKXsgcmV0dXJuICh0eXBlb2YgKGhpc3RvcnkucHVzaFN0YXRlKSAhPT0gXCJ1bmRlZmluZWRcIikgfSxcblxuICBkcm9wTG9jYWwobG9jYWxTdG9yYWdlLCBuYW1lc3BhY2UsIHN1YmtleSl7XG4gICAgcmV0dXJuIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKHRoaXMubG9jYWxLZXkobmFtZXNwYWNlLCBzdWJrZXkpKVxuICB9LFxuXG4gIHVwZGF0ZUxvY2FsKGxvY2FsU3RvcmFnZSwgbmFtZXNwYWNlLCBzdWJrZXksIGluaXRpYWwsIGZ1bmMpe1xuICAgIGxldCBjdXJyZW50ID0gdGhpcy5nZXRMb2NhbChsb2NhbFN0b3JhZ2UsIG5hbWVzcGFjZSwgc3Via2V5KVxuICAgIGxldCBrZXkgPSB0aGlzLmxvY2FsS2V5KG5hbWVzcGFjZSwgc3Via2V5KVxuICAgIGxldCBuZXdWYWwgPSBjdXJyZW50ID09PSBudWxsID8gaW5pdGlhbCA6IGZ1bmMoY3VycmVudClcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShrZXksIEpTT04uc3RyaW5naWZ5KG5ld1ZhbCkpXG4gICAgcmV0dXJuIG5ld1ZhbFxuICB9LFxuXG4gIGdldExvY2FsKGxvY2FsU3RvcmFnZSwgbmFtZXNwYWNlLCBzdWJrZXkpe1xuICAgIHJldHVybiBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMubG9jYWxLZXkobmFtZXNwYWNlLCBzdWJrZXkpKSlcbiAgfSxcblxuICB1cGRhdGVDdXJyZW50U3RhdGUoY2FsbGJhY2spe1xuICAgIGlmKCF0aGlzLmNhblB1c2hTdGF0ZSgpKXsgcmV0dXJuIH1cbiAgICBoaXN0b3J5LnJlcGxhY2VTdGF0ZShjYWxsYmFjayhoaXN0b3J5LnN0YXRlIHx8IHt9KSwgXCJcIiwgd2luZG93LmxvY2F0aW9uLmhyZWYpXG4gIH0sXG5cbiAgcHVzaFN0YXRlKGtpbmQsIG1ldGEsIHRvKXtcbiAgICBpZih0aGlzLmNhblB1c2hTdGF0ZSgpKXtcbiAgICAgIGlmKHRvICE9PSB3aW5kb3cubG9jYXRpb24uaHJlZil7XG4gICAgICAgIGlmKG1ldGEudHlwZSA9PSBcInJlZGlyZWN0XCIgJiYgbWV0YS5zY3JvbGwpe1xuICAgICAgICAgIC8vIElmIHdlJ3JlIHJlZGlyZWN0aW5nIHN0b3JlIHRoZSBjdXJyZW50IHNjcm9sbFkgZm9yIHRoZSBjdXJyZW50IGhpc3Rvcnkgc3RhdGUuXG4gICAgICAgICAgbGV0IGN1cnJlbnRTdGF0ZSA9IGhpc3Rvcnkuc3RhdGUgfHwge31cbiAgICAgICAgICBjdXJyZW50U3RhdGUuc2Nyb2xsID0gbWV0YS5zY3JvbGxcbiAgICAgICAgICBoaXN0b3J5LnJlcGxhY2VTdGF0ZShjdXJyZW50U3RhdGUsIFwiXCIsIHdpbmRvdy5sb2NhdGlvbi5ocmVmKVxuICAgICAgICB9XG5cbiAgICAgICAgZGVsZXRlIG1ldGEuc2Nyb2xsIC8vIE9ubHkgc3RvcmUgdGhlIHNjcm9sbCBpbiB0aGUgcmVkaXJlY3QgY2FzZS5cbiAgICAgICAgaGlzdG9yeVtraW5kICsgXCJTdGF0ZVwiXShtZXRhLCBcIlwiLCB0byB8fCBudWxsKSAvLyBJRSB3aWxsIGNvZXJjZSB1bmRlZmluZWQgdG8gc3RyaW5nXG4gICAgICAgIGxldCBoYXNoRWwgPSB0aGlzLmdldEhhc2hUYXJnZXRFbCh3aW5kb3cubG9jYXRpb24uaGFzaClcblxuICAgICAgICBpZihoYXNoRWwpe1xuICAgICAgICAgIGhhc2hFbC5zY3JvbGxJbnRvVmlldygpXG4gICAgICAgIH0gZWxzZSBpZihtZXRhLnR5cGUgPT09IFwicmVkaXJlY3RcIil7XG4gICAgICAgICAgd2luZG93LnNjcm9sbCgwLCAwKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmVkaXJlY3QodG8pXG4gICAgfVxuICB9LFxuXG4gIHNldENvb2tpZShuYW1lLCB2YWx1ZSl7XG4gICAgZG9jdW1lbnQuY29va2llID0gYCR7bmFtZX09JHt2YWx1ZX1gXG4gIH0sXG5cbiAgZ2V0Q29va2llKG5hbWUpe1xuICAgIHJldHVybiBkb2N1bWVudC5jb29raWUucmVwbGFjZShuZXcgUmVnRXhwKGAoPzooPzpefC4qO1xccyopJHtuYW1lfVxccypcXD1cXHMqKFteO10qKS4qJCl8Xi4qJGApLCBcIiQxXCIpXG4gIH0sXG5cbiAgcmVkaXJlY3QodG9VUkwsIGZsYXNoKXtcbiAgICBpZihmbGFzaCl7IEJyb3dzZXIuc2V0Q29va2llKFwiX19waG9lbml4X2ZsYXNoX19cIiwgZmxhc2ggKyBcIjsgbWF4LWFnZT02MDAwMDsgcGF0aD0vXCIpIH1cbiAgICB3aW5kb3cubG9jYXRpb24gPSB0b1VSTFxuICB9LFxuXG4gIGxvY2FsS2V5KG5hbWVzcGFjZSwgc3Via2V5KXsgcmV0dXJuIGAke25hbWVzcGFjZX0tJHtzdWJrZXl9YCB9LFxuXG4gIGdldEhhc2hUYXJnZXRFbChtYXliZUhhc2gpe1xuICAgIGxldCBoYXNoID0gbWF5YmVIYXNoLnRvU3RyaW5nKCkuc3Vic3RyaW5nKDEpXG4gICAgaWYoaGFzaCA9PT0gXCJcIil7IHJldHVybiB9XG4gICAgcmV0dXJuIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGhhc2gpIHx8IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYGFbbmFtZT1cIiR7aGFzaH1cIl1gKVxuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEJyb3dzZXJcbiIsICJpbXBvcnQge1xuICBDSEVDS0FCTEVfSU5QVVRTLFxuICBERUJPVU5DRV9QUkVWX0tFWSxcbiAgREVCT1VOQ0VfVFJJR0dFUixcbiAgRk9DVVNBQkxFX0lOUFVUUyxcbiAgUEhYX0NPTVBPTkVOVCxcbiAgUEhYX0VWRU5UX0NMQVNTRVMsXG4gIFBIWF9IQVNfRk9DVVNFRCxcbiAgUEhYX0hBU19TVUJNSVRURUQsXG4gIFBIWF9NQUlOLFxuICBQSFhfTk9fRkVFREJBQ0tfQ0xBU1MsXG4gIFBIWF9QQVJFTlRfSUQsXG4gIFBIWF9QUklWQVRFLFxuICBQSFhfUkVGLFxuICBQSFhfUkVGX1NSQyxcbiAgUEhYX1JPT1RfSUQsXG4gIFBIWF9TRVNTSU9OLFxuICBQSFhfU1RBVElDLFxuICBQSFhfVVBMT0FEX1JFRixcbiAgUEhYX1ZJRVdfU0VMRUNUT1IsXG4gIFBIWF9TVElDS1ksXG4gIFRIUk9UVExFRFxufSBmcm9tIFwiLi9jb25zdGFudHNcIlxuXG5pbXBvcnQge1xuICBsb2dFcnJvclxufSBmcm9tIFwiLi91dGlsc1wiXG5cbmxldCBET00gPSB7XG4gIGJ5SWQoaWQpeyByZXR1cm4gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpIHx8IGxvZ0Vycm9yKGBubyBpZCBmb3VuZCBmb3IgJHtpZH1gKSB9LFxuXG4gIHJlbW92ZUNsYXNzKGVsLCBjbGFzc05hbWUpe1xuICAgIGVsLmNsYXNzTGlzdC5yZW1vdmUoY2xhc3NOYW1lKVxuICAgIGlmKGVsLmNsYXNzTGlzdC5sZW5ndGggPT09IDApeyBlbC5yZW1vdmVBdHRyaWJ1dGUoXCJjbGFzc1wiKSB9XG4gIH0sXG5cbiAgYWxsKG5vZGUsIHF1ZXJ5LCBjYWxsYmFjayl7XG4gICAgaWYoIW5vZGUpeyByZXR1cm4gW10gfVxuICAgIGxldCBhcnJheSA9IEFycmF5LmZyb20obm9kZS5xdWVyeVNlbGVjdG9yQWxsKHF1ZXJ5KSlcbiAgICByZXR1cm4gY2FsbGJhY2sgPyBhcnJheS5mb3JFYWNoKGNhbGxiYWNrKSA6IGFycmF5XG4gIH0sXG5cbiAgY2hpbGROb2RlTGVuZ3RoKGh0bWwpe1xuICAgIGxldCB0ZW1wbGF0ZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ0ZW1wbGF0ZVwiKVxuICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IGh0bWxcbiAgICByZXR1cm4gdGVtcGxhdGUuY29udGVudC5jaGlsZEVsZW1lbnRDb3VudFxuICB9LFxuXG4gIGlzVXBsb2FkSW5wdXQoZWwpeyByZXR1cm4gZWwudHlwZSA9PT0gXCJmaWxlXCIgJiYgZWwuZ2V0QXR0cmlidXRlKFBIWF9VUExPQURfUkVGKSAhPT0gbnVsbCB9LFxuXG4gIGlzQXV0b1VwbG9hZChpbnB1dEVsKXsgcmV0dXJuIGlucHV0RWwuaGFzQXR0cmlidXRlKFwiZGF0YS1waHgtYXV0by11cGxvYWRcIikgfSxcblxuICBmaW5kVXBsb2FkSW5wdXRzKG5vZGUpeyByZXR1cm4gdGhpcy5hbGwobm9kZSwgYGlucHV0W3R5cGU9XCJmaWxlXCJdWyR7UEhYX1VQTE9BRF9SRUZ9XWApIH0sXG5cbiAgZmluZENvbXBvbmVudE5vZGVMaXN0KG5vZGUsIGNpZCl7XG4gICAgcmV0dXJuIHRoaXMuZmlsdGVyV2l0aGluU2FtZUxpdmVWaWV3KHRoaXMuYWxsKG5vZGUsIGBbJHtQSFhfQ09NUE9ORU5UfT1cIiR7Y2lkfVwiXWApLCBub2RlKVxuICB9LFxuXG4gIGlzUGh4RGVzdHJveWVkKG5vZGUpe1xuICAgIHJldHVybiBub2RlLmlkICYmIERPTS5wcml2YXRlKG5vZGUsIFwiZGVzdHJveWVkXCIpID8gdHJ1ZSA6IGZhbHNlXG4gIH0sXG5cbiAgd2FudHNOZXdUYWIoZSl7XG4gICAgbGV0IHdhbnRzTmV3VGFiID0gZS5jdHJsS2V5IHx8IGUuc2hpZnRLZXkgfHwgZS5tZXRhS2V5IHx8IChlLmJ1dHRvbiAmJiBlLmJ1dHRvbiA9PT0gMSlcbiAgICBsZXQgaXNEb3dubG9hZCA9IChlLnRhcmdldCBpbnN0YW5jZW9mIEhUTUxBbmNob3JFbGVtZW50ICYmIGUudGFyZ2V0Lmhhc0F0dHJpYnV0ZShcImRvd25sb2FkXCIpKVxuICAgIGxldCBpc1RhcmdldEJsYW5rID0gZS50YXJnZXQuaGFzQXR0cmlidXRlKFwidGFyZ2V0XCIpICYmIGUudGFyZ2V0LmdldEF0dHJpYnV0ZShcInRhcmdldFwiKS50b0xvd2VyQ2FzZSgpID09PSBcIl9ibGFua1wiXG4gICAgcmV0dXJuIHdhbnRzTmV3VGFiIHx8IGlzVGFyZ2V0QmxhbmsgfHwgaXNEb3dubG9hZFxuICB9LFxuXG4gIGlzVW5sb2FkYWJsZUZvcm1TdWJtaXQoZSl7XG4gICAgLy8gSWdub3JlIGZvcm0gc3VibWlzc2lvbnMgaW50ZW5kZWQgdG8gY2xvc2UgYSBuYXRpdmUgPGRpYWxvZz4gZWxlbWVudFxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9kaWFsb2cjdXNhZ2Vfbm90ZXNcbiAgICBsZXQgaXNEaWFsb2dTdWJtaXQgPSAoZS50YXJnZXQgJiYgZS50YXJnZXQuZ2V0QXR0cmlidXRlKFwibWV0aG9kXCIpID09PSBcImRpYWxvZ1wiKSB8fFxuICAgICAgKGUuc3VibWl0dGVyICYmIGUuc3VibWl0dGVyLmdldEF0dHJpYnV0ZShcImZvcm1tZXRob2RcIikgPT09IFwiZGlhbG9nXCIpXG5cbiAgICBpZihpc0RpYWxvZ1N1Ym1pdCl7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuICFlLmRlZmF1bHRQcmV2ZW50ZWQgJiYgIXRoaXMud2FudHNOZXdUYWIoZSlcbiAgICB9XG4gIH0sXG5cbiAgaXNOZXdQYWdlQ2xpY2soZSwgY3VycmVudExvY2F0aW9uKXtcbiAgICBsZXQgaHJlZiA9IGUudGFyZ2V0IGluc3RhbmNlb2YgSFRNTEFuY2hvckVsZW1lbnQgPyBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoXCJocmVmXCIpIDogbnVsbFxuICAgIGxldCB1cmxcblxuICAgIGlmKGUuZGVmYXVsdFByZXZlbnRlZCB8fCBocmVmID09PSBudWxsIHx8IHRoaXMud2FudHNOZXdUYWIoZSkpeyByZXR1cm4gZmFsc2UgfVxuICAgIGlmKGhyZWYuc3RhcnRzV2l0aChcIm1haWx0bzpcIikgfHwgaHJlZi5zdGFydHNXaXRoKFwidGVsOlwiKSl7IHJldHVybiBmYWxzZSB9XG4gICAgaWYoZS50YXJnZXQuaXNDb250ZW50RWRpdGFibGUpeyByZXR1cm4gZmFsc2UgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHVybCA9IG5ldyBVUkwoaHJlZilcbiAgICB9IGNhdGNoKGUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHVybCA9IG5ldyBVUkwoaHJlZiwgY3VycmVudExvY2F0aW9uKVxuICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgIC8vIGJhZCBVUkwsIGZhbGxiYWNrIHRvIGxldCBicm93c2VyIHRyeSBpdCBhcyBleHRlcm5hbFxuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmKHVybC5ob3N0ID09PSBjdXJyZW50TG9jYXRpb24uaG9zdCAmJiB1cmwucHJvdG9jb2wgPT09IGN1cnJlbnRMb2NhdGlvbi5wcm90b2NvbCl7XG4gICAgICBpZih1cmwucGF0aG5hbWUgPT09IGN1cnJlbnRMb2NhdGlvbi5wYXRobmFtZSAmJiB1cmwuc2VhcmNoID09PSBjdXJyZW50TG9jYXRpb24uc2VhcmNoKXtcbiAgICAgICAgcmV0dXJuIHVybC5oYXNoID09PSBcIlwiICYmICF1cmwuaHJlZi5lbmRzV2l0aChcIiNcIilcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVybC5wcm90b2NvbC5zdGFydHNXaXRoKFwiaHR0cFwiKVxuICB9LFxuXG4gIG1hcmtQaHhDaGlsZERlc3Ryb3llZChlbCl7XG4gICAgaWYodGhpcy5pc1BoeENoaWxkKGVsKSl7IGVsLnNldEF0dHJpYnV0ZShQSFhfU0VTU0lPTiwgXCJcIikgfVxuICAgIHRoaXMucHV0UHJpdmF0ZShlbCwgXCJkZXN0cm95ZWRcIiwgdHJ1ZSlcbiAgfSxcblxuICBmaW5kUGh4Q2hpbGRyZW5JbkZyYWdtZW50KGh0bWwsIHBhcmVudElkKXtcbiAgICBsZXQgdGVtcGxhdGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidGVtcGxhdGVcIilcbiAgICB0ZW1wbGF0ZS5pbm5lckhUTUwgPSBodG1sXG4gICAgcmV0dXJuIHRoaXMuZmluZFBoeENoaWxkcmVuKHRlbXBsYXRlLmNvbnRlbnQsIHBhcmVudElkKVxuICB9LFxuXG4gIGlzSWdub3JlZChlbCwgcGh4VXBkYXRlKXtcbiAgICByZXR1cm4gKGVsLmdldEF0dHJpYnV0ZShwaHhVcGRhdGUpIHx8IGVsLmdldEF0dHJpYnV0ZShcImRhdGEtcGh4LXVwZGF0ZVwiKSkgPT09IFwiaWdub3JlXCJcbiAgfSxcblxuICBpc1BoeFVwZGF0ZShlbCwgcGh4VXBkYXRlLCB1cGRhdGVUeXBlcyl7XG4gICAgcmV0dXJuIGVsLmdldEF0dHJpYnV0ZSAmJiB1cGRhdGVUeXBlcy5pbmRleE9mKGVsLmdldEF0dHJpYnV0ZShwaHhVcGRhdGUpKSA+PSAwXG4gIH0sXG5cbiAgZmluZFBoeFN0aWNreShlbCl7IHJldHVybiB0aGlzLmFsbChlbCwgYFske1BIWF9TVElDS1l9XWApIH0sXG5cbiAgZmluZFBoeENoaWxkcmVuKGVsLCBwYXJlbnRJZCl7XG4gICAgcmV0dXJuIHRoaXMuYWxsKGVsLCBgJHtQSFhfVklFV19TRUxFQ1RPUn1bJHtQSFhfUEFSRU5UX0lEfT1cIiR7cGFyZW50SWR9XCJdYClcbiAgfSxcblxuICBmaW5kUGFyZW50Q0lEcyhub2RlLCBjaWRzKXtcbiAgICBsZXQgaW5pdGlhbCA9IG5ldyBTZXQoY2lkcylcbiAgICBsZXQgcGFyZW50Q2lkcyA9XG4gICAgICBjaWRzLnJlZHVjZSgoYWNjLCBjaWQpID0+IHtcbiAgICAgICAgbGV0IHNlbGVjdG9yID0gYFske1BIWF9DT01QT05FTlR9PVwiJHtjaWR9XCJdIFske1BIWF9DT01QT05FTlR9XWBcblxuICAgICAgICB0aGlzLmZpbHRlcldpdGhpblNhbWVMaXZlVmlldyh0aGlzLmFsbChub2RlLCBzZWxlY3RvciksIG5vZGUpXG4gICAgICAgICAgLm1hcChlbCA9PiBwYXJzZUludChlbC5nZXRBdHRyaWJ1dGUoUEhYX0NPTVBPTkVOVCkpKVxuICAgICAgICAgIC5mb3JFYWNoKGNoaWxkQ0lEID0+IGFjYy5kZWxldGUoY2hpbGRDSUQpKVxuXG4gICAgICAgIHJldHVybiBhY2NcbiAgICAgIH0sIGluaXRpYWwpXG5cbiAgICByZXR1cm4gcGFyZW50Q2lkcy5zaXplID09PSAwID8gbmV3IFNldChjaWRzKSA6IHBhcmVudENpZHNcbiAgfSxcblxuICBmaWx0ZXJXaXRoaW5TYW1lTGl2ZVZpZXcobm9kZXMsIHBhcmVudCl7XG4gICAgaWYocGFyZW50LnF1ZXJ5U2VsZWN0b3IoUEhYX1ZJRVdfU0VMRUNUT1IpKXtcbiAgICAgIHJldHVybiBub2Rlcy5maWx0ZXIoZWwgPT4gdGhpcy53aXRoaW5TYW1lTGl2ZVZpZXcoZWwsIHBhcmVudCkpXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBub2Rlc1xuICAgIH1cbiAgfSxcblxuICB3aXRoaW5TYW1lTGl2ZVZpZXcobm9kZSwgcGFyZW50KXtcbiAgICB3aGlsZShub2RlID0gbm9kZS5wYXJlbnROb2RlKXtcbiAgICAgIGlmKG5vZGUuaXNTYW1lTm9kZShwYXJlbnQpKXsgcmV0dXJuIHRydWUgfVxuICAgICAgaWYobm9kZS5nZXRBdHRyaWJ1dGUoUEhYX1NFU1NJT04pICE9PSBudWxsKXsgcmV0dXJuIGZhbHNlIH1cbiAgICB9XG4gIH0sXG5cbiAgcHJpdmF0ZShlbCwga2V5KXsgcmV0dXJuIGVsW1BIWF9QUklWQVRFXSAmJiBlbFtQSFhfUFJJVkFURV1ba2V5XSB9LFxuXG4gIGRlbGV0ZVByaXZhdGUoZWwsIGtleSl7IGVsW1BIWF9QUklWQVRFXSAmJiBkZWxldGUgKGVsW1BIWF9QUklWQVRFXVtrZXldKSB9LFxuXG4gIHB1dFByaXZhdGUoZWwsIGtleSwgdmFsdWUpe1xuICAgIGlmKCFlbFtQSFhfUFJJVkFURV0peyBlbFtQSFhfUFJJVkFURV0gPSB7fSB9XG4gICAgZWxbUEhYX1BSSVZBVEVdW2tleV0gPSB2YWx1ZVxuICB9LFxuXG4gIHVwZGF0ZVByaXZhdGUoZWwsIGtleSwgZGVmYXVsdFZhbCwgdXBkYXRlRnVuYyl7XG4gICAgbGV0IGV4aXN0aW5nID0gdGhpcy5wcml2YXRlKGVsLCBrZXkpXG4gICAgaWYoZXhpc3RpbmcgPT09IHVuZGVmaW5lZCl7XG4gICAgICB0aGlzLnB1dFByaXZhdGUoZWwsIGtleSwgdXBkYXRlRnVuYyhkZWZhdWx0VmFsKSlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wdXRQcml2YXRlKGVsLCBrZXksIHVwZGF0ZUZ1bmMoZXhpc3RpbmcpKVxuICAgIH1cbiAgfSxcblxuICBjb3B5UHJpdmF0ZXModGFyZ2V0LCBzb3VyY2Upe1xuICAgIGlmKHNvdXJjZVtQSFhfUFJJVkFURV0pe1xuICAgICAgdGFyZ2V0W1BIWF9QUklWQVRFXSA9IHNvdXJjZVtQSFhfUFJJVkFURV1cbiAgICB9XG4gIH0sXG5cbiAgcHV0VGl0bGUoc3RyKXtcbiAgICBsZXQgdGl0bGVFbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJ0aXRsZVwiKVxuICAgIGlmKHRpdGxlRWwpe1xuICAgICAgbGV0IHtwcmVmaXgsIHN1ZmZpeH0gPSB0aXRsZUVsLmRhdGFzZXRcbiAgICAgIGRvY3VtZW50LnRpdGxlID0gYCR7cHJlZml4IHx8IFwiXCJ9JHtzdHJ9JHtzdWZmaXggfHwgXCJcIn1gXG4gICAgfSBlbHNlIHtcbiAgICAgIGRvY3VtZW50LnRpdGxlID0gc3RyXG4gICAgfVxuICB9LFxuXG4gIGRlYm91bmNlKGVsLCBldmVudCwgcGh4RGVib3VuY2UsIGRlZmF1bHREZWJvdW5jZSwgcGh4VGhyb3R0bGUsIGRlZmF1bHRUaHJvdHRsZSwgYXN5bmNGaWx0ZXIsIGNhbGxiYWNrKXtcbiAgICBsZXQgZGVib3VuY2UgPSBlbC5nZXRBdHRyaWJ1dGUocGh4RGVib3VuY2UpXG4gICAgbGV0IHRocm90dGxlID0gZWwuZ2V0QXR0cmlidXRlKHBoeFRocm90dGxlKVxuXG4gICAgaWYoZGVib3VuY2UgPT09IFwiXCIpeyBkZWJvdW5jZSA9IGRlZmF1bHREZWJvdW5jZSB9XG4gICAgaWYodGhyb3R0bGUgPT09IFwiXCIpeyB0aHJvdHRsZSA9IGRlZmF1bHRUaHJvdHRsZSB9XG4gICAgbGV0IHZhbHVlID0gZGVib3VuY2UgfHwgdGhyb3R0bGVcbiAgICBzd2l0Y2godmFsdWUpe1xuICAgICAgY2FzZSBudWxsOiByZXR1cm4gY2FsbGJhY2soKVxuXG4gICAgICBjYXNlIFwiYmx1clwiOlxuICAgICAgICBpZih0aGlzLm9uY2UoZWwsIFwiZGVib3VuY2UtYmx1clwiKSl7XG4gICAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcihcImJsdXJcIiwgKCkgPT4gY2FsbGJhY2soKSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm5cblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgbGV0IHRpbWVvdXQgPSBwYXJzZUludCh2YWx1ZSlcbiAgICAgICAgbGV0IHRyaWdnZXIgPSAoKSA9PiB0aHJvdHRsZSA/IHRoaXMuZGVsZXRlUHJpdmF0ZShlbCwgVEhST1RUTEVEKSA6IGNhbGxiYWNrKClcbiAgICAgICAgbGV0IGN1cnJlbnRDeWNsZSA9IHRoaXMuaW5jQ3ljbGUoZWwsIERFQk9VTkNFX1RSSUdHRVIsIHRyaWdnZXIpXG4gICAgICAgIGlmKGlzTmFOKHRpbWVvdXQpKXsgcmV0dXJuIGxvZ0Vycm9yKGBpbnZhbGlkIHRocm90dGxlL2RlYm91bmNlIHZhbHVlOiAke3ZhbHVlfWApIH1cbiAgICAgICAgaWYodGhyb3R0bGUpe1xuICAgICAgICAgIGxldCBuZXdLZXlEb3duID0gZmFsc2VcbiAgICAgICAgICBpZihldmVudC50eXBlID09PSBcImtleWRvd25cIil7XG4gICAgICAgICAgICBsZXQgcHJldktleSA9IHRoaXMucHJpdmF0ZShlbCwgREVCT1VOQ0VfUFJFVl9LRVkpXG4gICAgICAgICAgICB0aGlzLnB1dFByaXZhdGUoZWwsIERFQk9VTkNFX1BSRVZfS0VZLCBldmVudC5rZXkpXG4gICAgICAgICAgICBuZXdLZXlEb3duID0gcHJldktleSAhPT0gZXZlbnQua2V5XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYoIW5ld0tleURvd24gJiYgdGhpcy5wcml2YXRlKGVsLCBUSFJPVFRMRUQpKXtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWxsYmFjaygpXG4gICAgICAgICAgICB0aGlzLnB1dFByaXZhdGUoZWwsIFRIUk9UVExFRCwgdHJ1ZSlcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICBpZihhc3luY0ZpbHRlcigpKXsgdGhpcy50cmlnZ2VyQ3ljbGUoZWwsIERFQk9VTkNFX1RSSUdHRVIpIH1cbiAgICAgICAgICAgIH0sIHRpbWVvdXQpXG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgaWYoYXN5bmNGaWx0ZXIoKSl7IHRoaXMudHJpZ2dlckN5Y2xlKGVsLCBERUJPVU5DRV9UUklHR0VSLCBjdXJyZW50Q3ljbGUpIH1cbiAgICAgICAgICB9LCB0aW1lb3V0KVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGZvcm0gPSBlbC5mb3JtXG4gICAgICAgIGlmKGZvcm0gJiYgdGhpcy5vbmNlKGZvcm0sIFwiYmluZC1kZWJvdW5jZVwiKSl7XG4gICAgICAgICAgZm9ybS5hZGRFdmVudExpc3RlbmVyKFwic3VibWl0XCIsICgpID0+IHtcbiAgICAgICAgICAgIEFycmF5LmZyb20oKG5ldyBGb3JtRGF0YShmb3JtKSkuZW50cmllcygpLCAoW25hbWVdKSA9PiB7XG4gICAgICAgICAgICAgIGxldCBpbnB1dCA9IGZvcm0ucXVlcnlTZWxlY3RvcihgW25hbWU9XCIke25hbWV9XCJdYClcbiAgICAgICAgICAgICAgdGhpcy5pbmNDeWNsZShpbnB1dCwgREVCT1VOQ0VfVFJJR0dFUilcbiAgICAgICAgICAgICAgdGhpcy5kZWxldGVQcml2YXRlKGlucHV0LCBUSFJPVFRMRUQpXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgaWYodGhpcy5vbmNlKGVsLCBcImJpbmQtZGVib3VuY2VcIikpe1xuICAgICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoXCJibHVyXCIsICgpID0+IHRoaXMudHJpZ2dlckN5Y2xlKGVsLCBERUJPVU5DRV9UUklHR0VSKSlcbiAgICAgICAgfVxuICAgIH1cbiAgfSxcblxuICB0cmlnZ2VyQ3ljbGUoZWwsIGtleSwgY3VycmVudEN5Y2xlKXtcbiAgICBsZXQgW2N5Y2xlLCB0cmlnZ2VyXSA9IHRoaXMucHJpdmF0ZShlbCwga2V5KVxuICAgIGlmKCFjdXJyZW50Q3ljbGUpeyBjdXJyZW50Q3ljbGUgPSBjeWNsZSB9XG4gICAgaWYoY3VycmVudEN5Y2xlID09PSBjeWNsZSl7XG4gICAgICB0aGlzLmluY0N5Y2xlKGVsLCBrZXkpXG4gICAgICB0cmlnZ2VyKClcbiAgICB9XG4gIH0sXG5cbiAgb25jZShlbCwga2V5KXtcbiAgICBpZih0aGlzLnByaXZhdGUoZWwsIGtleSkgPT09IHRydWUpeyByZXR1cm4gZmFsc2UgfVxuICAgIHRoaXMucHV0UHJpdmF0ZShlbCwga2V5LCB0cnVlKVxuICAgIHJldHVybiB0cnVlXG4gIH0sXG5cbiAgaW5jQ3ljbGUoZWwsIGtleSwgdHJpZ2dlciA9IGZ1bmN0aW9uICgpeyB9KXtcbiAgICBsZXQgW2N1cnJlbnRDeWNsZV0gPSB0aGlzLnByaXZhdGUoZWwsIGtleSkgfHwgWzAsIHRyaWdnZXJdXG4gICAgY3VycmVudEN5Y2xlKytcbiAgICB0aGlzLnB1dFByaXZhdGUoZWwsIGtleSwgW2N1cnJlbnRDeWNsZSwgdHJpZ2dlcl0pXG4gICAgcmV0dXJuIGN1cnJlbnRDeWNsZVxuICB9LFxuXG4gIG1heWJlQWRkUHJpdmF0ZUhvb2tzKGVsLCBwaHhWaWV3cG9ydFRvcCwgcGh4Vmlld3BvcnRCb3R0b20pe1xuICAgIGlmKGVsLmhhc0F0dHJpYnV0ZSAmJiAoZWwuaGFzQXR0cmlidXRlKHBoeFZpZXdwb3J0VG9wKSB8fCBlbC5oYXNBdHRyaWJ1dGUocGh4Vmlld3BvcnRCb3R0b20pKSl7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoXCJkYXRhLXBoeC1ob29rXCIsIFwiUGhvZW5peC5JbmZpbml0ZVNjcm9sbFwiKVxuICAgIH1cbiAgfSxcblxuICBtYXliZUhpZGVGZWVkYmFjayhjb250YWluZXIsIGlucHV0LCBwaHhGZWVkYmFja0Zvcil7XG4gICAgaWYoISh0aGlzLnByaXZhdGUoaW5wdXQsIFBIWF9IQVNfRk9DVVNFRCkgfHwgdGhpcy5wcml2YXRlKGlucHV0LCBQSFhfSEFTX1NVQk1JVFRFRCkpKXtcbiAgICAgIGxldCBmZWVkYmFja3MgPSBbaW5wdXQubmFtZV1cbiAgICAgIGlmKGlucHV0Lm5hbWUuZW5kc1dpdGgoXCJbXVwiKSl7IGZlZWRiYWNrcy5wdXNoKGlucHV0Lm5hbWUuc2xpY2UoMCwgLTIpKSB9XG4gICAgICBsZXQgc2VsZWN0b3IgPSBmZWVkYmFja3MubWFwKGYgPT4gYFske3BoeEZlZWRiYWNrRm9yfT1cIiR7Zn1cIl1gKS5qb2luKFwiLCBcIilcbiAgICAgIERPTS5hbGwoY29udGFpbmVyLCBzZWxlY3RvciwgZWwgPT4gZWwuY2xhc3NMaXN0LmFkZChQSFhfTk9fRkVFREJBQ0tfQ0xBU1MpKVxuICAgIH1cbiAgfSxcblxuICByZXNldEZvcm0oZm9ybSwgcGh4RmVlZGJhY2tGb3Ipe1xuICAgIEFycmF5LmZyb20oZm9ybS5lbGVtZW50cykuZm9yRWFjaChpbnB1dCA9PiB7XG4gICAgICBsZXQgcXVlcnkgPSBgWyR7cGh4RmVlZGJhY2tGb3J9PVwiJHtpbnB1dC5pZH1cIl0sXG4gICAgICAgICAgICAgICAgICAgWyR7cGh4RmVlZGJhY2tGb3J9PVwiJHtpbnB1dC5uYW1lfVwiXSxcbiAgICAgICAgICAgICAgICAgICBbJHtwaHhGZWVkYmFja0Zvcn09XCIke2lucHV0Lm5hbWUucmVwbGFjZSgvXFxbXFxdJC8sIFwiXCIpfVwiXWBcblxuICAgICAgdGhpcy5kZWxldGVQcml2YXRlKGlucHV0LCBQSFhfSEFTX0ZPQ1VTRUQpXG4gICAgICB0aGlzLmRlbGV0ZVByaXZhdGUoaW5wdXQsIFBIWF9IQVNfU1VCTUlUVEVEKVxuICAgICAgdGhpcy5hbGwoZG9jdW1lbnQsIHF1ZXJ5LCBmZWVkYmFja0VsID0+IHtcbiAgICAgICAgZmVlZGJhY2tFbC5jbGFzc0xpc3QuYWRkKFBIWF9OT19GRUVEQkFDS19DTEFTUylcbiAgICAgIH0pXG4gICAgfSlcbiAgfSxcblxuICBzaG93RXJyb3IoaW5wdXRFbCwgcGh4RmVlZGJhY2tGb3Ipe1xuICAgIGlmKGlucHV0RWwuaWQgfHwgaW5wdXRFbC5uYW1lKXtcbiAgICAgIHRoaXMuYWxsKGlucHV0RWwuZm9ybSwgYFske3BoeEZlZWRiYWNrRm9yfT1cIiR7aW5wdXRFbC5pZH1cIl0sIFske3BoeEZlZWRiYWNrRm9yfT1cIiR7aW5wdXRFbC5uYW1lfVwiXWAsIChlbCkgPT4ge1xuICAgICAgICB0aGlzLnJlbW92ZUNsYXNzKGVsLCBQSFhfTk9fRkVFREJBQ0tfQ0xBU1MpXG4gICAgICB9KVxuICAgIH1cbiAgfSxcblxuICBpc1BoeENoaWxkKG5vZGUpe1xuICAgIHJldHVybiBub2RlLmdldEF0dHJpYnV0ZSAmJiBub2RlLmdldEF0dHJpYnV0ZShQSFhfUEFSRU5UX0lEKVxuICB9LFxuXG4gIGlzUGh4U3RpY2t5KG5vZGUpe1xuICAgIHJldHVybiBub2RlLmdldEF0dHJpYnV0ZSAmJiBub2RlLmdldEF0dHJpYnV0ZShQSFhfU1RJQ0tZKSAhPT0gbnVsbFxuICB9LFxuXG4gIGZpcnN0UGh4Q2hpbGQoZWwpe1xuICAgIHJldHVybiB0aGlzLmlzUGh4Q2hpbGQoZWwpID8gZWwgOiB0aGlzLmFsbChlbCwgYFske1BIWF9QQVJFTlRfSUR9XWApWzBdXG4gIH0sXG5cbiAgZGlzcGF0Y2hFdmVudCh0YXJnZXQsIG5hbWUsIG9wdHMgPSB7fSl7XG4gICAgbGV0IGJ1YmJsZXMgPSBvcHRzLmJ1YmJsZXMgPT09IHVuZGVmaW5lZCA/IHRydWUgOiAhIW9wdHMuYnViYmxlc1xuICAgIGxldCBldmVudE9wdHMgPSB7YnViYmxlczogYnViYmxlcywgY2FuY2VsYWJsZTogdHJ1ZSwgZGV0YWlsOiBvcHRzLmRldGFpbCB8fCB7fX1cbiAgICBsZXQgZXZlbnQgPSBuYW1lID09PSBcImNsaWNrXCIgPyBuZXcgTW91c2VFdmVudChcImNsaWNrXCIsIGV2ZW50T3B0cykgOiBuZXcgQ3VzdG9tRXZlbnQobmFtZSwgZXZlbnRPcHRzKVxuICAgIHRhcmdldC5kaXNwYXRjaEV2ZW50KGV2ZW50KVxuICB9LFxuXG4gIGNsb25lTm9kZShub2RlLCBodG1sKXtcbiAgICBpZih0eXBlb2YgKGh0bWwpID09PSBcInVuZGVmaW5lZFwiKXtcbiAgICAgIHJldHVybiBub2RlLmNsb25lTm9kZSh0cnVlKVxuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgY2xvbmVkID0gbm9kZS5jbG9uZU5vZGUoZmFsc2UpXG4gICAgICBjbG9uZWQuaW5uZXJIVE1MID0gaHRtbFxuICAgICAgcmV0dXJuIGNsb25lZFxuICAgIH1cbiAgfSxcblxuICBtZXJnZUF0dHJzKHRhcmdldCwgc291cmNlLCBvcHRzID0ge30pe1xuICAgIGxldCBleGNsdWRlID0gb3B0cy5leGNsdWRlIHx8IFtdXG4gICAgbGV0IGlzSWdub3JlZCA9IG9wdHMuaXNJZ25vcmVkXG4gICAgbGV0IHNvdXJjZUF0dHJzID0gc291cmNlLmF0dHJpYnV0ZXNcbiAgICBmb3IobGV0IGkgPSBzb3VyY2VBdHRycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSl7XG4gICAgICBsZXQgbmFtZSA9IHNvdXJjZUF0dHJzW2ldLm5hbWVcbiAgICAgIGlmKGV4Y2x1ZGUuaW5kZXhPZihuYW1lKSA8IDApeyB0YXJnZXQuc2V0QXR0cmlidXRlKG5hbWUsIHNvdXJjZS5nZXRBdHRyaWJ1dGUobmFtZSkpIH1cbiAgICB9XG5cbiAgICBsZXQgdGFyZ2V0QXR0cnMgPSB0YXJnZXQuYXR0cmlidXRlc1xuICAgIGZvcihsZXQgaSA9IHRhcmdldEF0dHJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKXtcbiAgICAgIGxldCBuYW1lID0gdGFyZ2V0QXR0cnNbaV0ubmFtZVxuICAgICAgaWYoaXNJZ25vcmVkKXtcbiAgICAgICAgaWYobmFtZS5zdGFydHNXaXRoKFwiZGF0YS1cIikgJiYgIXNvdXJjZS5oYXNBdHRyaWJ1dGUobmFtZSkpeyB0YXJnZXQucmVtb3ZlQXR0cmlidXRlKG5hbWUpIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmKCFzb3VyY2UuaGFzQXR0cmlidXRlKG5hbWUpKXsgdGFyZ2V0LnJlbW92ZUF0dHJpYnV0ZShuYW1lKSB9XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIG1lcmdlRm9jdXNlZElucHV0KHRhcmdldCwgc291cmNlKXtcbiAgICAvLyBza2lwIHNlbGVjdHMgYmVjYXVzZSBGRiB3aWxsIHJlc2V0IGhpZ2hsaWdodGVkIGluZGV4IGZvciBhbnkgc2V0QXR0cmlidXRlXG4gICAgaWYoISh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MU2VsZWN0RWxlbWVudCkpeyBET00ubWVyZ2VBdHRycyh0YXJnZXQsIHNvdXJjZSwge2V4Y2x1ZGU6IFtcInZhbHVlXCJdfSkgfVxuICAgIGlmKHNvdXJjZS5yZWFkT25seSl7XG4gICAgICB0YXJnZXQuc2V0QXR0cmlidXRlKFwicmVhZG9ubHlcIiwgdHJ1ZSlcbiAgICB9IGVsc2Uge1xuICAgICAgdGFyZ2V0LnJlbW92ZUF0dHJpYnV0ZShcInJlYWRvbmx5XCIpXG4gICAgfVxuICB9LFxuXG4gIGhhc1NlbGVjdGlvblJhbmdlKGVsKXtcbiAgICByZXR1cm4gZWwuc2V0U2VsZWN0aW9uUmFuZ2UgJiYgKGVsLnR5cGUgPT09IFwidGV4dFwiIHx8IGVsLnR5cGUgPT09IFwidGV4dGFyZWFcIilcbiAgfSxcblxuICByZXN0b3JlRm9jdXMoZm9jdXNlZCwgc2VsZWN0aW9uU3RhcnQsIHNlbGVjdGlvbkVuZCl7XG4gICAgaWYoIURPTS5pc1RleHR1YWxJbnB1dChmb2N1c2VkKSl7IHJldHVybiB9XG4gICAgbGV0IHdhc0ZvY3VzZWQgPSBmb2N1c2VkLm1hdGNoZXMoXCI6Zm9jdXNcIilcbiAgICBpZihmb2N1c2VkLnJlYWRPbmx5KXsgZm9jdXNlZC5ibHVyKCkgfVxuICAgIGlmKCF3YXNGb2N1c2VkKXsgZm9jdXNlZC5mb2N1cygpIH1cbiAgICBpZih0aGlzLmhhc1NlbGVjdGlvblJhbmdlKGZvY3VzZWQpKXtcbiAgICAgIGZvY3VzZWQuc2V0U2VsZWN0aW9uUmFuZ2Uoc2VsZWN0aW9uU3RhcnQsIHNlbGVjdGlvbkVuZClcbiAgICB9XG4gIH0sXG5cbiAgaXNGb3JtSW5wdXQoZWwpeyByZXR1cm4gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWEpJC9pLnRlc3QoZWwudGFnTmFtZSkgJiYgZWwudHlwZSAhPT0gXCJidXR0b25cIiB9LFxuXG4gIHN5bmNBdHRyc1RvUHJvcHMoZWwpe1xuICAgIGlmKGVsIGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCAmJiBDSEVDS0FCTEVfSU5QVVRTLmluZGV4T2YoZWwudHlwZS50b0xvY2FsZUxvd2VyQ2FzZSgpKSA+PSAwKXtcbiAgICAgIGVsLmNoZWNrZWQgPSBlbC5nZXRBdHRyaWJ1dGUoXCJjaGVja2VkXCIpICE9PSBudWxsXG4gICAgfVxuICB9LFxuXG4gIGlzVGV4dHVhbElucHV0KGVsKXsgcmV0dXJuIEZPQ1VTQUJMRV9JTlBVVFMuaW5kZXhPZihlbC50eXBlKSA+PSAwIH0sXG5cbiAgaXNOb3dUcmlnZ2VyRm9ybUV4dGVybmFsKGVsLCBwaHhUcmlnZ2VyRXh0ZXJuYWwpe1xuICAgIHJldHVybiBlbC5nZXRBdHRyaWJ1dGUgJiYgZWwuZ2V0QXR0cmlidXRlKHBoeFRyaWdnZXJFeHRlcm5hbCkgIT09IG51bGxcbiAgfSxcblxuICBzeW5jUGVuZGluZ1JlZihmcm9tRWwsIHRvRWwsIGRpc2FibGVXaXRoKXtcbiAgICBsZXQgcmVmID0gZnJvbUVsLmdldEF0dHJpYnV0ZShQSFhfUkVGKVxuICAgIGlmKHJlZiA9PT0gbnVsbCl7IHJldHVybiB0cnVlIH1cbiAgICBsZXQgcmVmU3JjID0gZnJvbUVsLmdldEF0dHJpYnV0ZShQSFhfUkVGX1NSQylcblxuICAgIGlmKERPTS5pc0Zvcm1JbnB1dChmcm9tRWwpIHx8IGZyb21FbC5nZXRBdHRyaWJ1dGUoZGlzYWJsZVdpdGgpICE9PSBudWxsKXtcbiAgICAgIGlmKERPTS5pc1VwbG9hZElucHV0KGZyb21FbCkpeyBET00ubWVyZ2VBdHRycyhmcm9tRWwsIHRvRWwsIHtpc0lnbm9yZWQ6IHRydWV9KSB9XG4gICAgICBET00ucHV0UHJpdmF0ZShmcm9tRWwsIFBIWF9SRUYsIHRvRWwpXG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9IGVsc2Uge1xuICAgICAgUEhYX0VWRU5UX0NMQVNTRVMuZm9yRWFjaChjbGFzc05hbWUgPT4ge1xuICAgICAgICBmcm9tRWwuY2xhc3NMaXN0LmNvbnRhaW5zKGNsYXNzTmFtZSkgJiYgdG9FbC5jbGFzc0xpc3QuYWRkKGNsYXNzTmFtZSlcbiAgICAgIH0pXG4gICAgICB0b0VsLnNldEF0dHJpYnV0ZShQSFhfUkVGLCByZWYpXG4gICAgICB0b0VsLnNldEF0dHJpYnV0ZShQSFhfUkVGX1NSQywgcmVmU3JjKVxuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH0sXG5cbiAgY2xlYW5DaGlsZE5vZGVzKGNvbnRhaW5lciwgcGh4VXBkYXRlKXtcbiAgICBpZihET00uaXNQaHhVcGRhdGUoY29udGFpbmVyLCBwaHhVcGRhdGUsIFtcImFwcGVuZFwiLCBcInByZXBlbmRcIl0pKXtcbiAgICAgIGxldCB0b1JlbW92ZSA9IFtdXG4gICAgICBjb250YWluZXIuY2hpbGROb2Rlcy5mb3JFYWNoKGNoaWxkTm9kZSA9PiB7XG4gICAgICAgIGlmKCFjaGlsZE5vZGUuaWQpe1xuICAgICAgICAgIC8vIFNraXAgd2FybmluZyBpZiBpdCdzIGFuIGVtcHR5IHRleHQgbm9kZSAoZS5nLiBhIG5ldy1saW5lKVxuICAgICAgICAgIGxldCBpc0VtcHR5VGV4dE5vZGUgPSBjaGlsZE5vZGUubm9kZVR5cGUgPT09IE5vZGUuVEVYVF9OT0RFICYmIGNoaWxkTm9kZS5ub2RlVmFsdWUudHJpbSgpID09PSBcIlwiXG4gICAgICAgICAgaWYoIWlzRW1wdHlUZXh0Tm9kZSl7XG4gICAgICAgICAgICBsb2dFcnJvcihcIm9ubHkgSFRNTCBlbGVtZW50IHRhZ3Mgd2l0aCBhbiBpZCBhcmUgYWxsb3dlZCBpbnNpZGUgY29udGFpbmVycyB3aXRoIHBoeC11cGRhdGUuXFxuXFxuXCIgK1xuICAgICAgICAgICAgICBgcmVtb3ZpbmcgaWxsZWdhbCBub2RlOiBcIiR7KGNoaWxkTm9kZS5vdXRlckhUTUwgfHwgY2hpbGROb2RlLm5vZGVWYWx1ZSkudHJpbSgpfVwiXFxuXFxuYClcbiAgICAgICAgICB9XG4gICAgICAgICAgdG9SZW1vdmUucHVzaChjaGlsZE5vZGUpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICB0b1JlbW92ZS5mb3JFYWNoKGNoaWxkTm9kZSA9PiBjaGlsZE5vZGUucmVtb3ZlKCkpXG4gICAgfVxuICB9LFxuXG4gIHJlcGxhY2VSb290Q29udGFpbmVyKGNvbnRhaW5lciwgdGFnTmFtZSwgYXR0cnMpe1xuICAgIGxldCByZXRhaW5lZEF0dHJzID0gbmV3IFNldChbXCJpZFwiLCBQSFhfU0VTU0lPTiwgUEhYX1NUQVRJQywgUEhYX01BSU4sIFBIWF9ST09UX0lEXSlcbiAgICBpZihjb250YWluZXIudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSB0YWdOYW1lLnRvTG93ZXJDYXNlKCkpe1xuICAgICAgQXJyYXkuZnJvbShjb250YWluZXIuYXR0cmlidXRlcylcbiAgICAgICAgLmZpbHRlcihhdHRyID0+ICFyZXRhaW5lZEF0dHJzLmhhcyhhdHRyLm5hbWUudG9Mb3dlckNhc2UoKSkpXG4gICAgICAgIC5mb3JFYWNoKGF0dHIgPT4gY29udGFpbmVyLnJlbW92ZUF0dHJpYnV0ZShhdHRyLm5hbWUpKVxuXG4gICAgICBPYmplY3Qua2V5cyhhdHRycylcbiAgICAgICAgLmZpbHRlcihuYW1lID0+ICFyZXRhaW5lZEF0dHJzLmhhcyhuYW1lLnRvTG93ZXJDYXNlKCkpKVxuICAgICAgICAuZm9yRWFjaChhdHRyID0+IGNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoYXR0ciwgYXR0cnNbYXR0cl0pKVxuXG4gICAgICByZXR1cm4gY29udGFpbmVyXG5cbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IG5ld0NvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSlcbiAgICAgIE9iamVjdC5rZXlzKGF0dHJzKS5mb3JFYWNoKGF0dHIgPT4gbmV3Q29udGFpbmVyLnNldEF0dHJpYnV0ZShhdHRyLCBhdHRyc1thdHRyXSkpXG4gICAgICByZXRhaW5lZEF0dHJzLmZvckVhY2goYXR0ciA9PiBuZXdDb250YWluZXIuc2V0QXR0cmlidXRlKGF0dHIsIGNvbnRhaW5lci5nZXRBdHRyaWJ1dGUoYXR0cikpKVxuICAgICAgbmV3Q29udGFpbmVyLmlubmVySFRNTCA9IGNvbnRhaW5lci5pbm5lckhUTUxcbiAgICAgIGNvbnRhaW5lci5yZXBsYWNlV2l0aChuZXdDb250YWluZXIpXG4gICAgICByZXR1cm4gbmV3Q29udGFpbmVyXG4gICAgfVxuICB9LFxuXG4gIGdldFN0aWNreShlbCwgbmFtZSwgZGVmYXVsdFZhbCl7XG4gICAgbGV0IG9wID0gKERPTS5wcml2YXRlKGVsLCBcInN0aWNreVwiKSB8fCBbXSkuZmluZCgoW2V4aXN0aW5nTmFtZSwgXSkgPT4gbmFtZSA9PT0gZXhpc3RpbmdOYW1lKVxuICAgIGlmKG9wKXtcbiAgICAgIGxldCBbX25hbWUsIF9vcCwgc3Rhc2hlZFJlc3VsdF0gPSBvcFxuICAgICAgcmV0dXJuIHN0YXNoZWRSZXN1bHRcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHR5cGVvZihkZWZhdWx0VmFsKSA9PT0gXCJmdW5jdGlvblwiID8gZGVmYXVsdFZhbCgpIDogZGVmYXVsdFZhbFxuICAgIH1cbiAgfSxcblxuICBkZWxldGVTdGlja3koZWwsIG5hbWUpe1xuICAgIHRoaXMudXBkYXRlUHJpdmF0ZShlbCwgXCJzdGlja3lcIiwgW10sIG9wcyA9PiB7XG4gICAgICByZXR1cm4gb3BzLmZpbHRlcigoW2V4aXN0aW5nTmFtZSwgX10pID0+IGV4aXN0aW5nTmFtZSAhPT0gbmFtZSlcbiAgICB9KVxuICB9LFxuXG4gIHB1dFN0aWNreShlbCwgbmFtZSwgb3Ape1xuICAgIGxldCBzdGFzaGVkUmVzdWx0ID0gb3AoZWwpXG4gICAgdGhpcy51cGRhdGVQcml2YXRlKGVsLCBcInN0aWNreVwiLCBbXSwgb3BzID0+IHtcbiAgICAgIGxldCBleGlzdGluZ0luZGV4ID0gb3BzLmZpbmRJbmRleCgoW2V4aXN0aW5nTmFtZSwgXSkgPT4gbmFtZSA9PT0gZXhpc3RpbmdOYW1lKVxuICAgICAgaWYoZXhpc3RpbmdJbmRleCA+PSAwKXtcbiAgICAgICAgb3BzW2V4aXN0aW5nSW5kZXhdID0gW25hbWUsIG9wLCBzdGFzaGVkUmVzdWx0XVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3BzLnB1c2goW25hbWUsIG9wLCBzdGFzaGVkUmVzdWx0XSlcbiAgICAgIH1cbiAgICAgIHJldHVybiBvcHNcbiAgICB9KVxuICB9LFxuXG4gIGFwcGx5U3RpY2t5T3BlcmF0aW9ucyhlbCl7XG4gICAgbGV0IG9wcyA9IERPTS5wcml2YXRlKGVsLCBcInN0aWNreVwiKVxuICAgIGlmKCFvcHMpeyByZXR1cm4gfVxuXG4gICAgb3BzLmZvckVhY2goKFtuYW1lLCBvcCwgX3N0YXNoZWRdKSA9PiB0aGlzLnB1dFN0aWNreShlbCwgbmFtZSwgb3ApKVxuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IERPTVxuIiwgImltcG9ydCB7XG4gIFBIWF9BQ1RJVkVfRU5UUllfUkVGUyxcbiAgUEhYX0xJVkVfRklMRV9VUERBVEVELFxuICBQSFhfUFJFRkxJR0hURURfUkVGU1xufSBmcm9tIFwiLi9jb25zdGFudHNcIlxuXG5pbXBvcnQge1xuICBjaGFubmVsVXBsb2FkZXIsXG4gIGxvZ0Vycm9yXG59IGZyb20gXCIuL3V0aWxzXCJcblxuaW1wb3J0IExpdmVVcGxvYWRlciBmcm9tIFwiLi9saXZlX3VwbG9hZGVyXCJcbmltcG9ydCBET00gZnJvbSBcIi4vZG9tXCJcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVXBsb2FkRW50cnkge1xuICBzdGF0aWMgaXNBY3RpdmUoZmlsZUVsLCBmaWxlKXtcbiAgICBsZXQgaXNOZXcgPSBmaWxlLl9waHhSZWYgPT09IHVuZGVmaW5lZFxuICAgIGxldCBhY3RpdmVSZWZzID0gZmlsZUVsLmdldEF0dHJpYnV0ZShQSFhfQUNUSVZFX0VOVFJZX1JFRlMpLnNwbGl0KFwiLFwiKVxuICAgIGxldCBpc0FjdGl2ZSA9IGFjdGl2ZVJlZnMuaW5kZXhPZihMaXZlVXBsb2FkZXIuZ2VuRmlsZVJlZihmaWxlKSkgPj0gMFxuICAgIHJldHVybiBmaWxlLnNpemUgPiAwICYmIChpc05ldyB8fCBpc0FjdGl2ZSlcbiAgfVxuXG4gIHN0YXRpYyBpc1ByZWZsaWdodGVkKGZpbGVFbCwgZmlsZSl7XG4gICAgbGV0IHByZWZsaWdodGVkUmVmcyA9IGZpbGVFbC5nZXRBdHRyaWJ1dGUoUEhYX1BSRUZMSUdIVEVEX1JFRlMpLnNwbGl0KFwiLFwiKVxuICAgIGxldCBpc1ByZWZsaWdodGVkID0gcHJlZmxpZ2h0ZWRSZWZzLmluZGV4T2YoTGl2ZVVwbG9hZGVyLmdlbkZpbGVSZWYoZmlsZSkpID49IDBcbiAgICByZXR1cm4gaXNQcmVmbGlnaHRlZCAmJiB0aGlzLmlzQWN0aXZlKGZpbGVFbCwgZmlsZSlcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKGZpbGVFbCwgZmlsZSwgdmlldyl7XG4gICAgdGhpcy5yZWYgPSBMaXZlVXBsb2FkZXIuZ2VuRmlsZVJlZihmaWxlKVxuICAgIHRoaXMuZmlsZUVsID0gZmlsZUVsXG4gICAgdGhpcy5maWxlID0gZmlsZVxuICAgIHRoaXMudmlldyA9IHZpZXdcbiAgICB0aGlzLm1ldGEgPSBudWxsXG4gICAgdGhpcy5faXNDYW5jZWxsZWQgPSBmYWxzZVxuICAgIHRoaXMuX2lzRG9uZSA9IGZhbHNlXG4gICAgdGhpcy5fcHJvZ3Jlc3MgPSAwXG4gICAgdGhpcy5fbGFzdFByb2dyZXNzU2VudCA9IC0xXG4gICAgdGhpcy5fb25Eb25lID0gZnVuY3Rpb24gKCl7IH1cbiAgICB0aGlzLl9vbkVsVXBkYXRlZCA9IHRoaXMub25FbFVwZGF0ZWQuYmluZCh0aGlzKVxuICAgIHRoaXMuZmlsZUVsLmFkZEV2ZW50TGlzdGVuZXIoUEhYX0xJVkVfRklMRV9VUERBVEVELCB0aGlzLl9vbkVsVXBkYXRlZClcbiAgfVxuXG4gIG1ldGFkYXRhKCl7IHJldHVybiB0aGlzLm1ldGEgfVxuXG4gIHByb2dyZXNzKHByb2dyZXNzKXtcbiAgICB0aGlzLl9wcm9ncmVzcyA9IE1hdGguZmxvb3IocHJvZ3Jlc3MpXG4gICAgaWYodGhpcy5fcHJvZ3Jlc3MgPiB0aGlzLl9sYXN0UHJvZ3Jlc3NTZW50KXtcbiAgICAgIGlmKHRoaXMuX3Byb2dyZXNzID49IDEwMCl7XG4gICAgICAgIHRoaXMuX3Byb2dyZXNzID0gMTAwXG4gICAgICAgIHRoaXMuX2xhc3RQcm9ncmVzc1NlbnQgPSAxMDBcbiAgICAgICAgdGhpcy5faXNEb25lID0gdHJ1ZVxuICAgICAgICB0aGlzLnZpZXcucHVzaEZpbGVQcm9ncmVzcyh0aGlzLmZpbGVFbCwgdGhpcy5yZWYsIDEwMCwgKCkgPT4ge1xuICAgICAgICAgIExpdmVVcGxvYWRlci51bnRyYWNrRmlsZSh0aGlzLmZpbGVFbCwgdGhpcy5maWxlKVxuICAgICAgICAgIHRoaXMuX29uRG9uZSgpXG4gICAgICAgIH0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9sYXN0UHJvZ3Jlc3NTZW50ID0gdGhpcy5fcHJvZ3Jlc3NcbiAgICAgICAgdGhpcy52aWV3LnB1c2hGaWxlUHJvZ3Jlc3ModGhpcy5maWxlRWwsIHRoaXMucmVmLCB0aGlzLl9wcm9ncmVzcylcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjYW5jZWwoKXtcbiAgICB0aGlzLl9pc0NhbmNlbGxlZCA9IHRydWVcbiAgICB0aGlzLl9pc0RvbmUgPSB0cnVlXG4gICAgdGhpcy5fb25Eb25lKClcbiAgfVxuXG4gIGlzRG9uZSgpeyByZXR1cm4gdGhpcy5faXNEb25lIH1cblxuICBlcnJvcihyZWFzb24gPSBcImZhaWxlZFwiKXtcbiAgICB0aGlzLmZpbGVFbC5yZW1vdmVFdmVudExpc3RlbmVyKFBIWF9MSVZFX0ZJTEVfVVBEQVRFRCwgdGhpcy5fb25FbFVwZGF0ZWQpXG4gICAgdGhpcy52aWV3LnB1c2hGaWxlUHJvZ3Jlc3ModGhpcy5maWxlRWwsIHRoaXMucmVmLCB7ZXJyb3I6IHJlYXNvbn0pXG4gICAgaWYoIURPTS5pc0F1dG9VcGxvYWQodGhpcy5maWxlRWwpKXsgTGl2ZVVwbG9hZGVyLmNsZWFyRmlsZXModGhpcy5maWxlRWwpIH1cbiAgfVxuXG4gIC8vcHJpdmF0ZVxuXG4gIG9uRG9uZShjYWxsYmFjayl7XG4gICAgdGhpcy5fb25Eb25lID0gKCkgPT4ge1xuICAgICAgdGhpcy5maWxlRWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihQSFhfTElWRV9GSUxFX1VQREFURUQsIHRoaXMuX29uRWxVcGRhdGVkKVxuICAgICAgY2FsbGJhY2soKVxuICAgIH1cbiAgfVxuXG4gIG9uRWxVcGRhdGVkKCl7XG4gICAgbGV0IGFjdGl2ZVJlZnMgPSB0aGlzLmZpbGVFbC5nZXRBdHRyaWJ1dGUoUEhYX0FDVElWRV9FTlRSWV9SRUZTKS5zcGxpdChcIixcIilcbiAgICBpZihhY3RpdmVSZWZzLmluZGV4T2YodGhpcy5yZWYpID09PSAtMSl7IHRoaXMuY2FuY2VsKCkgfVxuICB9XG5cbiAgdG9QcmVmbGlnaHRQYXlsb2FkKCl7XG4gICAgcmV0dXJuIHtcbiAgICAgIGxhc3RfbW9kaWZpZWQ6IHRoaXMuZmlsZS5sYXN0TW9kaWZpZWQsXG4gICAgICBuYW1lOiB0aGlzLmZpbGUubmFtZSxcbiAgICAgIHJlbGF0aXZlX3BhdGg6IHRoaXMuZmlsZS53ZWJraXRSZWxhdGl2ZVBhdGgsXG4gICAgICBzaXplOiB0aGlzLmZpbGUuc2l6ZSxcbiAgICAgIHR5cGU6IHRoaXMuZmlsZS50eXBlLFxuICAgICAgcmVmOiB0aGlzLnJlZlxuICAgIH1cbiAgfVxuXG4gIHVwbG9hZGVyKHVwbG9hZGVycyl7XG4gICAgaWYodGhpcy5tZXRhLnVwbG9hZGVyKXtcbiAgICAgIGxldCBjYWxsYmFjayA9IHVwbG9hZGVyc1t0aGlzLm1ldGEudXBsb2FkZXJdIHx8IGxvZ0Vycm9yKGBubyB1cGxvYWRlciBjb25maWd1cmVkIGZvciAke3RoaXMubWV0YS51cGxvYWRlcn1gKVxuICAgICAgcmV0dXJuIHtuYW1lOiB0aGlzLm1ldGEudXBsb2FkZXIsIGNhbGxiYWNrOiBjYWxsYmFja31cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHtuYW1lOiBcImNoYW5uZWxcIiwgY2FsbGJhY2s6IGNoYW5uZWxVcGxvYWRlcn1cbiAgICB9XG4gIH1cblxuICB6aXBQb3N0RmxpZ2h0KHJlc3Ape1xuICAgIHRoaXMubWV0YSA9IHJlc3AuZW50cmllc1t0aGlzLnJlZl1cbiAgICBpZighdGhpcy5tZXRhKXsgbG9nRXJyb3IoYG5vIHByZWZsaWdodCB1cGxvYWQgcmVzcG9uc2UgcmV0dXJuZWQgd2l0aCByZWYgJHt0aGlzLnJlZn1gLCB7aW5wdXQ6IHRoaXMuZmlsZUVsLCByZXNwb25zZTogcmVzcH0pIH1cbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIFBIWF9ET05FX1JFRlMsXG4gIFBIWF9QUkVGTElHSFRFRF9SRUZTLFxuICBQSFhfVVBMT0FEX1JFRlxufSBmcm9tIFwiLi9jb25zdGFudHNcIlxuXG5pbXBvcnQge1xufSBmcm9tIFwiLi91dGlsc1wiXG5cbmltcG9ydCBET00gZnJvbSBcIi4vZG9tXCJcbmltcG9ydCBVcGxvYWRFbnRyeSBmcm9tIFwiLi91cGxvYWRfZW50cnlcIlxuXG5sZXQgbGl2ZVVwbG9hZGVyRmlsZVJlZiA9IDBcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTGl2ZVVwbG9hZGVyIHtcbiAgc3RhdGljIGdlbkZpbGVSZWYoZmlsZSl7XG4gICAgbGV0IHJlZiA9IGZpbGUuX3BoeFJlZlxuICAgIGlmKHJlZiAhPT0gdW5kZWZpbmVkKXtcbiAgICAgIHJldHVybiByZWZcbiAgICB9IGVsc2Uge1xuICAgICAgZmlsZS5fcGh4UmVmID0gKGxpdmVVcGxvYWRlckZpbGVSZWYrKykudG9TdHJpbmcoKVxuICAgICAgcmV0dXJuIGZpbGUuX3BoeFJlZlxuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBnZXRFbnRyeURhdGFVUkwoaW5wdXRFbCwgcmVmLCBjYWxsYmFjayl7XG4gICAgbGV0IGZpbGUgPSB0aGlzLmFjdGl2ZUZpbGVzKGlucHV0RWwpLmZpbmQoZmlsZSA9PiB0aGlzLmdlbkZpbGVSZWYoZmlsZSkgPT09IHJlZilcbiAgICBjYWxsYmFjayhVUkwuY3JlYXRlT2JqZWN0VVJMKGZpbGUpKVxuICB9XG5cbiAgc3RhdGljIGhhc1VwbG9hZHNJblByb2dyZXNzKGZvcm1FbCl7XG4gICAgbGV0IGFjdGl2ZSA9IDBcbiAgICBET00uZmluZFVwbG9hZElucHV0cyhmb3JtRWwpLmZvckVhY2goaW5wdXQgPT4ge1xuICAgICAgaWYoaW5wdXQuZ2V0QXR0cmlidXRlKFBIWF9QUkVGTElHSFRFRF9SRUZTKSAhPT0gaW5wdXQuZ2V0QXR0cmlidXRlKFBIWF9ET05FX1JFRlMpKXtcbiAgICAgICAgYWN0aXZlKytcbiAgICAgIH1cbiAgICB9KVxuICAgIHJldHVybiBhY3RpdmUgPiAwXG4gIH1cblxuICBzdGF0aWMgc2VyaWFsaXplVXBsb2FkcyhpbnB1dEVsKXtcbiAgICBsZXQgZmlsZXMgPSB0aGlzLmFjdGl2ZUZpbGVzKGlucHV0RWwpXG4gICAgbGV0IGZpbGVEYXRhID0ge31cbiAgICBmaWxlcy5mb3JFYWNoKGZpbGUgPT4ge1xuICAgICAgbGV0IGVudHJ5ID0ge3BhdGg6IGlucHV0RWwubmFtZX1cbiAgICAgIGxldCB1cGxvYWRSZWYgPSBpbnB1dEVsLmdldEF0dHJpYnV0ZShQSFhfVVBMT0FEX1JFRilcbiAgICAgIGZpbGVEYXRhW3VwbG9hZFJlZl0gPSBmaWxlRGF0YVt1cGxvYWRSZWZdIHx8IFtdXG4gICAgICBlbnRyeS5yZWYgPSB0aGlzLmdlbkZpbGVSZWYoZmlsZSlcbiAgICAgIGVudHJ5Lmxhc3RfbW9kaWZpZWQgPSBmaWxlLmxhc3RNb2RpZmllZFxuICAgICAgZW50cnkubmFtZSA9IGZpbGUubmFtZSB8fCBlbnRyeS5yZWZcbiAgICAgIGVudHJ5LnJlbGF0aXZlX3BhdGggPSBmaWxlLndlYmtpdFJlbGF0aXZlUGF0aFxuICAgICAgZW50cnkudHlwZSA9IGZpbGUudHlwZVxuICAgICAgZW50cnkuc2l6ZSA9IGZpbGUuc2l6ZVxuICAgICAgZmlsZURhdGFbdXBsb2FkUmVmXS5wdXNoKGVudHJ5KVxuICAgIH0pXG4gICAgcmV0dXJuIGZpbGVEYXRhXG4gIH1cblxuICBzdGF0aWMgY2xlYXJGaWxlcyhpbnB1dEVsKXtcbiAgICBpbnB1dEVsLnZhbHVlID0gbnVsbFxuICAgIGlucHV0RWwucmVtb3ZlQXR0cmlidXRlKFBIWF9VUExPQURfUkVGKVxuICAgIERPTS5wdXRQcml2YXRlKGlucHV0RWwsIFwiZmlsZXNcIiwgW10pXG4gIH1cblxuICBzdGF0aWMgdW50cmFja0ZpbGUoaW5wdXRFbCwgZmlsZSl7XG4gICAgRE9NLnB1dFByaXZhdGUoaW5wdXRFbCwgXCJmaWxlc1wiLCBET00ucHJpdmF0ZShpbnB1dEVsLCBcImZpbGVzXCIpLmZpbHRlcihmID0+ICFPYmplY3QuaXMoZiwgZmlsZSkpKVxuICB9XG5cbiAgc3RhdGljIHRyYWNrRmlsZXMoaW5wdXRFbCwgZmlsZXMsIGRhdGFUcmFuc2Zlcil7XG4gICAgaWYoaW5wdXRFbC5nZXRBdHRyaWJ1dGUoXCJtdWx0aXBsZVwiKSAhPT0gbnVsbCl7XG4gICAgICBsZXQgbmV3RmlsZXMgPSBmaWxlcy5maWx0ZXIoZmlsZSA9PiAhdGhpcy5hY3RpdmVGaWxlcyhpbnB1dEVsKS5maW5kKGYgPT4gT2JqZWN0LmlzKGYsIGZpbGUpKSlcbiAgICAgIERPTS5wdXRQcml2YXRlKGlucHV0RWwsIFwiZmlsZXNcIiwgdGhpcy5hY3RpdmVGaWxlcyhpbnB1dEVsKS5jb25jYXQobmV3RmlsZXMpKVxuICAgICAgaW5wdXRFbC52YWx1ZSA9IG51bGxcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUmVzZXQgaW5wdXRFbCBmaWxlcyB0byBhbGlnbiBvdXRwdXQgd2l0aCBwcm9ncmFtbWF0aWMgY2hhbmdlcyAoaS5lLiBkcmFnIGFuZCBkcm9wKVxuICAgICAgaWYoZGF0YVRyYW5zZmVyICYmIGRhdGFUcmFuc2Zlci5maWxlcy5sZW5ndGggPiAwKXsgaW5wdXRFbC5maWxlcyA9IGRhdGFUcmFuc2Zlci5maWxlcyB9XG4gICAgICBET00ucHV0UHJpdmF0ZShpbnB1dEVsLCBcImZpbGVzXCIsIGZpbGVzKVxuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBhY3RpdmVGaWxlSW5wdXRzKGZvcm1FbCl7XG4gICAgbGV0IGZpbGVJbnB1dHMgPSBET00uZmluZFVwbG9hZElucHV0cyhmb3JtRWwpXG4gICAgcmV0dXJuIEFycmF5LmZyb20oZmlsZUlucHV0cykuZmlsdGVyKGVsID0+IGVsLmZpbGVzICYmIHRoaXMuYWN0aXZlRmlsZXMoZWwpLmxlbmd0aCA+IDApXG4gIH1cblxuICBzdGF0aWMgYWN0aXZlRmlsZXMoaW5wdXQpe1xuICAgIHJldHVybiAoRE9NLnByaXZhdGUoaW5wdXQsIFwiZmlsZXNcIikgfHwgW10pLmZpbHRlcihmID0+IFVwbG9hZEVudHJ5LmlzQWN0aXZlKGlucHV0LCBmKSlcbiAgfVxuXG4gIHN0YXRpYyBpbnB1dHNBd2FpdGluZ1ByZWZsaWdodChmb3JtRWwpe1xuICAgIGxldCBmaWxlSW5wdXRzID0gRE9NLmZpbmRVcGxvYWRJbnB1dHMoZm9ybUVsKVxuICAgIHJldHVybiBBcnJheS5mcm9tKGZpbGVJbnB1dHMpLmZpbHRlcihpbnB1dCA9PiB0aGlzLmZpbGVzQXdhaXRpbmdQcmVmbGlnaHQoaW5wdXQpLmxlbmd0aCA+IDApXG4gIH1cblxuICBzdGF0aWMgZmlsZXNBd2FpdGluZ1ByZWZsaWdodChpbnB1dCl7XG4gICAgcmV0dXJuIHRoaXMuYWN0aXZlRmlsZXMoaW5wdXQpLmZpbHRlcihmID0+ICFVcGxvYWRFbnRyeS5pc1ByZWZsaWdodGVkKGlucHV0LCBmKSlcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKGlucHV0RWwsIHZpZXcsIG9uQ29tcGxldGUpe1xuICAgIHRoaXMudmlldyA9IHZpZXdcbiAgICB0aGlzLm9uQ29tcGxldGUgPSBvbkNvbXBsZXRlXG4gICAgdGhpcy5fZW50cmllcyA9XG4gICAgICBBcnJheS5mcm9tKExpdmVVcGxvYWRlci5maWxlc0F3YWl0aW5nUHJlZmxpZ2h0KGlucHV0RWwpIHx8IFtdKVxuICAgICAgICAubWFwKGZpbGUgPT4gbmV3IFVwbG9hZEVudHJ5KGlucHV0RWwsIGZpbGUsIHZpZXcpKVxuXG4gICAgdGhpcy5udW1FbnRyaWVzSW5Qcm9ncmVzcyA9IHRoaXMuX2VudHJpZXMubGVuZ3RoXG4gIH1cblxuICBlbnRyaWVzKCl7IHJldHVybiB0aGlzLl9lbnRyaWVzIH1cblxuICBpbml0QWRhcHRlclVwbG9hZChyZXNwLCBvbkVycm9yLCBsaXZlU29ja2V0KXtcbiAgICB0aGlzLl9lbnRyaWVzID1cbiAgICAgIHRoaXMuX2VudHJpZXMubWFwKGVudHJ5ID0+IHtcbiAgICAgICAgZW50cnkuemlwUG9zdEZsaWdodChyZXNwKVxuICAgICAgICBlbnRyeS5vbkRvbmUoKCkgPT4ge1xuICAgICAgICAgIHRoaXMubnVtRW50cmllc0luUHJvZ3Jlc3MtLVxuICAgICAgICAgIGlmKHRoaXMubnVtRW50cmllc0luUHJvZ3Jlc3MgPT09IDApeyB0aGlzLm9uQ29tcGxldGUoKSB9XG4gICAgICAgIH0pXG4gICAgICAgIHJldHVybiBlbnRyeVxuICAgICAgfSlcblxuICAgIGxldCBncm91cGVkRW50cmllcyA9IHRoaXMuX2VudHJpZXMucmVkdWNlKChhY2MsIGVudHJ5KSA9PiB7XG4gICAgICBpZighZW50cnkubWV0YSl7IHJldHVybiBhY2MgfVxuICAgICAgbGV0IHtuYW1lLCBjYWxsYmFja30gPSBlbnRyeS51cGxvYWRlcihsaXZlU29ja2V0LnVwbG9hZGVycylcbiAgICAgIGFjY1tuYW1lXSA9IGFjY1tuYW1lXSB8fCB7Y2FsbGJhY2s6IGNhbGxiYWNrLCBlbnRyaWVzOiBbXX1cbiAgICAgIGFjY1tuYW1lXS5lbnRyaWVzLnB1c2goZW50cnkpXG4gICAgICByZXR1cm4gYWNjXG4gICAgfSwge30pXG5cbiAgICBmb3IobGV0IG5hbWUgaW4gZ3JvdXBlZEVudHJpZXMpe1xuICAgICAgbGV0IHtjYWxsYmFjaywgZW50cmllc30gPSBncm91cGVkRW50cmllc1tuYW1lXVxuICAgICAgY2FsbGJhY2soZW50cmllcywgb25FcnJvciwgcmVzcCwgbGl2ZVNvY2tldClcbiAgICB9XG4gIH1cbn1cbiIsICJsZXQgQVJJQSA9IHtcbiAgZm9jdXNNYWluKCl7XG4gICAgbGV0IHRhcmdldCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJtYWluIGgxLCBtYWluLCBoMVwiKVxuICAgIGlmKHRhcmdldCl7XG4gICAgICBsZXQgb3JpZ1RhYkluZGV4ID0gdGFyZ2V0LnRhYkluZGV4XG4gICAgICB0YXJnZXQudGFiSW5kZXggPSAtMVxuICAgICAgdGFyZ2V0LmZvY3VzKClcbiAgICAgIHRhcmdldC50YWJJbmRleCA9IG9yaWdUYWJJbmRleFxuICAgIH1cbiAgfSxcblxuICBhbnlPZihpbnN0YW5jZSwgY2xhc3Nlcyl7IHJldHVybiBjbGFzc2VzLmZpbmQobmFtZSA9PiBpbnN0YW5jZSBpbnN0YW5jZW9mIG5hbWUpIH0sXG5cbiAgaXNGb2N1c2FibGUoZWwsIGludGVyYWN0aXZlT25seSl7XG4gICAgcmV0dXJuKFxuICAgICAgKGVsIGluc3RhbmNlb2YgSFRNTEFuY2hvckVsZW1lbnQgJiYgZWwucmVsICE9PSBcImlnbm9yZVwiKSB8fFxuICAgICAgKGVsIGluc3RhbmNlb2YgSFRNTEFyZWFFbGVtZW50ICYmIGVsLmhyZWYgIT09IHVuZGVmaW5lZCkgfHxcbiAgICAgICghZWwuZGlzYWJsZWQgJiYgKHRoaXMuYW55T2YoZWwsIFtIVE1MSW5wdXRFbGVtZW50LCBIVE1MU2VsZWN0RWxlbWVudCwgSFRNTFRleHRBcmVhRWxlbWVudCwgSFRNTEJ1dHRvbkVsZW1lbnRdKSkpIHx8XG4gICAgICAoZWwgaW5zdGFuY2VvZiBIVE1MSUZyYW1lRWxlbWVudCkgfHxcbiAgICAgIChlbC50YWJJbmRleCA+IDAgfHwgKCFpbnRlcmFjdGl2ZU9ubHkgJiYgZWwudGFiSW5kZXggPT09IDAgJiYgZWwuZ2V0QXR0cmlidXRlKFwidGFiaW5kZXhcIikgIT09IG51bGwgJiYgZWwuZ2V0QXR0cmlidXRlKFwiYXJpYS1oaWRkZW5cIikgIT09IFwidHJ1ZVwiKSlcbiAgICApXG4gIH0sXG5cbiAgYXR0ZW1wdEZvY3VzKGVsLCBpbnRlcmFjdGl2ZU9ubHkpe1xuICAgIGlmKHRoaXMuaXNGb2N1c2FibGUoZWwsIGludGVyYWN0aXZlT25seSkpeyB0cnl7IGVsLmZvY3VzKCkgfSBjYXRjaChlKXt9IH1cbiAgICByZXR1cm4gISFkb2N1bWVudC5hY3RpdmVFbGVtZW50ICYmIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQuaXNTYW1lTm9kZShlbClcbiAgfSxcblxuICBmb2N1c0ZpcnN0SW50ZXJhY3RpdmUoZWwpe1xuICAgIGxldCBjaGlsZCA9IGVsLmZpcnN0RWxlbWVudENoaWxkXG4gICAgd2hpbGUoY2hpbGQpe1xuICAgICAgaWYodGhpcy5hdHRlbXB0Rm9jdXMoY2hpbGQsIHRydWUpIHx8IHRoaXMuZm9jdXNGaXJzdEludGVyYWN0aXZlKGNoaWxkLCB0cnVlKSl7XG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgICB9XG4gICAgICBjaGlsZCA9IGNoaWxkLm5leHRFbGVtZW50U2libGluZ1xuICAgIH1cbiAgfSxcblxuICBmb2N1c0ZpcnN0KGVsKXtcbiAgICBsZXQgY2hpbGQgPSBlbC5maXJzdEVsZW1lbnRDaGlsZFxuICAgIHdoaWxlKGNoaWxkKXtcbiAgICAgIGlmKHRoaXMuYXR0ZW1wdEZvY3VzKGNoaWxkKSB8fCB0aGlzLmZvY3VzRmlyc3QoY2hpbGQpKXtcbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgIH1cbiAgICAgIGNoaWxkID0gY2hpbGQubmV4dEVsZW1lbnRTaWJsaW5nXG4gICAgfVxuICB9LFxuXG4gIGZvY3VzTGFzdChlbCl7XG4gICAgbGV0IGNoaWxkID0gZWwubGFzdEVsZW1lbnRDaGlsZFxuICAgIHdoaWxlKGNoaWxkKXtcbiAgICAgIGlmKHRoaXMuYXR0ZW1wdEZvY3VzKGNoaWxkKSB8fCB0aGlzLmZvY3VzTGFzdChjaGlsZCkpe1xuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfVxuICAgICAgY2hpbGQgPSBjaGlsZC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nXG4gICAgfVxuICB9XG59XG5leHBvcnQgZGVmYXVsdCBBUklBIiwgImltcG9ydCB7XG4gIFBIWF9BQ1RJVkVfRU5UUllfUkVGUyxcbiAgUEhYX0xJVkVfRklMRV9VUERBVEVELFxuICBQSFhfUFJFRkxJR0hURURfUkVGUyxcbiAgUEhYX1VQTE9BRF9SRUZcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCJcblxuaW1wb3J0IExpdmVVcGxvYWRlciBmcm9tIFwiLi9saXZlX3VwbG9hZGVyXCJcbmltcG9ydCBBUklBIGZyb20gXCIuL2FyaWFcIlxuXG5sZXQgSG9va3MgPSB7XG4gIExpdmVGaWxlVXBsb2FkOiB7XG4gICAgYWN0aXZlUmVmcygpeyByZXR1cm4gdGhpcy5lbC5nZXRBdHRyaWJ1dGUoUEhYX0FDVElWRV9FTlRSWV9SRUZTKSB9LFxuXG4gICAgcHJlZmxpZ2h0ZWRSZWZzKCl7IHJldHVybiB0aGlzLmVsLmdldEF0dHJpYnV0ZShQSFhfUFJFRkxJR0hURURfUkVGUykgfSxcblxuICAgIG1vdW50ZWQoKXsgdGhpcy5wcmVmbGlnaHRlZFdhcyA9IHRoaXMucHJlZmxpZ2h0ZWRSZWZzKCkgfSxcblxuICAgIHVwZGF0ZWQoKXtcbiAgICAgIGxldCBuZXdQcmVmbGlnaHRzID0gdGhpcy5wcmVmbGlnaHRlZFJlZnMoKVxuICAgICAgaWYodGhpcy5wcmVmbGlnaHRlZFdhcyAhPT0gbmV3UHJlZmxpZ2h0cyl7XG4gICAgICAgIHRoaXMucHJlZmxpZ2h0ZWRXYXMgPSBuZXdQcmVmbGlnaHRzXG4gICAgICAgIGlmKG5ld1ByZWZsaWdodHMgPT09IFwiXCIpe1xuICAgICAgICAgIHRoaXMuX192aWV3LmNhbmNlbFN1Ym1pdCh0aGlzLmVsLmZvcm0pXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYodGhpcy5hY3RpdmVSZWZzKCkgPT09IFwiXCIpeyB0aGlzLmVsLnZhbHVlID0gbnVsbCB9XG4gICAgICB0aGlzLmVsLmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KFBIWF9MSVZFX0ZJTEVfVVBEQVRFRCkpXG4gICAgfVxuICB9LFxuXG4gIExpdmVJbWdQcmV2aWV3OiB7XG4gICAgbW91bnRlZCgpe1xuICAgICAgdGhpcy5yZWYgPSB0aGlzLmVsLmdldEF0dHJpYnV0ZShcImRhdGEtcGh4LWVudHJ5LXJlZlwiKVxuICAgICAgdGhpcy5pbnB1dEVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5lbC5nZXRBdHRyaWJ1dGUoUEhYX1VQTE9BRF9SRUYpKVxuICAgICAgTGl2ZVVwbG9hZGVyLmdldEVudHJ5RGF0YVVSTCh0aGlzLmlucHV0RWwsIHRoaXMucmVmLCB1cmwgPT4ge1xuICAgICAgICB0aGlzLnVybCA9IHVybFxuICAgICAgICB0aGlzLmVsLnNyYyA9IHVybFxuICAgICAgfSlcbiAgICB9LFxuICAgIGRlc3Ryb3llZCgpe1xuICAgICAgVVJMLnJldm9rZU9iamVjdFVSTCh0aGlzLnVybClcbiAgICB9XG4gIH0sXG4gIEZvY3VzV3JhcDoge1xuICAgIG1vdW50ZWQoKXtcbiAgICAgIHRoaXMuZm9jdXNTdGFydCA9IHRoaXMuZWwuZmlyc3RFbGVtZW50Q2hpbGRcbiAgICAgIHRoaXMuZm9jdXNFbmQgPSB0aGlzLmVsLmxhc3RFbGVtZW50Q2hpbGRcbiAgICAgIHRoaXMuZm9jdXNTdGFydC5hZGRFdmVudExpc3RlbmVyKFwiZm9jdXNcIiwgKCkgPT4gQVJJQS5mb2N1c0xhc3QodGhpcy5lbCkpXG4gICAgICB0aGlzLmZvY3VzRW5kLmFkZEV2ZW50TGlzdGVuZXIoXCJmb2N1c1wiLCAoKSA9PiBBUklBLmZvY3VzRmlyc3QodGhpcy5lbCkpXG4gICAgICB0aGlzLmVsLmFkZEV2ZW50TGlzdGVuZXIoXCJwaHg6c2hvdy1lbmRcIiwgKCkgPT4gdGhpcy5lbC5mb2N1cygpKVxuICAgICAgaWYod2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5lbCkuZGlzcGxheSAhPT0gXCJub25lXCIpe1xuICAgICAgICBBUklBLmZvY3VzRmlyc3QodGhpcy5lbClcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxubGV0IHNjcm9sbFRvcCA9ICgpID0+IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3AgfHwgZG9jdW1lbnQuYm9keS5zY3JvbGxUb3BcbmxldCB3aW5IZWlnaHQgPSAoKSA9PiB3aW5kb3cuaW5uZXJIZWlnaHQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodFxuXG5sZXQgaXNBdFZpZXdwb3J0VG9wID0gKGVsKSA9PiB7XG4gIGxldCByZWN0ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgcmV0dXJuIHJlY3QudG9wID49IDAgJiYgcmVjdC5sZWZ0ID49IDAgJiYgcmVjdC50b3AgPD0gd2luSGVpZ2h0KClcbn1cblxubGV0IGlzQXRWaWV3cG9ydEJvdHRvbSA9IChlbCkgPT4ge1xuICBsZXQgcmVjdCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gIHJldHVybiByZWN0LnJpZ2h0ID49IDAgJiYgcmVjdC5sZWZ0ID49IDAgJiYgcmVjdC5ib3R0b20gPD0gd2luSGVpZ2h0KClcbn1cblxubGV0IGlzV2l0aGluVmlld3BvcnQgPSAoZWwpID0+IHtcbiAgbGV0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICByZXR1cm4gcmVjdC50b3AgPj0gMCAmJiByZWN0LmxlZnQgPj0gMCAmJiByZWN0LnRvcCA8PSB3aW5IZWlnaHQoKVxufVxuXG5Ib29rcy5JbmZpbml0ZVNjcm9sbCA9IHtcbiAgbW91bnRlZCgpe1xuICAgIGxldCBzY3JvbGxCZWZvcmUgPSBzY3JvbGxUb3AoKVxuICAgIGxldCB0b3BPdmVycmFuID0gZmFsc2VcbiAgICBsZXQgdGhyb3R0bGVJbnRlcnZhbCA9IDUwMFxuICAgIGxldCBwZW5kaW5nT3AgPSBudWxsXG5cbiAgICBsZXQgb25Ub3BPdmVycnVuID0gdGhpcy50aHJvdHRsZSh0aHJvdHRsZUludGVydmFsLCAodG9wRXZlbnQsIGZpcnN0Q2hpbGQpID0+IHtcbiAgICAgIHBlbmRpbmdPcCA9ICgpID0+IHRydWVcbiAgICAgIHRoaXMubGl2ZVNvY2tldC5leGVjSlNIb29rUHVzaCh0aGlzLmVsLCB0b3BFdmVudCwge2lkOiBmaXJzdENoaWxkLmlkLCBfb3ZlcnJhbjogdHJ1ZX0sICgpID0+IHtcbiAgICAgICAgcGVuZGluZ09wID0gbnVsbFxuICAgICAgfSlcbiAgICB9KVxuXG4gICAgbGV0IG9uRmlyc3RDaGlsZEF0VG9wID0gdGhpcy50aHJvdHRsZSh0aHJvdHRsZUludGVydmFsLCAodG9wRXZlbnQsIGZpcnN0Q2hpbGQpID0+IHtcbiAgICAgIHBlbmRpbmdPcCA9ICgpID0+IGZpcnN0Q2hpbGQuc2Nyb2xsSW50b1ZpZXcoe2Jsb2NrOiBcInN0YXJ0XCJ9KVxuICAgICAgdGhpcy5saXZlU29ja2V0LmV4ZWNKU0hvb2tQdXNoKHRoaXMuZWwsIHRvcEV2ZW50LCB7aWQ6IGZpcnN0Q2hpbGQuaWR9LCAoKSA9PiB7XG4gICAgICAgIHBlbmRpbmdPcCA9IG51bGxcbiAgICAgICAgaWYoIWlzV2l0aGluVmlld3BvcnQoZmlyc3RDaGlsZCkpeyBmaXJzdENoaWxkLnNjcm9sbEludG9WaWV3KHtibG9jazogXCJzdGFydFwifSkgfVxuICAgICAgfSlcbiAgICB9KVxuXG4gICAgbGV0IG9uTGFzdENoaWxkQXRCb3R0b20gPSB0aGlzLnRocm90dGxlKHRocm90dGxlSW50ZXJ2YWwsIChib3R0b21FdmVudCwgbGFzdENoaWxkKSA9PiB7XG4gICAgICBwZW5kaW5nT3AgPSAoKSA9PiBsYXN0Q2hpbGQuc2Nyb2xsSW50b1ZpZXcoe2Jsb2NrOiBcImVuZFwifSlcbiAgICAgIHRoaXMubGl2ZVNvY2tldC5leGVjSlNIb29rUHVzaCh0aGlzLmVsLCBib3R0b21FdmVudCwge2lkOiBsYXN0Q2hpbGQuaWR9LCAoKSA9PiB7XG4gICAgICAgIHBlbmRpbmdPcCA9IG51bGxcbiAgICAgICAgaWYoIWlzV2l0aGluVmlld3BvcnQobGFzdENoaWxkKSl7IGxhc3RDaGlsZC5zY3JvbGxJbnRvVmlldyh7YmxvY2s6IFwiZW5kXCJ9KSB9XG4gICAgICB9KVxuICAgIH0pXG5cbiAgICB0aGlzLm9uU2Nyb2xsID0gKGUpID0+IHtcbiAgICAgIGxldCBzY3JvbGxOb3cgPSBzY3JvbGxUb3AoKVxuXG4gICAgICBpZihwZW5kaW5nT3Ape1xuICAgICAgICBzY3JvbGxCZWZvcmUgPSBzY3JvbGxOb3dcbiAgICAgICAgcmV0dXJuIHBlbmRpbmdPcCgpXG4gICAgICB9XG4gICAgICBsZXQgcmVjdCA9IHRoaXMuZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICAgIGxldCB0b3BFdmVudCA9IHRoaXMuZWwuZ2V0QXR0cmlidXRlKHRoaXMubGl2ZVNvY2tldC5iaW5kaW5nKFwidmlld3BvcnQtdG9wXCIpKVxuICAgICAgbGV0IGJvdHRvbUV2ZW50ID0gdGhpcy5lbC5nZXRBdHRyaWJ1dGUodGhpcy5saXZlU29ja2V0LmJpbmRpbmcoXCJ2aWV3cG9ydC1ib3R0b21cIikpXG4gICAgICBsZXQgbGFzdENoaWxkID0gdGhpcy5lbC5sYXN0RWxlbWVudENoaWxkXG4gICAgICBsZXQgZmlyc3RDaGlsZCA9IHRoaXMuZWwuZmlyc3RFbGVtZW50Q2hpbGRcbiAgICAgIGxldCBpc1Njcm9sbGluZ1VwID0gc2Nyb2xsTm93IDwgc2Nyb2xsQmVmb3JlXG4gICAgICBsZXQgaXNTY3JvbGxpbmdEb3duID0gc2Nyb2xsTm93ID4gc2Nyb2xsQmVmb3JlXG5cbiAgICAgIC8vIGVsIG92ZXJyYW4gd2hpbGUgc2Nyb2xsaW5nIHVwXG4gICAgICBpZihpc1Njcm9sbGluZ1VwICYmIHRvcEV2ZW50ICYmICF0b3BPdmVycmFuICYmIHJlY3QudG9wID49IDApe1xuICAgICAgICB0b3BPdmVycmFuID0gdHJ1ZVxuICAgICAgICBvblRvcE92ZXJydW4odG9wRXZlbnQsIGZpcnN0Q2hpbGQpXG4gICAgICB9IGVsc2UgaWYoaXNTY3JvbGxpbmdEb3duICYmIHRvcE92ZXJyYW4gJiYgcmVjdC50b3AgPD0gMCl7XG4gICAgICAgIHRvcE92ZXJyYW4gPSBmYWxzZVxuICAgICAgfVxuXG4gICAgICBpZih0b3BFdmVudCAmJiBpc1Njcm9sbGluZ1VwICYmIGlzQXRWaWV3cG9ydFRvcChmaXJzdENoaWxkKSl7XG4gICAgICAgIG9uRmlyc3RDaGlsZEF0VG9wKHRvcEV2ZW50LCBmaXJzdENoaWxkKVxuICAgICAgfSBlbHNlIGlmKGJvdHRvbUV2ZW50ICYmIGlzU2Nyb2xsaW5nRG93biAmJiBpc0F0Vmlld3BvcnRCb3R0b20obGFzdENoaWxkKSl7XG4gICAgICAgIG9uTGFzdENoaWxkQXRCb3R0b20oYm90dG9tRXZlbnQsIGxhc3RDaGlsZClcbiAgICAgIH1cbiAgICAgIHNjcm9sbEJlZm9yZSA9IHNjcm9sbE5vd1xuICAgIH1cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLCB0aGlzLm9uU2Nyb2xsKVxuICB9LFxuICBkZXN0cm95ZWQoKXsgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgdGhpcy5vblNjcm9sbCkgfSxcblxuICB0aHJvdHRsZShpbnRlcnZhbCwgY2FsbGJhY2spe1xuICAgIGxldCBsYXN0Q2FsbEF0ID0gMFxuICAgIGxldCB0aW1lclxuXG4gICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICBsZXQgbm93ID0gRGF0ZS5ub3coKVxuICAgICAgbGV0IHJlbWFpbmluZ1RpbWUgPSBpbnRlcnZhbCAtIChub3cgLSBsYXN0Q2FsbEF0KVxuXG4gICAgICBpZihyZW1haW5pbmdUaW1lIDw9IDAgfHwgcmVtYWluaW5nVGltZSA+IGludGVydmFsKXtcbiAgICAgICAgaWYodGltZXIpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpXG4gICAgICAgICAgdGltZXIgPSBudWxsXG4gICAgICAgIH1cbiAgICAgICAgbGFzdENhbGxBdCA9IG5vd1xuICAgICAgICBjYWxsYmFjayguLi5hcmdzKVxuICAgICAgfSBlbHNlIGlmKCF0aW1lcil7XG4gICAgICAgIHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgbGFzdENhbGxBdCA9IERhdGUubm93KClcbiAgICAgICAgICB0aW1lciA9IG51bGxcbiAgICAgICAgICBjYWxsYmFjayguLi5hcmdzKVxuICAgICAgICB9LCByZW1haW5pbmdUaW1lKVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuZXhwb3J0IGRlZmF1bHQgSG9va3NcbiIsICJpbXBvcnQge1xuICBtYXliZVxufSBmcm9tIFwiLi91dGlsc1wiXG5cbmltcG9ydCBET00gZnJvbSBcIi4vZG9tXCJcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRE9NUG9zdE1vcnBoUmVzdG9yZXIge1xuICBjb25zdHJ1Y3Rvcihjb250YWluZXJCZWZvcmUsIGNvbnRhaW5lckFmdGVyLCB1cGRhdGVUeXBlKXtcbiAgICBsZXQgaWRzQmVmb3JlID0gbmV3IFNldCgpXG4gICAgbGV0IGlkc0FmdGVyID0gbmV3IFNldChbLi4uY29udGFpbmVyQWZ0ZXIuY2hpbGRyZW5dLm1hcChjaGlsZCA9PiBjaGlsZC5pZCkpXG5cbiAgICBsZXQgZWxlbWVudHNUb01vZGlmeSA9IFtdXG5cbiAgICBBcnJheS5mcm9tKGNvbnRhaW5lckJlZm9yZS5jaGlsZHJlbikuZm9yRWFjaChjaGlsZCA9PiB7XG4gICAgICBpZihjaGlsZC5pZCl7IC8vIGFsbCBvZiBvdXIgY2hpbGRyZW4gc2hvdWxkIGJlIGVsZW1lbnRzIHdpdGggaWRzXG4gICAgICAgIGlkc0JlZm9yZS5hZGQoY2hpbGQuaWQpXG4gICAgICAgIGlmKGlkc0FmdGVyLmhhcyhjaGlsZC5pZCkpe1xuICAgICAgICAgIGxldCBwcmV2aW91c0VsZW1lbnRJZCA9IGNoaWxkLnByZXZpb3VzRWxlbWVudFNpYmxpbmcgJiYgY2hpbGQucHJldmlvdXNFbGVtZW50U2libGluZy5pZFxuICAgICAgICAgIGVsZW1lbnRzVG9Nb2RpZnkucHVzaCh7ZWxlbWVudElkOiBjaGlsZC5pZCwgcHJldmlvdXNFbGVtZW50SWQ6IHByZXZpb3VzRWxlbWVudElkfSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG5cbiAgICB0aGlzLmNvbnRhaW5lcklkID0gY29udGFpbmVyQWZ0ZXIuaWRcbiAgICB0aGlzLnVwZGF0ZVR5cGUgPSB1cGRhdGVUeXBlXG4gICAgdGhpcy5lbGVtZW50c1RvTW9kaWZ5ID0gZWxlbWVudHNUb01vZGlmeVxuICAgIHRoaXMuZWxlbWVudElkc1RvQWRkID0gWy4uLmlkc0FmdGVyXS5maWx0ZXIoaWQgPT4gIWlkc0JlZm9yZS5oYXMoaWQpKVxuICB9XG5cbiAgLy8gV2UgZG8gdGhlIGZvbGxvd2luZyB0byBvcHRpbWl6ZSBhcHBlbmQvcHJlcGVuZCBvcGVyYXRpb25zOlxuICAvLyAgIDEpIFRyYWNrIGlkcyBvZiBtb2RpZmllZCBlbGVtZW50cyAmIG9mIG5ldyBlbGVtZW50c1xuICAvLyAgIDIpIEFsbCB0aGUgbW9kaWZpZWQgZWxlbWVudHMgYXJlIHB1dCBiYWNrIGluIHRoZSBjb3JyZWN0IHBvc2l0aW9uIGluIHRoZSBET00gdHJlZVxuICAvLyAgICAgIGJ5IHN0b3JpbmcgdGhlIGlkIG9mIHRoZWlyIHByZXZpb3VzIHNpYmxpbmdcbiAgLy8gICAzKSBOZXcgZWxlbWVudHMgYXJlIGdvaW5nIHRvIGJlIHB1dCBpbiB0aGUgcmlnaHQgcGxhY2UgYnkgbW9ycGhkb20gZHVyaW5nIGFwcGVuZC5cbiAgLy8gICAgICBGb3IgcHJlcGVuZCwgd2UgbW92ZSB0aGVtIHRvIHRoZSBmaXJzdCBwb3NpdGlvbiBpbiB0aGUgY29udGFpbmVyXG4gIHBlcmZvcm0oKXtcbiAgICBsZXQgY29udGFpbmVyID0gRE9NLmJ5SWQodGhpcy5jb250YWluZXJJZClcbiAgICB0aGlzLmVsZW1lbnRzVG9Nb2RpZnkuZm9yRWFjaChlbGVtZW50VG9Nb2RpZnkgPT4ge1xuICAgICAgaWYoZWxlbWVudFRvTW9kaWZ5LnByZXZpb3VzRWxlbWVudElkKXtcbiAgICAgICAgbWF5YmUoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxlbWVudFRvTW9kaWZ5LnByZXZpb3VzRWxlbWVudElkKSwgcHJldmlvdXNFbGVtID0+IHtcbiAgICAgICAgICBtYXliZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbGVtZW50VG9Nb2RpZnkuZWxlbWVudElkKSwgZWxlbSA9PiB7XG4gICAgICAgICAgICBsZXQgaXNJblJpZ2h0UGxhY2UgPSBlbGVtLnByZXZpb3VzRWxlbWVudFNpYmxpbmcgJiYgZWxlbS5wcmV2aW91c0VsZW1lbnRTaWJsaW5nLmlkID09IHByZXZpb3VzRWxlbS5pZFxuICAgICAgICAgICAgaWYoIWlzSW5SaWdodFBsYWNlKXtcbiAgICAgICAgICAgICAgcHJldmlvdXNFbGVtLmluc2VydEFkamFjZW50RWxlbWVudChcImFmdGVyZW5kXCIsIGVsZW0pXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgfSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRoaXMgaXMgdGhlIGZpcnN0IGVsZW1lbnQgaW4gdGhlIGNvbnRhaW5lclxuICAgICAgICBtYXliZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbGVtZW50VG9Nb2RpZnkuZWxlbWVudElkKSwgZWxlbSA9PiB7XG4gICAgICAgICAgbGV0IGlzSW5SaWdodFBsYWNlID0gZWxlbS5wcmV2aW91c0VsZW1lbnRTaWJsaW5nID09IG51bGxcbiAgICAgICAgICBpZighaXNJblJpZ2h0UGxhY2Upe1xuICAgICAgICAgICAgY29udGFpbmVyLmluc2VydEFkamFjZW50RWxlbWVudChcImFmdGVyYmVnaW5cIiwgZWxlbSlcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfSlcblxuICAgIGlmKHRoaXMudXBkYXRlVHlwZSA9PSBcInByZXBlbmRcIil7XG4gICAgICB0aGlzLmVsZW1lbnRJZHNUb0FkZC5yZXZlcnNlKCkuZm9yRWFjaChlbGVtSWQgPT4ge1xuICAgICAgICBtYXliZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbGVtSWQpLCBlbGVtID0+IGNvbnRhaW5lci5pbnNlcnRBZGphY2VudEVsZW1lbnQoXCJhZnRlcmJlZ2luXCIsIGVsZW0pKVxuICAgICAgfSlcbiAgICB9XG4gIH1cbn1cbiIsICJ2YXIgRE9DVU1FTlRfRlJBR01FTlRfTk9ERSA9IDExO1xuXG5mdW5jdGlvbiBtb3JwaEF0dHJzKGZyb21Ob2RlLCB0b05vZGUpIHtcbiAgICB2YXIgdG9Ob2RlQXR0cnMgPSB0b05vZGUuYXR0cmlidXRlcztcbiAgICB2YXIgYXR0cjtcbiAgICB2YXIgYXR0ck5hbWU7XG4gICAgdmFyIGF0dHJOYW1lc3BhY2VVUkk7XG4gICAgdmFyIGF0dHJWYWx1ZTtcbiAgICB2YXIgZnJvbVZhbHVlO1xuXG4gICAgLy8gZG9jdW1lbnQtZnJhZ21lbnRzIGRvbnQgaGF2ZSBhdHRyaWJ1dGVzIHNvIGxldHMgbm90IGRvIGFueXRoaW5nXG4gICAgaWYgKHRvTm9kZS5ub2RlVHlwZSA9PT0gRE9DVU1FTlRfRlJBR01FTlRfTk9ERSB8fCBmcm9tTm9kZS5ub2RlVHlwZSA9PT0gRE9DVU1FTlRfRlJBR01FTlRfTk9ERSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHVwZGF0ZSBhdHRyaWJ1dGVzIG9uIG9yaWdpbmFsIERPTSBlbGVtZW50XG4gICAgZm9yICh2YXIgaSA9IHRvTm9kZUF0dHJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGF0dHIgPSB0b05vZGVBdHRyc1tpXTtcbiAgICAgICAgYXR0ck5hbWUgPSBhdHRyLm5hbWU7XG4gICAgICAgIGF0dHJOYW1lc3BhY2VVUkkgPSBhdHRyLm5hbWVzcGFjZVVSSTtcbiAgICAgICAgYXR0clZhbHVlID0gYXR0ci52YWx1ZTtcblxuICAgICAgICBpZiAoYXR0ck5hbWVzcGFjZVVSSSkge1xuICAgICAgICAgICAgYXR0ck5hbWUgPSBhdHRyLmxvY2FsTmFtZSB8fCBhdHRyTmFtZTtcbiAgICAgICAgICAgIGZyb21WYWx1ZSA9IGZyb21Ob2RlLmdldEF0dHJpYnV0ZU5TKGF0dHJOYW1lc3BhY2VVUkksIGF0dHJOYW1lKTtcblxuICAgICAgICAgICAgaWYgKGZyb21WYWx1ZSAhPT0gYXR0clZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGF0dHIucHJlZml4ID09PSAneG1sbnMnKXtcbiAgICAgICAgICAgICAgICAgICAgYXR0ck5hbWUgPSBhdHRyLm5hbWU7IC8vIEl0J3Mgbm90IGFsbG93ZWQgdG8gc2V0IGFuIGF0dHJpYnV0ZSB3aXRoIHRoZSBYTUxOUyBuYW1lc3BhY2Ugd2l0aG91dCBzcGVjaWZ5aW5nIHRoZSBgeG1sbnNgIHByZWZpeFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmcm9tTm9kZS5zZXRBdHRyaWJ1dGVOUyhhdHRyTmFtZXNwYWNlVVJJLCBhdHRyTmFtZSwgYXR0clZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZyb21WYWx1ZSA9IGZyb21Ob2RlLmdldEF0dHJpYnV0ZShhdHRyTmFtZSk7XG5cbiAgICAgICAgICAgIGlmIChmcm9tVmFsdWUgIT09IGF0dHJWYWx1ZSkge1xuICAgICAgICAgICAgICAgIGZyb21Ob2RlLnNldEF0dHJpYnV0ZShhdHRyTmFtZSwgYXR0clZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJlbW92ZSBhbnkgZXh0cmEgYXR0cmlidXRlcyBmb3VuZCBvbiB0aGUgb3JpZ2luYWwgRE9NIGVsZW1lbnQgdGhhdFxuICAgIC8vIHdlcmVuJ3QgZm91bmQgb24gdGhlIHRhcmdldCBlbGVtZW50LlxuICAgIHZhciBmcm9tTm9kZUF0dHJzID0gZnJvbU5vZGUuYXR0cmlidXRlcztcblxuICAgIGZvciAodmFyIGQgPSBmcm9tTm9kZUF0dHJzLmxlbmd0aCAtIDE7IGQgPj0gMDsgZC0tKSB7XG4gICAgICAgIGF0dHIgPSBmcm9tTm9kZUF0dHJzW2RdO1xuICAgICAgICBhdHRyTmFtZSA9IGF0dHIubmFtZTtcbiAgICAgICAgYXR0ck5hbWVzcGFjZVVSSSA9IGF0dHIubmFtZXNwYWNlVVJJO1xuXG4gICAgICAgIGlmIChhdHRyTmFtZXNwYWNlVVJJKSB7XG4gICAgICAgICAgICBhdHRyTmFtZSA9IGF0dHIubG9jYWxOYW1lIHx8IGF0dHJOYW1lO1xuXG4gICAgICAgICAgICBpZiAoIXRvTm9kZS5oYXNBdHRyaWJ1dGVOUyhhdHRyTmFtZXNwYWNlVVJJLCBhdHRyTmFtZSkpIHtcbiAgICAgICAgICAgICAgICBmcm9tTm9kZS5yZW1vdmVBdHRyaWJ1dGVOUyhhdHRyTmFtZXNwYWNlVVJJLCBhdHRyTmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoIXRvTm9kZS5oYXNBdHRyaWJ1dGUoYXR0ck5hbWUpKSB7XG4gICAgICAgICAgICAgICAgZnJvbU5vZGUucmVtb3ZlQXR0cmlidXRlKGF0dHJOYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxudmFyIHJhbmdlOyAvLyBDcmVhdGUgYSByYW5nZSBvYmplY3QgZm9yIGVmZmljZW50bHkgcmVuZGVyaW5nIHN0cmluZ3MgdG8gZWxlbWVudHMuXG52YXIgTlNfWEhUTUwgPSAnaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCc7XG5cbnZhciBkb2MgPSB0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogZG9jdW1lbnQ7XG52YXIgSEFTX1RFTVBMQVRFX1NVUFBPUlQgPSAhIWRvYyAmJiAnY29udGVudCcgaW4gZG9jLmNyZWF0ZUVsZW1lbnQoJ3RlbXBsYXRlJyk7XG52YXIgSEFTX1JBTkdFX1NVUFBPUlQgPSAhIWRvYyAmJiBkb2MuY3JlYXRlUmFuZ2UgJiYgJ2NyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCcgaW4gZG9jLmNyZWF0ZVJhbmdlKCk7XG5cbmZ1bmN0aW9uIGNyZWF0ZUZyYWdtZW50RnJvbVRlbXBsYXRlKHN0cikge1xuICAgIHZhciB0ZW1wbGF0ZSA9IGRvYy5jcmVhdGVFbGVtZW50KCd0ZW1wbGF0ZScpO1xuICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IHN0cjtcbiAgICByZXR1cm4gdGVtcGxhdGUuY29udGVudC5jaGlsZE5vZGVzWzBdO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVGcmFnbWVudEZyb21SYW5nZShzdHIpIHtcbiAgICBpZiAoIXJhbmdlKSB7XG4gICAgICAgIHJhbmdlID0gZG9jLmNyZWF0ZVJhbmdlKCk7XG4gICAgICAgIHJhbmdlLnNlbGVjdE5vZGUoZG9jLmJvZHkpO1xuICAgIH1cblxuICAgIHZhciBmcmFnbWVudCA9IHJhbmdlLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudChzdHIpO1xuICAgIHJldHVybiBmcmFnbWVudC5jaGlsZE5vZGVzWzBdO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVGcmFnbWVudEZyb21XcmFwKHN0cikge1xuICAgIHZhciBmcmFnbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50KCdib2R5Jyk7XG4gICAgZnJhZ21lbnQuaW5uZXJIVE1MID0gc3RyO1xuICAgIHJldHVybiBmcmFnbWVudC5jaGlsZE5vZGVzWzBdO1xufVxuXG4vKipcbiAqIFRoaXMgaXMgYWJvdXQgdGhlIHNhbWVcbiAqIHZhciBodG1sID0gbmV3IERPTVBhcnNlcigpLnBhcnNlRnJvbVN0cmluZyhzdHIsICd0ZXh0L2h0bWwnKTtcbiAqIHJldHVybiBodG1sLmJvZHkuZmlyc3RDaGlsZDtcbiAqXG4gKiBAbWV0aG9kIHRvRWxlbWVudFxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICovXG5mdW5jdGlvbiB0b0VsZW1lbnQoc3RyKSB7XG4gICAgc3RyID0gc3RyLnRyaW0oKTtcbiAgICBpZiAoSEFTX1RFTVBMQVRFX1NVUFBPUlQpIHtcbiAgICAgIC8vIGF2b2lkIHJlc3RyaWN0aW9ucyBvbiBjb250ZW50IGZvciB0aGluZ3MgbGlrZSBgPHRyPjx0aD5IaTwvdGg+PC90cj5gIHdoaWNoXG4gICAgICAvLyBjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQgZG9lc24ndCBzdXBwb3J0XG4gICAgICAvLyA8dGVtcGxhdGU+IHN1cHBvcnQgbm90IGF2YWlsYWJsZSBpbiBJRVxuICAgICAgcmV0dXJuIGNyZWF0ZUZyYWdtZW50RnJvbVRlbXBsYXRlKHN0cik7XG4gICAgfSBlbHNlIGlmIChIQVNfUkFOR0VfU1VQUE9SVCkge1xuICAgICAgcmV0dXJuIGNyZWF0ZUZyYWdtZW50RnJvbVJhbmdlKHN0cik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNyZWF0ZUZyYWdtZW50RnJvbVdyYXAoc3RyKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdHdvIG5vZGUncyBuYW1lcyBhcmUgdGhlIHNhbWUuXG4gKlxuICogTk9URTogV2UgZG9uJ3QgYm90aGVyIGNoZWNraW5nIGBuYW1lc3BhY2VVUklgIGJlY2F1c2UgeW91IHdpbGwgbmV2ZXIgZmluZCB0d28gSFRNTCBlbGVtZW50cyB3aXRoIHRoZSBzYW1lXG4gKiAgICAgICBub2RlTmFtZSBhbmQgZGlmZmVyZW50IG5hbWVzcGFjZSBVUklzLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gYVxuICogQHBhcmFtIHtFbGVtZW50fSBiIFRoZSB0YXJnZXQgZWxlbWVudFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gY29tcGFyZU5vZGVOYW1lcyhmcm9tRWwsIHRvRWwpIHtcbiAgICB2YXIgZnJvbU5vZGVOYW1lID0gZnJvbUVsLm5vZGVOYW1lO1xuICAgIHZhciB0b05vZGVOYW1lID0gdG9FbC5ub2RlTmFtZTtcbiAgICB2YXIgZnJvbUNvZGVTdGFydCwgdG9Db2RlU3RhcnQ7XG5cbiAgICBpZiAoZnJvbU5vZGVOYW1lID09PSB0b05vZGVOYW1lKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGZyb21Db2RlU3RhcnQgPSBmcm9tTm9kZU5hbWUuY2hhckNvZGVBdCgwKTtcbiAgICB0b0NvZGVTdGFydCA9IHRvTm9kZU5hbWUuY2hhckNvZGVBdCgwKTtcblxuICAgIC8vIElmIHRoZSB0YXJnZXQgZWxlbWVudCBpcyBhIHZpcnR1YWwgRE9NIG5vZGUgb3IgU1ZHIG5vZGUgdGhlbiB3ZSBtYXlcbiAgICAvLyBuZWVkIHRvIG5vcm1hbGl6ZSB0aGUgdGFnIG5hbWUgYmVmb3JlIGNvbXBhcmluZy4gTm9ybWFsIEhUTUwgZWxlbWVudHMgdGhhdCBhcmVcbiAgICAvLyBpbiB0aGUgXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCJcbiAgICAvLyBhcmUgY29udmVydGVkIHRvIHVwcGVyIGNhc2VcbiAgICBpZiAoZnJvbUNvZGVTdGFydCA8PSA5MCAmJiB0b0NvZGVTdGFydCA+PSA5NykgeyAvLyBmcm9tIGlzIHVwcGVyIGFuZCB0byBpcyBsb3dlclxuICAgICAgICByZXR1cm4gZnJvbU5vZGVOYW1lID09PSB0b05vZGVOYW1lLnRvVXBwZXJDYXNlKCk7XG4gICAgfSBlbHNlIGlmICh0b0NvZGVTdGFydCA8PSA5MCAmJiBmcm9tQ29kZVN0YXJ0ID49IDk3KSB7IC8vIHRvIGlzIHVwcGVyIGFuZCBmcm9tIGlzIGxvd2VyXG4gICAgICAgIHJldHVybiB0b05vZGVOYW1lID09PSBmcm9tTm9kZU5hbWUudG9VcHBlckNhc2UoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuXG4vKipcbiAqIENyZWF0ZSBhbiBlbGVtZW50LCBvcHRpb25hbGx5IHdpdGggYSBrbm93biBuYW1lc3BhY2UgVVJJLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIHRoZSBlbGVtZW50IG5hbWUsIGUuZy4gJ2Rpdicgb3IgJ3N2ZydcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbmFtZXNwYWNlVVJJXSB0aGUgZWxlbWVudCdzIG5hbWVzcGFjZSBVUkksIGkuZS4gdGhlIHZhbHVlIG9mXG4gKiBpdHMgYHhtbG5zYCBhdHRyaWJ1dGUgb3IgaXRzIGluZmVycmVkIG5hbWVzcGFjZS5cbiAqXG4gKiBAcmV0dXJuIHtFbGVtZW50fVxuICovXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50TlMobmFtZSwgbmFtZXNwYWNlVVJJKSB7XG4gICAgcmV0dXJuICFuYW1lc3BhY2VVUkkgfHwgbmFtZXNwYWNlVVJJID09PSBOU19YSFRNTCA/XG4gICAgICAgIGRvYy5jcmVhdGVFbGVtZW50KG5hbWUpIDpcbiAgICAgICAgZG9jLmNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2VVUkksIG5hbWUpO1xufVxuXG4vKipcbiAqIENvcGllcyB0aGUgY2hpbGRyZW4gb2Ygb25lIERPTSBlbGVtZW50IHRvIGFub3RoZXIgRE9NIGVsZW1lbnRcbiAqL1xuZnVuY3Rpb24gbW92ZUNoaWxkcmVuKGZyb21FbCwgdG9FbCkge1xuICAgIHZhciBjdXJDaGlsZCA9IGZyb21FbC5maXJzdENoaWxkO1xuICAgIHdoaWxlIChjdXJDaGlsZCkge1xuICAgICAgICB2YXIgbmV4dENoaWxkID0gY3VyQ2hpbGQubmV4dFNpYmxpbmc7XG4gICAgICAgIHRvRWwuYXBwZW5kQ2hpbGQoY3VyQ2hpbGQpO1xuICAgICAgICBjdXJDaGlsZCA9IG5leHRDaGlsZDtcbiAgICB9XG4gICAgcmV0dXJuIHRvRWw7XG59XG5cbmZ1bmN0aW9uIHN5bmNCb29sZWFuQXR0clByb3AoZnJvbUVsLCB0b0VsLCBuYW1lKSB7XG4gICAgaWYgKGZyb21FbFtuYW1lXSAhPT0gdG9FbFtuYW1lXSkge1xuICAgICAgICBmcm9tRWxbbmFtZV0gPSB0b0VsW25hbWVdO1xuICAgICAgICBpZiAoZnJvbUVsW25hbWVdKSB7XG4gICAgICAgICAgICBmcm9tRWwuc2V0QXR0cmlidXRlKG5hbWUsICcnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZyb21FbC5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbnZhciBzcGVjaWFsRWxIYW5kbGVycyA9IHtcbiAgICBPUFRJT046IGZ1bmN0aW9uKGZyb21FbCwgdG9FbCkge1xuICAgICAgICB2YXIgcGFyZW50Tm9kZSA9IGZyb21FbC5wYXJlbnROb2RlO1xuICAgICAgICBpZiAocGFyZW50Tm9kZSkge1xuICAgICAgICAgICAgdmFyIHBhcmVudE5hbWUgPSBwYXJlbnROb2RlLm5vZGVOYW1lLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgICAgICBpZiAocGFyZW50TmFtZSA9PT0gJ09QVEdST1VQJykge1xuICAgICAgICAgICAgICAgIHBhcmVudE5vZGUgPSBwYXJlbnROb2RlLnBhcmVudE5vZGU7XG4gICAgICAgICAgICAgICAgcGFyZW50TmFtZSA9IHBhcmVudE5vZGUgJiYgcGFyZW50Tm9kZS5ub2RlTmFtZS50b1VwcGVyQ2FzZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBhcmVudE5hbWUgPT09ICdTRUxFQ1QnICYmICFwYXJlbnROb2RlLmhhc0F0dHJpYnV0ZSgnbXVsdGlwbGUnKSkge1xuICAgICAgICAgICAgICAgIGlmIChmcm9tRWwuaGFzQXR0cmlidXRlKCdzZWxlY3RlZCcpICYmICF0b0VsLnNlbGVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdvcmthcm91bmQgZm9yIE1TIEVkZ2UgYnVnIHdoZXJlIHRoZSAnc2VsZWN0ZWQnIGF0dHJpYnV0ZSBjYW4gb25seSBiZVxuICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmVkIGlmIHNldCB0byBhIG5vbi1lbXB0eSB2YWx1ZTpcbiAgICAgICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubWljcm9zb2Z0LmNvbS9lbi11cy9taWNyb3NvZnQtZWRnZS9wbGF0Zm9ybS9pc3N1ZXMvMTIwODc2NzkvXG4gICAgICAgICAgICAgICAgICAgIGZyb21FbC5zZXRBdHRyaWJ1dGUoJ3NlbGVjdGVkJywgJ3NlbGVjdGVkJyk7XG4gICAgICAgICAgICAgICAgICAgIGZyb21FbC5yZW1vdmVBdHRyaWJ1dGUoJ3NlbGVjdGVkJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIFdlIGhhdmUgdG8gcmVzZXQgc2VsZWN0IGVsZW1lbnQncyBzZWxlY3RlZEluZGV4IHRvIC0xLCBvdGhlcndpc2Ugc2V0dGluZ1xuICAgICAgICAgICAgICAgIC8vIGZyb21FbC5zZWxlY3RlZCB1c2luZyB0aGUgc3luY0Jvb2xlYW5BdHRyUHJvcCBiZWxvdyBoYXMgbm8gZWZmZWN0LlxuICAgICAgICAgICAgICAgIC8vIFRoZSBjb3JyZWN0IHNlbGVjdGVkSW5kZXggd2lsbCBiZSBzZXQgaW4gdGhlIFNFTEVDVCBzcGVjaWFsIGhhbmRsZXIgYmVsb3cuXG4gICAgICAgICAgICAgICAgcGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4ID0gLTE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3luY0Jvb2xlYW5BdHRyUHJvcChmcm9tRWwsIHRvRWwsICdzZWxlY3RlZCcpO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIFwidmFsdWVcIiBhdHRyaWJ1dGUgaXMgc3BlY2lhbCBmb3IgdGhlIDxpbnB1dD4gZWxlbWVudCBzaW5jZSBpdCBzZXRzXG4gICAgICogdGhlIGluaXRpYWwgdmFsdWUuIENoYW5naW5nIHRoZSBcInZhbHVlXCIgYXR0cmlidXRlIHdpdGhvdXQgY2hhbmdpbmcgdGhlXG4gICAgICogXCJ2YWx1ZVwiIHByb3BlcnR5IHdpbGwgaGF2ZSBubyBlZmZlY3Qgc2luY2UgaXQgaXMgb25seSB1c2VkIHRvIHRoZSBzZXQgdGhlXG4gICAgICogaW5pdGlhbCB2YWx1ZS4gIFNpbWlsYXIgZm9yIHRoZSBcImNoZWNrZWRcIiBhdHRyaWJ1dGUsIGFuZCBcImRpc2FibGVkXCIuXG4gICAgICovXG4gICAgSU5QVVQ6IGZ1bmN0aW9uKGZyb21FbCwgdG9FbCkge1xuICAgICAgICBzeW5jQm9vbGVhbkF0dHJQcm9wKGZyb21FbCwgdG9FbCwgJ2NoZWNrZWQnKTtcbiAgICAgICAgc3luY0Jvb2xlYW5BdHRyUHJvcChmcm9tRWwsIHRvRWwsICdkaXNhYmxlZCcpO1xuXG4gICAgICAgIGlmIChmcm9tRWwudmFsdWUgIT09IHRvRWwudmFsdWUpIHtcbiAgICAgICAgICAgIGZyb21FbC52YWx1ZSA9IHRvRWwudmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRvRWwuaGFzQXR0cmlidXRlKCd2YWx1ZScpKSB7XG4gICAgICAgICAgICBmcm9tRWwucmVtb3ZlQXR0cmlidXRlKCd2YWx1ZScpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIFRFWFRBUkVBOiBmdW5jdGlvbihmcm9tRWwsIHRvRWwpIHtcbiAgICAgICAgdmFyIG5ld1ZhbHVlID0gdG9FbC52YWx1ZTtcbiAgICAgICAgaWYgKGZyb21FbC52YWx1ZSAhPT0gbmV3VmFsdWUpIHtcbiAgICAgICAgICAgIGZyb21FbC52YWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGZpcnN0Q2hpbGQgPSBmcm9tRWwuZmlyc3RDaGlsZDtcbiAgICAgICAgaWYgKGZpcnN0Q2hpbGQpIHtcbiAgICAgICAgICAgIC8vIE5lZWRlZCBmb3IgSUUuIEFwcGFyZW50bHkgSUUgc2V0cyB0aGUgcGxhY2Vob2xkZXIgYXMgdGhlXG4gICAgICAgICAgICAvLyBub2RlIHZhbHVlIGFuZCB2aXNlIHZlcnNhLiBUaGlzIGlnbm9yZXMgYW4gZW1wdHkgdXBkYXRlLlxuICAgICAgICAgICAgdmFyIG9sZFZhbHVlID0gZmlyc3RDaGlsZC5ub2RlVmFsdWU7XG5cbiAgICAgICAgICAgIGlmIChvbGRWYWx1ZSA9PSBuZXdWYWx1ZSB8fCAoIW5ld1ZhbHVlICYmIG9sZFZhbHVlID09IGZyb21FbC5wbGFjZWhvbGRlcikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZpcnN0Q2hpbGQubm9kZVZhbHVlID0gbmV3VmFsdWU7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIFNFTEVDVDogZnVuY3Rpb24oZnJvbUVsLCB0b0VsKSB7XG4gICAgICAgIGlmICghdG9FbC5oYXNBdHRyaWJ1dGUoJ211bHRpcGxlJykpIHtcbiAgICAgICAgICAgIHZhciBzZWxlY3RlZEluZGV4ID0gLTE7XG4gICAgICAgICAgICB2YXIgaSA9IDA7XG4gICAgICAgICAgICAvLyBXZSBoYXZlIHRvIGxvb3AgdGhyb3VnaCBjaGlsZHJlbiBvZiBmcm9tRWwsIG5vdCB0b0VsIHNpbmNlIG5vZGVzIGNhbiBiZSBtb3ZlZFxuICAgICAgICAgICAgLy8gZnJvbSB0b0VsIHRvIGZyb21FbCBkaXJlY3RseSB3aGVuIG1vcnBoaW5nLlxuICAgICAgICAgICAgLy8gQXQgdGhlIHRpbWUgdGhpcyBzcGVjaWFsIGhhbmRsZXIgaXMgaW52b2tlZCwgYWxsIGNoaWxkcmVuIGhhdmUgYWxyZWFkeSBiZWVuIG1vcnBoZWRcbiAgICAgICAgICAgIC8vIGFuZCBhcHBlbmRlZCB0byAvIHJlbW92ZWQgZnJvbSBmcm9tRWwsIHNvIHVzaW5nIGZyb21FbCBoZXJlIGlzIHNhZmUgYW5kIGNvcnJlY3QuXG4gICAgICAgICAgICB2YXIgY3VyQ2hpbGQgPSBmcm9tRWwuZmlyc3RDaGlsZDtcbiAgICAgICAgICAgIHZhciBvcHRncm91cDtcbiAgICAgICAgICAgIHZhciBub2RlTmFtZTtcbiAgICAgICAgICAgIHdoaWxlKGN1ckNoaWxkKSB7XG4gICAgICAgICAgICAgICAgbm9kZU5hbWUgPSBjdXJDaGlsZC5ub2RlTmFtZSAmJiBjdXJDaGlsZC5ub2RlTmFtZS50b1VwcGVyQ2FzZSgpO1xuICAgICAgICAgICAgICAgIGlmIChub2RlTmFtZSA9PT0gJ09QVEdST1VQJykge1xuICAgICAgICAgICAgICAgICAgICBvcHRncm91cCA9IGN1ckNoaWxkO1xuICAgICAgICAgICAgICAgICAgICBjdXJDaGlsZCA9IG9wdGdyb3VwLmZpcnN0Q2hpbGQ7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVOYW1lID09PSAnT1BUSU9OJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1ckNoaWxkLmhhc0F0dHJpYnV0ZSgnc2VsZWN0ZWQnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkSW5kZXggPSBpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaSsrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGN1ckNoaWxkID0gY3VyQ2hpbGQubmV4dFNpYmxpbmc7XG4gICAgICAgICAgICAgICAgICAgIGlmICghY3VyQ2hpbGQgJiYgb3B0Z3JvdXApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1ckNoaWxkID0gb3B0Z3JvdXAubmV4dFNpYmxpbmc7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRncm91cCA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZyb21FbC5zZWxlY3RlZEluZGV4ID0gc2VsZWN0ZWRJbmRleDtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cbnZhciBFTEVNRU5UX05PREUgPSAxO1xudmFyIERPQ1VNRU5UX0ZSQUdNRU5UX05PREUkMSA9IDExO1xudmFyIFRFWFRfTk9ERSA9IDM7XG52YXIgQ09NTUVOVF9OT0RFID0gODtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbmZ1bmN0aW9uIGRlZmF1bHRHZXROb2RlS2V5KG5vZGUpIHtcbiAgaWYgKG5vZGUpIHtcbiAgICByZXR1cm4gKG5vZGUuZ2V0QXR0cmlidXRlICYmIG5vZGUuZ2V0QXR0cmlidXRlKCdpZCcpKSB8fCBub2RlLmlkO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1vcnBoZG9tRmFjdG9yeShtb3JwaEF0dHJzKSB7XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIG1vcnBoZG9tKGZyb21Ob2RlLCB0b05vZGUsIG9wdGlvbnMpIHtcbiAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHRvTm9kZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmIChmcm9tTm9kZS5ub2RlTmFtZSA9PT0gJyNkb2N1bWVudCcgfHwgZnJvbU5vZGUubm9kZU5hbWUgPT09ICdIVE1MJyB8fCBmcm9tTm9kZS5ub2RlTmFtZSA9PT0gJ0JPRFknKSB7XG4gICAgICAgIHZhciB0b05vZGVIdG1sID0gdG9Ob2RlO1xuICAgICAgICB0b05vZGUgPSBkb2MuY3JlYXRlRWxlbWVudCgnaHRtbCcpO1xuICAgICAgICB0b05vZGUuaW5uZXJIVE1MID0gdG9Ob2RlSHRtbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRvTm9kZSA9IHRvRWxlbWVudCh0b05vZGUpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodG9Ob2RlLm5vZGVUeXBlID09PSBET0NVTUVOVF9GUkFHTUVOVF9OT0RFJDEpIHtcbiAgICAgIHRvTm9kZSA9IHRvTm9kZS5maXJzdEVsZW1lbnRDaGlsZDtcbiAgICB9XG5cbiAgICB2YXIgZ2V0Tm9kZUtleSA9IG9wdGlvbnMuZ2V0Tm9kZUtleSB8fCBkZWZhdWx0R2V0Tm9kZUtleTtcbiAgICB2YXIgb25CZWZvcmVOb2RlQWRkZWQgPSBvcHRpb25zLm9uQmVmb3JlTm9kZUFkZGVkIHx8IG5vb3A7XG4gICAgdmFyIG9uTm9kZUFkZGVkID0gb3B0aW9ucy5vbk5vZGVBZGRlZCB8fCBub29wO1xuICAgIHZhciBvbkJlZm9yZUVsVXBkYXRlZCA9IG9wdGlvbnMub25CZWZvcmVFbFVwZGF0ZWQgfHwgbm9vcDtcbiAgICB2YXIgb25FbFVwZGF0ZWQgPSBvcHRpb25zLm9uRWxVcGRhdGVkIHx8IG5vb3A7XG4gICAgdmFyIG9uQmVmb3JlTm9kZURpc2NhcmRlZCA9IG9wdGlvbnMub25CZWZvcmVOb2RlRGlzY2FyZGVkIHx8IG5vb3A7XG4gICAgdmFyIG9uTm9kZURpc2NhcmRlZCA9IG9wdGlvbnMub25Ob2RlRGlzY2FyZGVkIHx8IG5vb3A7XG4gICAgdmFyIG9uQmVmb3JlRWxDaGlsZHJlblVwZGF0ZWQgPSBvcHRpb25zLm9uQmVmb3JlRWxDaGlsZHJlblVwZGF0ZWQgfHwgbm9vcDtcbiAgICB2YXIgc2tpcEZyb21DaGlsZHJlbiA9IG9wdGlvbnMuc2tpcEZyb21DaGlsZHJlbiB8fCBub29wO1xuICAgIHZhciBhZGRDaGlsZCA9IG9wdGlvbnMuYWRkQ2hpbGQgfHwgZnVuY3Rpb24ocGFyZW50LCBjaGlsZCl7IHJldHVybiBwYXJlbnQuYXBwZW5kQ2hpbGQoY2hpbGQpOyB9O1xuICAgIHZhciBjaGlsZHJlbk9ubHkgPSBvcHRpb25zLmNoaWxkcmVuT25seSA9PT0gdHJ1ZTtcblxuICAgIC8vIFRoaXMgb2JqZWN0IGlzIHVzZWQgYXMgYSBsb29rdXAgdG8gcXVpY2tseSBmaW5kIGFsbCBrZXllZCBlbGVtZW50cyBpbiB0aGUgb3JpZ2luYWwgRE9NIHRyZWUuXG4gICAgdmFyIGZyb21Ob2Rlc0xvb2t1cCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgdmFyIGtleWVkUmVtb3ZhbExpc3QgPSBbXTtcblxuICAgIGZ1bmN0aW9uIGFkZEtleWVkUmVtb3ZhbChrZXkpIHtcbiAgICAgIGtleWVkUmVtb3ZhbExpc3QucHVzaChrZXkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHdhbGtEaXNjYXJkZWRDaGlsZE5vZGVzKG5vZGUsIHNraXBLZXllZE5vZGVzKSB7XG4gICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgIHZhciBjdXJDaGlsZCA9IG5vZGUuZmlyc3RDaGlsZDtcbiAgICAgICAgd2hpbGUgKGN1ckNoaWxkKSB7XG5cbiAgICAgICAgICB2YXIga2V5ID0gdW5kZWZpbmVkO1xuXG4gICAgICAgICAgaWYgKHNraXBLZXllZE5vZGVzICYmIChrZXkgPSBnZXROb2RlS2V5KGN1ckNoaWxkKSkpIHtcbiAgICAgICAgICAgIC8vIElmIHdlIGFyZSBza2lwcGluZyBrZXllZCBub2RlcyB0aGVuIHdlIGFkZCB0aGUga2V5XG4gICAgICAgICAgICAvLyB0byBhIGxpc3Qgc28gdGhhdCBpdCBjYW4gYmUgaGFuZGxlZCBhdCB0aGUgdmVyeSBlbmQuXG4gICAgICAgICAgICBhZGRLZXllZFJlbW92YWwoa2V5KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gT25seSByZXBvcnQgdGhlIG5vZGUgYXMgZGlzY2FyZGVkIGlmIGl0IGlzIG5vdCBrZXllZC4gV2UgZG8gdGhpcyBiZWNhdXNlXG4gICAgICAgICAgICAvLyBhdCB0aGUgZW5kIHdlIGxvb3AgdGhyb3VnaCBhbGwga2V5ZWQgZWxlbWVudHMgdGhhdCB3ZXJlIHVubWF0Y2hlZFxuICAgICAgICAgICAgLy8gYW5kIHRoZW4gZGlzY2FyZCB0aGVtIGluIG9uZSBmaW5hbCBwYXNzLlxuICAgICAgICAgICAgb25Ob2RlRGlzY2FyZGVkKGN1ckNoaWxkKTtcbiAgICAgICAgICAgIGlmIChjdXJDaGlsZC5maXJzdENoaWxkKSB7XG4gICAgICAgICAgICAgIHdhbGtEaXNjYXJkZWRDaGlsZE5vZGVzKGN1ckNoaWxkLCBza2lwS2V5ZWROb2Rlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY3VyQ2hpbGQgPSBjdXJDaGlsZC5uZXh0U2libGluZztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICogUmVtb3ZlcyBhIERPTSBub2RlIG91dCBvZiB0aGUgb3JpZ2luYWwgRE9NXG4gICAgKlxuICAgICogQHBhcmFtICB7Tm9kZX0gbm9kZSBUaGUgbm9kZSB0byByZW1vdmVcbiAgICAqIEBwYXJhbSAge05vZGV9IHBhcmVudE5vZGUgVGhlIG5vZGVzIHBhcmVudFxuICAgICogQHBhcmFtICB7Qm9vbGVhbn0gc2tpcEtleWVkTm9kZXMgSWYgdHJ1ZSB0aGVuIGVsZW1lbnRzIHdpdGgga2V5cyB3aWxsIGJlIHNraXBwZWQgYW5kIG5vdCBkaXNjYXJkZWQuXG4gICAgKiBAcmV0dXJuIHt1bmRlZmluZWR9XG4gICAgKi9cbiAgICBmdW5jdGlvbiByZW1vdmVOb2RlKG5vZGUsIHBhcmVudE5vZGUsIHNraXBLZXllZE5vZGVzKSB7XG4gICAgICBpZiAob25CZWZvcmVOb2RlRGlzY2FyZGVkKG5vZGUpID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJlbnROb2RlKSB7XG4gICAgICAgIHBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobm9kZSk7XG4gICAgICB9XG5cbiAgICAgIG9uTm9kZURpc2NhcmRlZChub2RlKTtcbiAgICAgIHdhbGtEaXNjYXJkZWRDaGlsZE5vZGVzKG5vZGUsIHNraXBLZXllZE5vZGVzKTtcbiAgICB9XG5cbiAgICAvLyAvLyBUcmVlV2Fsa2VyIGltcGxlbWVudGF0aW9uIGlzIG5vIGZhc3RlciwgYnV0IGtlZXBpbmcgdGhpcyBhcm91bmQgaW4gY2FzZSB0aGlzIGNoYW5nZXMgaW4gdGhlIGZ1dHVyZVxuICAgIC8vIGZ1bmN0aW9uIGluZGV4VHJlZShyb290KSB7XG4gICAgLy8gICAgIHZhciB0cmVlV2Fsa2VyID0gZG9jdW1lbnQuY3JlYXRlVHJlZVdhbGtlcihcbiAgICAvLyAgICAgICAgIHJvb3QsXG4gICAgLy8gICAgICAgICBOb2RlRmlsdGVyLlNIT1dfRUxFTUVOVCk7XG4gICAgLy9cbiAgICAvLyAgICAgdmFyIGVsO1xuICAgIC8vICAgICB3aGlsZSgoZWwgPSB0cmVlV2Fsa2VyLm5leHROb2RlKCkpKSB7XG4gICAgLy8gICAgICAgICB2YXIga2V5ID0gZ2V0Tm9kZUtleShlbCk7XG4gICAgLy8gICAgICAgICBpZiAoa2V5KSB7XG4gICAgLy8gICAgICAgICAgICAgZnJvbU5vZGVzTG9va3VwW2tleV0gPSBlbDtcbiAgICAvLyAgICAgICAgIH1cbiAgICAvLyAgICAgfVxuICAgIC8vIH1cblxuICAgIC8vIC8vIE5vZGVJdGVyYXRvciBpbXBsZW1lbnRhdGlvbiBpcyBubyBmYXN0ZXIsIGJ1dCBrZWVwaW5nIHRoaXMgYXJvdW5kIGluIGNhc2UgdGhpcyBjaGFuZ2VzIGluIHRoZSBmdXR1cmVcbiAgICAvL1xuICAgIC8vIGZ1bmN0aW9uIGluZGV4VHJlZShub2RlKSB7XG4gICAgLy8gICAgIHZhciBub2RlSXRlcmF0b3IgPSBkb2N1bWVudC5jcmVhdGVOb2RlSXRlcmF0b3Iobm9kZSwgTm9kZUZpbHRlci5TSE9XX0VMRU1FTlQpO1xuICAgIC8vICAgICB2YXIgZWw7XG4gICAgLy8gICAgIHdoaWxlKChlbCA9IG5vZGVJdGVyYXRvci5uZXh0Tm9kZSgpKSkge1xuICAgIC8vICAgICAgICAgdmFyIGtleSA9IGdldE5vZGVLZXkoZWwpO1xuICAgIC8vICAgICAgICAgaWYgKGtleSkge1xuICAgIC8vICAgICAgICAgICAgIGZyb21Ob2Rlc0xvb2t1cFtrZXldID0gZWw7XG4gICAgLy8gICAgICAgICB9XG4gICAgLy8gICAgIH1cbiAgICAvLyB9XG5cbiAgICBmdW5jdGlvbiBpbmRleFRyZWUobm9kZSkge1xuICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSB8fCBub2RlLm5vZGVUeXBlID09PSBET0NVTUVOVF9GUkFHTUVOVF9OT0RFJDEpIHtcbiAgICAgICAgdmFyIGN1ckNoaWxkID0gbm9kZS5maXJzdENoaWxkO1xuICAgICAgICB3aGlsZSAoY3VyQ2hpbGQpIHtcbiAgICAgICAgICB2YXIga2V5ID0gZ2V0Tm9kZUtleShjdXJDaGlsZCk7XG4gICAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgICAgZnJvbU5vZGVzTG9va3VwW2tleV0gPSBjdXJDaGlsZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBXYWxrIHJlY3Vyc2l2ZWx5XG4gICAgICAgICAgaW5kZXhUcmVlKGN1ckNoaWxkKTtcblxuICAgICAgICAgIGN1ckNoaWxkID0gY3VyQ2hpbGQubmV4dFNpYmxpbmc7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpbmRleFRyZWUoZnJvbU5vZGUpO1xuXG4gICAgZnVuY3Rpb24gaGFuZGxlTm9kZUFkZGVkKGVsKSB7XG4gICAgICBvbk5vZGVBZGRlZChlbCk7XG5cbiAgICAgIHZhciBjdXJDaGlsZCA9IGVsLmZpcnN0Q2hpbGQ7XG4gICAgICB3aGlsZSAoY3VyQ2hpbGQpIHtcbiAgICAgICAgdmFyIG5leHRTaWJsaW5nID0gY3VyQ2hpbGQubmV4dFNpYmxpbmc7XG5cbiAgICAgICAgdmFyIGtleSA9IGdldE5vZGVLZXkoY3VyQ2hpbGQpO1xuICAgICAgICBpZiAoa2V5KSB7XG4gICAgICAgICAgdmFyIHVubWF0Y2hlZEZyb21FbCA9IGZyb21Ob2Rlc0xvb2t1cFtrZXldO1xuICAgICAgICAgIC8vIGlmIHdlIGZpbmQgYSBkdXBsaWNhdGUgI2lkIG5vZGUgaW4gY2FjaGUsIHJlcGxhY2UgYGVsYCB3aXRoIGNhY2hlIHZhbHVlXG4gICAgICAgICAgLy8gYW5kIG1vcnBoIGl0IHRvIHRoZSBjaGlsZCBub2RlLlxuICAgICAgICAgIGlmICh1bm1hdGNoZWRGcm9tRWwgJiYgY29tcGFyZU5vZGVOYW1lcyhjdXJDaGlsZCwgdW5tYXRjaGVkRnJvbUVsKSkge1xuICAgICAgICAgICAgY3VyQ2hpbGQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQodW5tYXRjaGVkRnJvbUVsLCBjdXJDaGlsZCk7XG4gICAgICAgICAgICBtb3JwaEVsKHVubWF0Y2hlZEZyb21FbCwgY3VyQ2hpbGQpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBoYW5kbGVOb2RlQWRkZWQoY3VyQ2hpbGQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyByZWN1cnNpdmVseSBjYWxsIGZvciBjdXJDaGlsZCBhbmQgaXQncyBjaGlsZHJlbiB0byBzZWUgaWYgd2UgZmluZCBzb21ldGhpbmcgaW5cbiAgICAgICAgICAvLyBmcm9tTm9kZXNMb29rdXBcbiAgICAgICAgICBoYW5kbGVOb2RlQWRkZWQoY3VyQ2hpbGQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY3VyQ2hpbGQgPSBuZXh0U2libGluZztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjbGVhbnVwRnJvbUVsKGZyb21FbCwgY3VyRnJvbU5vZGVDaGlsZCwgY3VyRnJvbU5vZGVLZXkpIHtcbiAgICAgIC8vIFdlIGhhdmUgcHJvY2Vzc2VkIGFsbCBvZiB0aGUgXCJ0byBub2Rlc1wiLiBJZiBjdXJGcm9tTm9kZUNoaWxkIGlzXG4gICAgICAvLyBub24tbnVsbCB0aGVuIHdlIHN0aWxsIGhhdmUgc29tZSBmcm9tIG5vZGVzIGxlZnQgb3ZlciB0aGF0IG5lZWRcbiAgICAgIC8vIHRvIGJlIHJlbW92ZWRcbiAgICAgIHdoaWxlIChjdXJGcm9tTm9kZUNoaWxkKSB7XG4gICAgICAgIHZhciBmcm9tTmV4dFNpYmxpbmcgPSBjdXJGcm9tTm9kZUNoaWxkLm5leHRTaWJsaW5nO1xuICAgICAgICBpZiAoKGN1ckZyb21Ob2RlS2V5ID0gZ2V0Tm9kZUtleShjdXJGcm9tTm9kZUNoaWxkKSkpIHtcbiAgICAgICAgICAvLyBTaW5jZSB0aGUgbm9kZSBpcyBrZXllZCBpdCBtaWdodCBiZSBtYXRjaGVkIHVwIGxhdGVyIHNvIHdlIGRlZmVyXG4gICAgICAgICAgLy8gdGhlIGFjdHVhbCByZW1vdmFsIHRvIGxhdGVyXG4gICAgICAgICAgYWRkS2V5ZWRSZW1vdmFsKGN1ckZyb21Ob2RlS2V5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBOT1RFOiB3ZSBza2lwIG5lc3RlZCBrZXllZCBub2RlcyBmcm9tIGJlaW5nIHJlbW92ZWQgc2luY2UgdGhlcmUgaXNcbiAgICAgICAgICAvLyAgICAgICBzdGlsbCBhIGNoYW5jZSB0aGV5IHdpbGwgYmUgbWF0Y2hlZCB1cCBsYXRlclxuICAgICAgICAgIHJlbW92ZU5vZGUoY3VyRnJvbU5vZGVDaGlsZCwgZnJvbUVsLCB0cnVlIC8qIHNraXAga2V5ZWQgbm9kZXMgKi8pO1xuICAgICAgICB9XG4gICAgICAgIGN1ckZyb21Ob2RlQ2hpbGQgPSBmcm9tTmV4dFNpYmxpbmc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbW9ycGhFbChmcm9tRWwsIHRvRWwsIGNoaWxkcmVuT25seSkge1xuICAgICAgdmFyIHRvRWxLZXkgPSBnZXROb2RlS2V5KHRvRWwpO1xuXG4gICAgICBpZiAodG9FbEtleSkge1xuICAgICAgICAvLyBJZiBhbiBlbGVtZW50IHdpdGggYW4gSUQgaXMgYmVpbmcgbW9ycGhlZCB0aGVuIGl0IHdpbGwgYmUgaW4gdGhlIGZpbmFsXG4gICAgICAgIC8vIERPTSBzbyBjbGVhciBpdCBvdXQgb2YgdGhlIHNhdmVkIGVsZW1lbnRzIGNvbGxlY3Rpb25cbiAgICAgICAgZGVsZXRlIGZyb21Ob2Rlc0xvb2t1cFt0b0VsS2V5XTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFjaGlsZHJlbk9ubHkpIHtcbiAgICAgICAgLy8gb3B0aW9uYWxcbiAgICAgICAgaWYgKG9uQmVmb3JlRWxVcGRhdGVkKGZyb21FbCwgdG9FbCkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdXBkYXRlIGF0dHJpYnV0ZXMgb24gb3JpZ2luYWwgRE9NIGVsZW1lbnQgZmlyc3RcbiAgICAgICAgbW9ycGhBdHRycyhmcm9tRWwsIHRvRWwpO1xuICAgICAgICAvLyBvcHRpb25hbFxuICAgICAgICBvbkVsVXBkYXRlZChmcm9tRWwpO1xuXG4gICAgICAgIGlmIChvbkJlZm9yZUVsQ2hpbGRyZW5VcGRhdGVkKGZyb21FbCwgdG9FbCkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChmcm9tRWwubm9kZU5hbWUgIT09ICdURVhUQVJFQScpIHtcbiAgICAgICAgbW9ycGhDaGlsZHJlbihmcm9tRWwsIHRvRWwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3BlY2lhbEVsSGFuZGxlcnMuVEVYVEFSRUEoZnJvbUVsLCB0b0VsKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb3JwaENoaWxkcmVuKGZyb21FbCwgdG9FbCkge1xuICAgICAgdmFyIHNraXBGcm9tID0gc2tpcEZyb21DaGlsZHJlbihmcm9tRWwpO1xuICAgICAgdmFyIGN1clRvTm9kZUNoaWxkID0gdG9FbC5maXJzdENoaWxkO1xuICAgICAgdmFyIGN1ckZyb21Ob2RlQ2hpbGQgPSBmcm9tRWwuZmlyc3RDaGlsZDtcbiAgICAgIHZhciBjdXJUb05vZGVLZXk7XG4gICAgICB2YXIgY3VyRnJvbU5vZGVLZXk7XG5cbiAgICAgIHZhciBmcm9tTmV4dFNpYmxpbmc7XG4gICAgICB2YXIgdG9OZXh0U2libGluZztcbiAgICAgIHZhciBtYXRjaGluZ0Zyb21FbDtcblxuICAgICAgLy8gd2FsayB0aGUgY2hpbGRyZW5cbiAgICAgIG91dGVyOiB3aGlsZSAoY3VyVG9Ob2RlQ2hpbGQpIHtcbiAgICAgICAgdG9OZXh0U2libGluZyA9IGN1clRvTm9kZUNoaWxkLm5leHRTaWJsaW5nO1xuICAgICAgICBjdXJUb05vZGVLZXkgPSBnZXROb2RlS2V5KGN1clRvTm9kZUNoaWxkKTtcblxuICAgICAgICAvLyB3YWxrIHRoZSBmcm9tTm9kZSBjaGlsZHJlbiBhbGwgdGhlIHdheSB0aHJvdWdoXG4gICAgICAgIHdoaWxlICghc2tpcEZyb20gJiYgY3VyRnJvbU5vZGVDaGlsZCkge1xuICAgICAgICAgIGZyb21OZXh0U2libGluZyA9IGN1ckZyb21Ob2RlQ2hpbGQubmV4dFNpYmxpbmc7XG5cbiAgICAgICAgICBpZiAoY3VyVG9Ob2RlQ2hpbGQuaXNTYW1lTm9kZSAmJiBjdXJUb05vZGVDaGlsZC5pc1NhbWVOb2RlKGN1ckZyb21Ob2RlQ2hpbGQpKSB7XG4gICAgICAgICAgICBjdXJUb05vZGVDaGlsZCA9IHRvTmV4dFNpYmxpbmc7XG4gICAgICAgICAgICBjdXJGcm9tTm9kZUNoaWxkID0gZnJvbU5leHRTaWJsaW5nO1xuICAgICAgICAgICAgY29udGludWUgb3V0ZXI7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY3VyRnJvbU5vZGVLZXkgPSBnZXROb2RlS2V5KGN1ckZyb21Ob2RlQ2hpbGQpO1xuXG4gICAgICAgICAgdmFyIGN1ckZyb21Ob2RlVHlwZSA9IGN1ckZyb21Ob2RlQ2hpbGQubm9kZVR5cGU7XG5cbiAgICAgICAgICAvLyB0aGlzIG1lYW5zIGlmIHRoZSBjdXJGcm9tTm9kZUNoaWxkIGRvZXNudCBoYXZlIGEgbWF0Y2ggd2l0aCB0aGUgY3VyVG9Ob2RlQ2hpbGRcbiAgICAgICAgICB2YXIgaXNDb21wYXRpYmxlID0gdW5kZWZpbmVkO1xuXG4gICAgICAgICAgaWYgKGN1ckZyb21Ob2RlVHlwZSA9PT0gY3VyVG9Ob2RlQ2hpbGQubm9kZVR5cGUpIHtcbiAgICAgICAgICAgIGlmIChjdXJGcm9tTm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSkge1xuICAgICAgICAgICAgICAvLyBCb3RoIG5vZGVzIGJlaW5nIGNvbXBhcmVkIGFyZSBFbGVtZW50IG5vZGVzXG5cbiAgICAgICAgICAgICAgaWYgKGN1clRvTm9kZUtleSkge1xuICAgICAgICAgICAgICAgIC8vIFRoZSB0YXJnZXQgbm9kZSBoYXMgYSBrZXkgc28gd2Ugd2FudCB0byBtYXRjaCBpdCB1cCB3aXRoIHRoZSBjb3JyZWN0IGVsZW1lbnRcbiAgICAgICAgICAgICAgICAvLyBpbiB0aGUgb3JpZ2luYWwgRE9NIHRyZWVcbiAgICAgICAgICAgICAgICBpZiAoY3VyVG9Ob2RlS2V5ICE9PSBjdXJGcm9tTm9kZUtleSkge1xuICAgICAgICAgICAgICAgICAgLy8gVGhlIGN1cnJlbnQgZWxlbWVudCBpbiB0aGUgb3JpZ2luYWwgRE9NIHRyZWUgZG9lcyBub3QgaGF2ZSBhIG1hdGNoaW5nIGtleSBzb1xuICAgICAgICAgICAgICAgICAgLy8gbGV0J3MgY2hlY2sgb3VyIGxvb2t1cCB0byBzZWUgaWYgdGhlcmUgaXMgYSBtYXRjaGluZyBlbGVtZW50IGluIHRoZSBvcmlnaW5hbFxuICAgICAgICAgICAgICAgICAgLy8gRE9NIHRyZWVcbiAgICAgICAgICAgICAgICAgIGlmICgobWF0Y2hpbmdGcm9tRWwgPSBmcm9tTm9kZXNMb29rdXBbY3VyVG9Ob2RlS2V5XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZyb21OZXh0U2libGluZyA9PT0gbWF0Y2hpbmdGcm9tRWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBTcGVjaWFsIGNhc2UgZm9yIHNpbmdsZSBlbGVtZW50IHJlbW92YWxzLiBUbyBhdm9pZCByZW1vdmluZyB0aGUgb3JpZ2luYWxcbiAgICAgICAgICAgICAgICAgICAgICAvLyBET00gbm9kZSBvdXQgb2YgdGhlIHRyZWUgKHNpbmNlIHRoYXQgY2FuIGJyZWFrIENTUyB0cmFuc2l0aW9ucywgZXRjLiksXG4gICAgICAgICAgICAgICAgICAgICAgLy8gd2Ugd2lsbCBpbnN0ZWFkIGRpc2NhcmQgdGhlIGN1cnJlbnQgbm9kZSBhbmQgd2FpdCB1bnRpbCB0aGUgbmV4dFxuICAgICAgICAgICAgICAgICAgICAgIC8vIGl0ZXJhdGlvbiB0byBwcm9wZXJseSBtYXRjaCB1cCB0aGUga2V5ZWQgdGFyZ2V0IGVsZW1lbnQgd2l0aCBpdHMgbWF0Y2hpbmdcbiAgICAgICAgICAgICAgICAgICAgICAvLyBlbGVtZW50IGluIHRoZSBvcmlnaW5hbCB0cmVlXG4gICAgICAgICAgICAgICAgICAgICAgaXNDb21wYXRpYmxlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gV2UgZm91bmQgYSBtYXRjaGluZyBrZXllZCBlbGVtZW50IHNvbWV3aGVyZSBpbiB0aGUgb3JpZ2luYWwgRE9NIHRyZWUuXG4gICAgICAgICAgICAgICAgICAgICAgLy8gTGV0J3MgbW92ZSB0aGUgb3JpZ2luYWwgRE9NIG5vZGUgaW50byB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQgbW9ycGhcbiAgICAgICAgICAgICAgICAgICAgICAvLyBpdC5cblxuICAgICAgICAgICAgICAgICAgICAgIC8vIE5PVEU6IFdlIHVzZSBpbnNlcnRCZWZvcmUgaW5zdGVhZCBvZiByZXBsYWNlQ2hpbGQgYmVjYXVzZSB3ZSB3YW50IHRvIGdvIHRocm91Z2hcbiAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgYHJlbW92ZU5vZGUoKWAgZnVuY3Rpb24gZm9yIHRoZSBub2RlIHRoYXQgaXMgYmVpbmcgZGlzY2FyZGVkIHNvIHRoYXRcbiAgICAgICAgICAgICAgICAgICAgICAvLyBhbGwgbGlmZWN5Y2xlIGhvb2tzIGFyZSBjb3JyZWN0bHkgaW52b2tlZFxuICAgICAgICAgICAgICAgICAgICAgIGZyb21FbC5pbnNlcnRCZWZvcmUobWF0Y2hpbmdGcm9tRWwsIGN1ckZyb21Ob2RlQ2hpbGQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgLy8gZnJvbU5leHRTaWJsaW5nID0gY3VyRnJvbU5vZGVDaGlsZC5uZXh0U2libGluZztcblxuICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJGcm9tTm9kZUtleSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2luY2UgdGhlIG5vZGUgaXMga2V5ZWQgaXQgbWlnaHQgYmUgbWF0Y2hlZCB1cCBsYXRlciBzbyB3ZSBkZWZlclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGFjdHVhbCByZW1vdmFsIHRvIGxhdGVyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRLZXllZFJlbW92YWwoY3VyRnJvbU5vZGVLZXkpO1xuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBOT1RFOiB3ZSBza2lwIG5lc3RlZCBrZXllZCBub2RlcyBmcm9tIGJlaW5nIHJlbW92ZWQgc2luY2UgdGhlcmUgaXNcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgIHN0aWxsIGEgY2hhbmNlIHRoZXkgd2lsbCBiZSBtYXRjaGVkIHVwIGxhdGVyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVOb2RlKGN1ckZyb21Ob2RlQ2hpbGQsIGZyb21FbCwgdHJ1ZSAvKiBza2lwIGtleWVkIG5vZGVzICovKTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICBjdXJGcm9tTm9kZUNoaWxkID0gbWF0Y2hpbmdGcm9tRWw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZSBub2RlcyBhcmUgbm90IGNvbXBhdGlibGUgc2luY2UgdGhlIFwidG9cIiBub2RlIGhhcyBhIGtleSBhbmQgdGhlcmVcbiAgICAgICAgICAgICAgICAgICAgLy8gaXMgbm8gbWF0Y2hpbmcga2V5ZWQgbm9kZSBpbiB0aGUgc291cmNlIHRyZWVcbiAgICAgICAgICAgICAgICAgICAgaXNDb21wYXRpYmxlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGN1ckZyb21Ob2RlS2V5KSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlIG9yaWdpbmFsIGhhcyBhIGtleVxuICAgICAgICAgICAgICAgIGlzQ29tcGF0aWJsZSA9IGZhbHNlO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaXNDb21wYXRpYmxlID0gaXNDb21wYXRpYmxlICE9PSBmYWxzZSAmJiBjb21wYXJlTm9kZU5hbWVzKGN1ckZyb21Ob2RlQ2hpbGQsIGN1clRvTm9kZUNoaWxkKTtcbiAgICAgICAgICAgICAgaWYgKGlzQ29tcGF0aWJsZSkge1xuICAgICAgICAgICAgICAgIC8vIFdlIGZvdW5kIGNvbXBhdGlibGUgRE9NIGVsZW1lbnRzIHNvIHRyYW5zZm9ybVxuICAgICAgICAgICAgICAgIC8vIHRoZSBjdXJyZW50IFwiZnJvbVwiIG5vZGUgdG8gbWF0Y2ggdGhlIGN1cnJlbnRcbiAgICAgICAgICAgICAgICAvLyB0YXJnZXQgRE9NIG5vZGUuXG4gICAgICAgICAgICAgICAgLy8gTU9SUEhcbiAgICAgICAgICAgICAgICBtb3JwaEVsKGN1ckZyb21Ob2RlQ2hpbGQsIGN1clRvTm9kZUNoaWxkKTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGN1ckZyb21Ob2RlVHlwZSA9PT0gVEVYVF9OT0RFIHx8IGN1ckZyb21Ob2RlVHlwZSA9PSBDT01NRU5UX05PREUpIHtcbiAgICAgICAgICAgICAgLy8gQm90aCBub2RlcyBiZWluZyBjb21wYXJlZCBhcmUgVGV4dCBvciBDb21tZW50IG5vZGVzXG4gICAgICAgICAgICAgIGlzQ29tcGF0aWJsZSA9IHRydWU7XG4gICAgICAgICAgICAgIC8vIFNpbXBseSB1cGRhdGUgbm9kZVZhbHVlIG9uIHRoZSBvcmlnaW5hbCBub2RlIHRvXG4gICAgICAgICAgICAgIC8vIGNoYW5nZSB0aGUgdGV4dCB2YWx1ZVxuICAgICAgICAgICAgICBpZiAoY3VyRnJvbU5vZGVDaGlsZC5ub2RlVmFsdWUgIT09IGN1clRvTm9kZUNoaWxkLm5vZGVWYWx1ZSkge1xuICAgICAgICAgICAgICAgIGN1ckZyb21Ob2RlQ2hpbGQubm9kZVZhbHVlID0gY3VyVG9Ob2RlQ2hpbGQubm9kZVZhbHVlO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaXNDb21wYXRpYmxlKSB7XG4gICAgICAgICAgICAvLyBBZHZhbmNlIGJvdGggdGhlIFwidG9cIiBjaGlsZCBhbmQgdGhlIFwiZnJvbVwiIGNoaWxkIHNpbmNlIHdlIGZvdW5kIGEgbWF0Y2hcbiAgICAgICAgICAgIC8vIE5vdGhpbmcgZWxzZSB0byBkbyBhcyB3ZSBhbHJlYWR5IHJlY3Vyc2l2ZWx5IGNhbGxlZCBtb3JwaENoaWxkcmVuIGFib3ZlXG4gICAgICAgICAgICBjdXJUb05vZGVDaGlsZCA9IHRvTmV4dFNpYmxpbmc7XG4gICAgICAgICAgICBjdXJGcm9tTm9kZUNoaWxkID0gZnJvbU5leHRTaWJsaW5nO1xuICAgICAgICAgICAgY29udGludWUgb3V0ZXI7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gTm8gY29tcGF0aWJsZSBtYXRjaCBzbyByZW1vdmUgdGhlIG9sZCBub2RlIGZyb20gdGhlIERPTSBhbmQgY29udGludWUgdHJ5aW5nIHRvIGZpbmQgYVxuICAgICAgICAgIC8vIG1hdGNoIGluIHRoZSBvcmlnaW5hbCBET00uIEhvd2V2ZXIsIHdlIG9ubHkgZG8gdGhpcyBpZiB0aGUgZnJvbSBub2RlIGlzIG5vdCBrZXllZFxuICAgICAgICAgIC8vIHNpbmNlIGl0IGlzIHBvc3NpYmxlIHRoYXQgYSBrZXllZCBub2RlIG1pZ2h0IG1hdGNoIHVwIHdpdGggYSBub2RlIHNvbWV3aGVyZSBlbHNlIGluIHRoZVxuICAgICAgICAgIC8vIHRhcmdldCB0cmVlIGFuZCB3ZSBkb24ndCB3YW50IHRvIGRpc2NhcmQgaXQganVzdCB5ZXQgc2luY2UgaXQgc3RpbGwgbWlnaHQgZmluZCBhXG4gICAgICAgICAgLy8gaG9tZSBpbiB0aGUgZmluYWwgRE9NIHRyZWUuIEFmdGVyIGV2ZXJ5dGhpbmcgaXMgZG9uZSB3ZSB3aWxsIHJlbW92ZSBhbnkga2V5ZWQgbm9kZXNcbiAgICAgICAgICAvLyB0aGF0IGRpZG4ndCBmaW5kIGEgaG9tZVxuICAgICAgICAgIGlmIChjdXJGcm9tTm9kZUtleSkge1xuICAgICAgICAgICAgLy8gU2luY2UgdGhlIG5vZGUgaXMga2V5ZWQgaXQgbWlnaHQgYmUgbWF0Y2hlZCB1cCBsYXRlciBzbyB3ZSBkZWZlclxuICAgICAgICAgICAgLy8gdGhlIGFjdHVhbCByZW1vdmFsIHRvIGxhdGVyXG4gICAgICAgICAgICBhZGRLZXllZFJlbW92YWwoY3VyRnJvbU5vZGVLZXkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBOT1RFOiB3ZSBza2lwIG5lc3RlZCBrZXllZCBub2RlcyBmcm9tIGJlaW5nIHJlbW92ZWQgc2luY2UgdGhlcmUgaXNcbiAgICAgICAgICAgIC8vICAgICAgIHN0aWxsIGEgY2hhbmNlIHRoZXkgd2lsbCBiZSBtYXRjaGVkIHVwIGxhdGVyXG4gICAgICAgICAgICByZW1vdmVOb2RlKGN1ckZyb21Ob2RlQ2hpbGQsIGZyb21FbCwgdHJ1ZSAvKiBza2lwIGtleWVkIG5vZGVzICovKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjdXJGcm9tTm9kZUNoaWxkID0gZnJvbU5leHRTaWJsaW5nO1xuICAgICAgICB9IC8vIEVORDogd2hpbGUoY3VyRnJvbU5vZGVDaGlsZCkge31cblxuICAgICAgICAvLyBJZiB3ZSBnb3QgdGhpcyBmYXIgdGhlbiB3ZSBkaWQgbm90IGZpbmQgYSBjYW5kaWRhdGUgbWF0Y2ggZm9yXG4gICAgICAgIC8vIG91ciBcInRvIG5vZGVcIiBhbmQgd2UgZXhoYXVzdGVkIGFsbCBvZiB0aGUgY2hpbGRyZW4gXCJmcm9tXCJcbiAgICAgICAgLy8gbm9kZXMuIFRoZXJlZm9yZSwgd2Ugd2lsbCBqdXN0IGFwcGVuZCB0aGUgY3VycmVudCBcInRvXCIgbm9kZVxuICAgICAgICAvLyB0byB0aGUgZW5kXG4gICAgICAgIGlmIChjdXJUb05vZGVLZXkgJiYgKG1hdGNoaW5nRnJvbUVsID0gZnJvbU5vZGVzTG9va3VwW2N1clRvTm9kZUtleV0pICYmIGNvbXBhcmVOb2RlTmFtZXMobWF0Y2hpbmdGcm9tRWwsIGN1clRvTm9kZUNoaWxkKSkge1xuICAgICAgICAgIC8vIE1PUlBIXG4gICAgICAgICAgaWYoIXNraXBGcm9tKXsgYWRkQ2hpbGQoZnJvbUVsLCBtYXRjaGluZ0Zyb21FbCk7IH1cbiAgICAgICAgICBtb3JwaEVsKG1hdGNoaW5nRnJvbUVsLCBjdXJUb05vZGVDaGlsZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIG9uQmVmb3JlTm9kZUFkZGVkUmVzdWx0ID0gb25CZWZvcmVOb2RlQWRkZWQoY3VyVG9Ob2RlQ2hpbGQpO1xuICAgICAgICAgIGlmIChvbkJlZm9yZU5vZGVBZGRlZFJlc3VsdCAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGlmIChvbkJlZm9yZU5vZGVBZGRlZFJlc3VsdCkge1xuICAgICAgICAgICAgICBjdXJUb05vZGVDaGlsZCA9IG9uQmVmb3JlTm9kZUFkZGVkUmVzdWx0O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoY3VyVG9Ob2RlQ2hpbGQuYWN0dWFsaXplKSB7XG4gICAgICAgICAgICAgIGN1clRvTm9kZUNoaWxkID0gY3VyVG9Ob2RlQ2hpbGQuYWN0dWFsaXplKGZyb21FbC5vd25lckRvY3VtZW50IHx8IGRvYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhZGRDaGlsZChmcm9tRWwsIGN1clRvTm9kZUNoaWxkKTtcbiAgICAgICAgICAgIGhhbmRsZU5vZGVBZGRlZChjdXJUb05vZGVDaGlsZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY3VyVG9Ob2RlQ2hpbGQgPSB0b05leHRTaWJsaW5nO1xuICAgICAgICBjdXJGcm9tTm9kZUNoaWxkID0gZnJvbU5leHRTaWJsaW5nO1xuICAgICAgfVxuXG4gICAgICBjbGVhbnVwRnJvbUVsKGZyb21FbCwgY3VyRnJvbU5vZGVDaGlsZCwgY3VyRnJvbU5vZGVLZXkpO1xuXG4gICAgICB2YXIgc3BlY2lhbEVsSGFuZGxlciA9IHNwZWNpYWxFbEhhbmRsZXJzW2Zyb21FbC5ub2RlTmFtZV07XG4gICAgICBpZiAoc3BlY2lhbEVsSGFuZGxlcikge1xuICAgICAgICBzcGVjaWFsRWxIYW5kbGVyKGZyb21FbCwgdG9FbCk7XG4gICAgICB9XG4gICAgfSAvLyBFTkQ6IG1vcnBoQ2hpbGRyZW4oLi4uKVxuXG4gICAgdmFyIG1vcnBoZWROb2RlID0gZnJvbU5vZGU7XG4gICAgdmFyIG1vcnBoZWROb2RlVHlwZSA9IG1vcnBoZWROb2RlLm5vZGVUeXBlO1xuICAgIHZhciB0b05vZGVUeXBlID0gdG9Ob2RlLm5vZGVUeXBlO1xuXG4gICAgaWYgKCFjaGlsZHJlbk9ubHkpIHtcbiAgICAgIC8vIEhhbmRsZSB0aGUgY2FzZSB3aGVyZSB3ZSBhcmUgZ2l2ZW4gdHdvIERPTSBub2RlcyB0aGF0IGFyZSBub3RcbiAgICAgIC8vIGNvbXBhdGlibGUgKGUuZy4gPGRpdj4gLS0+IDxzcGFuPiBvciA8ZGl2PiAtLT4gVEVYVClcbiAgICAgIGlmIChtb3JwaGVkTm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSkge1xuICAgICAgICBpZiAodG9Ob2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgICAgaWYgKCFjb21wYXJlTm9kZU5hbWVzKGZyb21Ob2RlLCB0b05vZGUpKSB7XG4gICAgICAgICAgICBvbk5vZGVEaXNjYXJkZWQoZnJvbU5vZGUpO1xuICAgICAgICAgICAgbW9ycGhlZE5vZGUgPSBtb3ZlQ2hpbGRyZW4oZnJvbU5vZGUsIGNyZWF0ZUVsZW1lbnROUyh0b05vZGUubm9kZU5hbWUsIHRvTm9kZS5uYW1lc3BhY2VVUkkpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gR29pbmcgZnJvbSBhbiBlbGVtZW50IG5vZGUgdG8gYSB0ZXh0IG5vZGVcbiAgICAgICAgICBtb3JwaGVkTm9kZSA9IHRvTm9kZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChtb3JwaGVkTm9kZVR5cGUgPT09IFRFWFRfTk9ERSB8fCBtb3JwaGVkTm9kZVR5cGUgPT09IENPTU1FTlRfTk9ERSkgeyAvLyBUZXh0IG9yIGNvbW1lbnQgbm9kZVxuICAgICAgICBpZiAodG9Ob2RlVHlwZSA9PT0gbW9ycGhlZE5vZGVUeXBlKSB7XG4gICAgICAgICAgaWYgKG1vcnBoZWROb2RlLm5vZGVWYWx1ZSAhPT0gdG9Ob2RlLm5vZGVWYWx1ZSkge1xuICAgICAgICAgICAgbW9ycGhlZE5vZGUubm9kZVZhbHVlID0gdG9Ob2RlLm5vZGVWYWx1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gbW9ycGhlZE5vZGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gVGV4dCBub2RlIHRvIHNvbWV0aGluZyBlbHNlXG4gICAgICAgICAgbW9ycGhlZE5vZGUgPSB0b05vZGU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobW9ycGhlZE5vZGUgPT09IHRvTm9kZSkge1xuICAgICAgLy8gVGhlIFwidG8gbm9kZVwiIHdhcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoZSBcImZyb20gbm9kZVwiIHNvIHdlIGhhZCB0b1xuICAgICAgLy8gdG9zcyBvdXQgdGhlIFwiZnJvbSBub2RlXCIgYW5kIHVzZSB0aGUgXCJ0byBub2RlXCJcbiAgICAgIG9uTm9kZURpc2NhcmRlZChmcm9tTm9kZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0b05vZGUuaXNTYW1lTm9kZSAmJiB0b05vZGUuaXNTYW1lTm9kZShtb3JwaGVkTm9kZSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBtb3JwaEVsKG1vcnBoZWROb2RlLCB0b05vZGUsIGNoaWxkcmVuT25seSk7XG5cbiAgICAgIC8vIFdlIG5vdyBuZWVkIHRvIGxvb3Agb3ZlciBhbnkga2V5ZWQgbm9kZXMgdGhhdCBtaWdodCBuZWVkIHRvIGJlXG4gICAgICAvLyByZW1vdmVkLiBXZSBvbmx5IGRvIHRoZSByZW1vdmFsIGlmIHdlIGtub3cgdGhhdCB0aGUga2V5ZWQgbm9kZVxuICAgICAgLy8gbmV2ZXIgZm91bmQgYSBtYXRjaC4gV2hlbiBhIGtleWVkIG5vZGUgaXMgbWF0Y2hlZCB1cCB3ZSByZW1vdmVcbiAgICAgIC8vIGl0IG91dCBvZiBmcm9tTm9kZXNMb29rdXAgYW5kIHdlIHVzZSBmcm9tTm9kZXNMb29rdXAgdG8gZGV0ZXJtaW5lXG4gICAgICAvLyBpZiBhIGtleWVkIG5vZGUgaGFzIGJlZW4gbWF0Y2hlZCB1cCBvciBub3RcbiAgICAgIGlmIChrZXllZFJlbW92YWxMaXN0KSB7XG4gICAgICAgIGZvciAodmFyIGk9MCwgbGVuPWtleWVkUmVtb3ZhbExpc3QubGVuZ3RoOyBpPGxlbjsgaSsrKSB7XG4gICAgICAgICAgdmFyIGVsVG9SZW1vdmUgPSBmcm9tTm9kZXNMb29rdXBba2V5ZWRSZW1vdmFsTGlzdFtpXV07XG4gICAgICAgICAgaWYgKGVsVG9SZW1vdmUpIHtcbiAgICAgICAgICAgIHJlbW92ZU5vZGUoZWxUb1JlbW92ZSwgZWxUb1JlbW92ZS5wYXJlbnROb2RlLCBmYWxzZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFjaGlsZHJlbk9ubHkgJiYgbW9ycGhlZE5vZGUgIT09IGZyb21Ob2RlICYmIGZyb21Ob2RlLnBhcmVudE5vZGUpIHtcbiAgICAgIGlmIChtb3JwaGVkTm9kZS5hY3R1YWxpemUpIHtcbiAgICAgICAgbW9ycGhlZE5vZGUgPSBtb3JwaGVkTm9kZS5hY3R1YWxpemUoZnJvbU5vZGUub3duZXJEb2N1bWVudCB8fCBkb2MpO1xuICAgICAgfVxuICAgICAgLy8gSWYgd2UgaGFkIHRvIHN3YXAgb3V0IHRoZSBmcm9tIG5vZGUgd2l0aCBhIG5ldyBub2RlIGJlY2F1c2UgdGhlIG9sZFxuICAgICAgLy8gbm9kZSB3YXMgbm90IGNvbXBhdGlibGUgd2l0aCB0aGUgdGFyZ2V0IG5vZGUgdGhlbiB3ZSBuZWVkIHRvXG4gICAgICAvLyByZXBsYWNlIHRoZSBvbGQgRE9NIG5vZGUgaW4gdGhlIG9yaWdpbmFsIERPTSB0cmVlLiBUaGlzIGlzIG9ubHlcbiAgICAgIC8vIHBvc3NpYmxlIGlmIHRoZSBvcmlnaW5hbCBET00gbm9kZSB3YXMgcGFydCBvZiBhIERPTSB0cmVlIHdoaWNoXG4gICAgICAvLyB3ZSBrbm93IGlzIHRoZSBjYXNlIGlmIGl0IGhhcyBhIHBhcmVudCBub2RlLlxuICAgICAgZnJvbU5vZGUucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQobW9ycGhlZE5vZGUsIGZyb21Ob2RlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbW9ycGhlZE5vZGU7XG4gIH07XG59XG5cbnZhciBtb3JwaGRvbSA9IG1vcnBoZG9tRmFjdG9yeShtb3JwaEF0dHJzKTtcblxuZXhwb3J0IGRlZmF1bHQgbW9ycGhkb207XG4iLCAiaW1wb3J0IHtcbiAgUEhYX0NPTVBPTkVOVCxcbiAgUEhYX0RJU0FCTEVfV0lUSCxcbiAgUEhYX0ZFRURCQUNLX0ZPUixcbiAgUEhYX1BSVU5FLFxuICBQSFhfUk9PVF9JRCxcbiAgUEhYX1NFU1NJT04sXG4gIFBIWF9TS0lQLFxuICBQSFhfU1RBVElDLFxuICBQSFhfVFJJR0dFUl9BQ1RJT04sXG4gIFBIWF9VUERBVEUsXG4gIFBIWF9TVFJFQU0sXG4gIFBIWF9TVFJFQU1fUkVGLFxuICBQSFhfVklFV1BPUlRfVE9QLFxuICBQSFhfVklFV1BPUlRfQk9UVE9NLFxufSBmcm9tIFwiLi9jb25zdGFudHNcIlxuXG5pbXBvcnQge1xuICBkZXRlY3REdXBsaWNhdGVJZHMsXG4gIGlzQ2lkXG59IGZyb20gXCIuL3V0aWxzXCJcblxuaW1wb3J0IERPTSBmcm9tIFwiLi9kb21cIlxuaW1wb3J0IERPTVBvc3RNb3JwaFJlc3RvcmVyIGZyb20gXCIuL2RvbV9wb3N0X21vcnBoX3Jlc3RvcmVyXCJcbmltcG9ydCBtb3JwaGRvbSBmcm9tIFwibW9ycGhkb21cIlxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBET01QYXRjaCB7XG4gIHN0YXRpYyBwYXRjaEVsKGZyb21FbCwgdG9FbCwgYWN0aXZlRWxlbWVudCl7XG4gICAgbW9ycGhkb20oZnJvbUVsLCB0b0VsLCB7XG4gICAgICBjaGlsZHJlbk9ubHk6IGZhbHNlLFxuICAgICAgb25CZWZvcmVFbFVwZGF0ZWQ6IChmcm9tRWwsIHRvRWwpID0+IHtcbiAgICAgICAgaWYoYWN0aXZlRWxlbWVudCAmJiBhY3RpdmVFbGVtZW50LmlzU2FtZU5vZGUoZnJvbUVsKSAmJiBET00uaXNGb3JtSW5wdXQoZnJvbUVsKSl7XG4gICAgICAgICAgRE9NLm1lcmdlRm9jdXNlZElucHV0KGZyb21FbCwgdG9FbClcbiAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICBjb25zdHJ1Y3Rvcih2aWV3LCBjb250YWluZXIsIGlkLCBodG1sLCBzdHJlYW1zLCB0YXJnZXRDSUQpe1xuICAgIHRoaXMudmlldyA9IHZpZXdcbiAgICB0aGlzLmxpdmVTb2NrZXQgPSB2aWV3LmxpdmVTb2NrZXRcbiAgICB0aGlzLmNvbnRhaW5lciA9IGNvbnRhaW5lclxuICAgIHRoaXMuaWQgPSBpZFxuICAgIHRoaXMucm9vdElEID0gdmlldy5yb290LmlkXG4gICAgdGhpcy5odG1sID0gaHRtbFxuICAgIHRoaXMuc3RyZWFtcyA9IHN0cmVhbXNcbiAgICB0aGlzLnN0cmVhbUluc2VydHMgPSB7fVxuICAgIHRoaXMudGFyZ2V0Q0lEID0gdGFyZ2V0Q0lEXG4gICAgdGhpcy5jaWRQYXRjaCA9IGlzQ2lkKHRoaXMudGFyZ2V0Q0lEKVxuICAgIHRoaXMucGVuZGluZ1JlbW92ZXMgPSBbXVxuICAgIHRoaXMucGh4UmVtb3ZlID0gdGhpcy5saXZlU29ja2V0LmJpbmRpbmcoXCJyZW1vdmVcIilcbiAgICB0aGlzLmNhbGxiYWNrcyA9IHtcbiAgICAgIGJlZm9yZWFkZGVkOiBbXSwgYmVmb3JldXBkYXRlZDogW10sIGJlZm9yZXBoeENoaWxkQWRkZWQ6IFtdLFxuICAgICAgYWZ0ZXJhZGRlZDogW10sIGFmdGVydXBkYXRlZDogW10sIGFmdGVyZGlzY2FyZGVkOiBbXSwgYWZ0ZXJwaHhDaGlsZEFkZGVkOiBbXSxcbiAgICAgIGFmdGVydHJhbnNpdGlvbnNEaXNjYXJkZWQ6IFtdXG4gICAgfVxuICB9XG5cbiAgYmVmb3JlKGtpbmQsIGNhbGxiYWNrKXsgdGhpcy5jYWxsYmFja3NbYGJlZm9yZSR7a2luZH1gXS5wdXNoKGNhbGxiYWNrKSB9XG4gIGFmdGVyKGtpbmQsIGNhbGxiYWNrKXsgdGhpcy5jYWxsYmFja3NbYGFmdGVyJHtraW5kfWBdLnB1c2goY2FsbGJhY2spIH1cblxuICB0cmFja0JlZm9yZShraW5kLCAuLi5hcmdzKXtcbiAgICB0aGlzLmNhbGxiYWNrc1tgYmVmb3JlJHtraW5kfWBdLmZvckVhY2goY2FsbGJhY2sgPT4gY2FsbGJhY2soLi4uYXJncykpXG4gIH1cblxuICB0cmFja0FmdGVyKGtpbmQsIC4uLmFyZ3Mpe1xuICAgIHRoaXMuY2FsbGJhY2tzW2BhZnRlciR7a2luZH1gXS5mb3JFYWNoKGNhbGxiYWNrID0+IGNhbGxiYWNrKC4uLmFyZ3MpKVxuICB9XG5cbiAgbWFya1BydW5hYmxlQ29udGVudEZvclJlbW92YWwoKXtcbiAgICBsZXQgcGh4VXBkYXRlID0gdGhpcy5saXZlU29ja2V0LmJpbmRpbmcoUEhYX1VQREFURSlcbiAgICBET00uYWxsKHRoaXMuY29udGFpbmVyLCBgWyR7cGh4VXBkYXRlfT0ke1BIWF9TVFJFQU19XWAsIGVsID0+IGVsLmlubmVySFRNTCA9IFwiXCIpXG4gICAgRE9NLmFsbCh0aGlzLmNvbnRhaW5lciwgYFske3BoeFVwZGF0ZX09YXBwZW5kXSA+ICosIFske3BoeFVwZGF0ZX09cHJlcGVuZF0gPiAqYCwgZWwgPT4ge1xuICAgICAgZWwuc2V0QXR0cmlidXRlKFBIWF9QUlVORSwgXCJcIilcbiAgICB9KVxuICB9XG5cbiAgcGVyZm9ybSgpe1xuICAgIGxldCB7dmlldywgbGl2ZVNvY2tldCwgY29udGFpbmVyLCBodG1sfSA9IHRoaXNcbiAgICBsZXQgdGFyZ2V0Q29udGFpbmVyID0gdGhpcy5pc0NJRFBhdGNoKCkgPyB0aGlzLnRhcmdldENJRENvbnRhaW5lcihodG1sKSA6IGNvbnRhaW5lclxuICAgIGlmKHRoaXMuaXNDSURQYXRjaCgpICYmICF0YXJnZXRDb250YWluZXIpeyByZXR1cm4gfVxuXG4gICAgbGV0IGZvY3VzZWQgPSBsaXZlU29ja2V0LmdldEFjdGl2ZUVsZW1lbnQoKVxuICAgIGxldCB7c2VsZWN0aW9uU3RhcnQsIHNlbGVjdGlvbkVuZH0gPSBmb2N1c2VkICYmIERPTS5oYXNTZWxlY3Rpb25SYW5nZShmb2N1c2VkKSA/IGZvY3VzZWQgOiB7fVxuICAgIGxldCBwaHhVcGRhdGUgPSBsaXZlU29ja2V0LmJpbmRpbmcoUEhYX1VQREFURSlcbiAgICBsZXQgcGh4RmVlZGJhY2tGb3IgPSBsaXZlU29ja2V0LmJpbmRpbmcoUEhYX0ZFRURCQUNLX0ZPUilcbiAgICBsZXQgZGlzYWJsZVdpdGggPSBsaXZlU29ja2V0LmJpbmRpbmcoUEhYX0RJU0FCTEVfV0lUSClcbiAgICBsZXQgcGh4Vmlld3BvcnRUb3AgPSBsaXZlU29ja2V0LmJpbmRpbmcoUEhYX1ZJRVdQT1JUX1RPUClcbiAgICBsZXQgcGh4Vmlld3BvcnRCb3R0b20gPSBsaXZlU29ja2V0LmJpbmRpbmcoUEhYX1ZJRVdQT1JUX0JPVFRPTSlcbiAgICBsZXQgcGh4VHJpZ2dlckV4dGVybmFsID0gbGl2ZVNvY2tldC5iaW5kaW5nKFBIWF9UUklHR0VSX0FDVElPTilcbiAgICBsZXQgYWRkZWQgPSBbXVxuICAgIGxldCB0cmFja2VkSW5wdXRzID0gW11cbiAgICBsZXQgdXBkYXRlcyA9IFtdXG4gICAgbGV0IGFwcGVuZFByZXBlbmRVcGRhdGVzID0gW11cblxuICAgIGxldCBleHRlcm5hbEZvcm1UcmlnZ2VyZWQgPSBudWxsXG5cbiAgICBsZXQgZGlmZkhUTUwgPSBsaXZlU29ja2V0LnRpbWUoXCJwcmVtb3JwaCBjb250YWluZXIgcHJlcFwiLCAoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5idWlsZERpZmZIVE1MKGNvbnRhaW5lciwgaHRtbCwgcGh4VXBkYXRlLCB0YXJnZXRDb250YWluZXIpXG4gICAgfSlcblxuICAgIHRoaXMudHJhY2tCZWZvcmUoXCJhZGRlZFwiLCBjb250YWluZXIpXG4gICAgdGhpcy50cmFja0JlZm9yZShcInVwZGF0ZWRcIiwgY29udGFpbmVyLCBjb250YWluZXIpXG5cbiAgICBsaXZlU29ja2V0LnRpbWUoXCJtb3JwaGRvbVwiLCAoKSA9PiB7XG4gICAgICB0aGlzLnN0cmVhbXMuZm9yRWFjaCgoW3JlZiwgaW5zZXJ0cywgZGVsZXRlSWRzLCByZXNldF0pID0+IHtcbiAgICAgICAgT2JqZWN0LmVudHJpZXMoaW5zZXJ0cykuZm9yRWFjaCgoW2tleSwgW3N0cmVhbUF0LCBsaW1pdF1dKSA9PiB7XG4gICAgICAgICAgdGhpcy5zdHJlYW1JbnNlcnRzW2tleV0gPSB7cmVmLCBzdHJlYW1BdCwgbGltaXR9XG4gICAgICAgIH0pXG4gICAgICAgIGlmKHJlc2V0ICE9PSB1bmRlZmluZWQpe1xuICAgICAgICAgIERPTS5hbGwoY29udGFpbmVyLCBgWyR7UEhYX1NUUkVBTV9SRUZ9PVwiJHtyZWZ9XCJdYCwgY2hpbGQgPT4ge1xuICAgICAgICAgICAgaWYoIWluc2VydHNbY2hpbGQuaWRdKXtcbiAgICAgICAgICAgICAgdGhpcy5yZW1vdmVTdHJlYW1DaGlsZEVsZW1lbnQoY2hpbGQpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICBkZWxldGVJZHMuZm9yRWFjaChpZCA9PiB7XG4gICAgICAgICAgbGV0IGNoaWxkID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoYFtpZD1cIiR7aWR9XCJdYClcbiAgICAgICAgICBpZihjaGlsZCl7IHRoaXMucmVtb3ZlU3RyZWFtQ2hpbGRFbGVtZW50KGNoaWxkKSB9XG4gICAgICAgIH0pXG4gICAgICB9KVxuXG4gICAgICBtb3JwaGRvbSh0YXJnZXRDb250YWluZXIsIGRpZmZIVE1MLCB7XG4gICAgICAgIGNoaWxkcmVuT25seTogdGFyZ2V0Q29udGFpbmVyLmdldEF0dHJpYnV0ZShQSFhfQ09NUE9ORU5UKSA9PT0gbnVsbCxcbiAgICAgICAgZ2V0Tm9kZUtleTogKG5vZGUpID0+IHtcbiAgICAgICAgICByZXR1cm4gRE9NLmlzUGh4RGVzdHJveWVkKG5vZGUpID8gbnVsbCA6IG5vZGUuaWRcbiAgICAgICAgfSxcbiAgICAgICAgLy8gc2tpcCBpbmRleGluZyBmcm9tIGNoaWxkcmVuIHdoZW4gY29udGFpbmVyIGlzIHN0cmVhbVxuICAgICAgICBza2lwRnJvbUNoaWxkcmVuOiAoZnJvbSkgPT4geyByZXR1cm4gZnJvbS5nZXRBdHRyaWJ1dGUocGh4VXBkYXRlKSA9PT0gUEhYX1NUUkVBTSB9LFxuICAgICAgICAvLyB0ZWxsIG1vcnBoZG9tIGhvdyB0byBhZGQgYSBjaGlsZFxuICAgICAgICBhZGRDaGlsZDogKHBhcmVudCwgY2hpbGQpID0+IHtcbiAgICAgICAgICBsZXQge3JlZiwgc3RyZWFtQXQsIGxpbWl0fSA9IHRoaXMuZ2V0U3RyZWFtSW5zZXJ0KGNoaWxkKVxuICAgICAgICAgIGlmKHJlZiA9PT0gdW5kZWZpbmVkKSB7IHJldHVybiBwYXJlbnQuYXBwZW5kQ2hpbGQoY2hpbGQpIH1cblxuICAgICAgICAgIERPTS5wdXRTdGlja3koY2hpbGQsIFBIWF9TVFJFQU1fUkVGLCBlbCA9PiBlbC5zZXRBdHRyaWJ1dGUoUEhYX1NUUkVBTV9SRUYsIHJlZikpXG5cbiAgICAgICAgICAvLyBzdHJlYW1pbmdcbiAgICAgICAgICBpZihzdHJlYW1BdCA9PT0gMCl7XG4gICAgICAgICAgICBwYXJlbnQuaW5zZXJ0QWRqYWNlbnRFbGVtZW50KFwiYWZ0ZXJiZWdpblwiLCBjaGlsZClcbiAgICAgICAgICB9IGVsc2UgaWYoc3RyZWFtQXQgPT09IC0xKXtcbiAgICAgICAgICAgIHBhcmVudC5hcHBlbmRDaGlsZChjaGlsZClcbiAgICAgICAgICB9IGVsc2UgaWYoc3RyZWFtQXQgPiAwKXtcbiAgICAgICAgICAgIGxldCBzaWJsaW5nID0gQXJyYXkuZnJvbShwYXJlbnQuY2hpbGRyZW4pW3N0cmVhbUF0XVxuICAgICAgICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShjaGlsZCwgc2libGluZylcbiAgICAgICAgICB9XG4gICAgICAgICAgbGV0IGNoaWxkcmVuID0gbGltaXQgIT09IG51bGwgJiYgQXJyYXkuZnJvbShwYXJlbnQuY2hpbGRyZW4pXG4gICAgICAgICAgbGV0IGNoaWxkcmVuVG9SZW1vdmUgPSBbXVxuICAgICAgICAgIGlmKGxpbWl0ICYmIGxpbWl0IDwgMCAmJiBjaGlsZHJlbi5sZW5ndGggPiBsaW1pdCAqIC0xKXtcbiAgICAgICAgICAgIGNoaWxkcmVuVG9SZW1vdmUgPSBjaGlsZHJlbi5zbGljZSgwLCBjaGlsZHJlbi5sZW5ndGggKyBsaW1pdClcbiAgICAgICAgICB9IGVsc2UgaWYobGltaXQgJiYgbGltaXQgPj0gMCAmJiBjaGlsZHJlbi5sZW5ndGggPiBsaW1pdCl7XG4gICAgICAgICAgICBjaGlsZHJlblRvUmVtb3ZlID0gY2hpbGRyZW4uc2xpY2UobGltaXQpXG4gICAgICAgICAgfVxuICAgICAgICAgIGNoaWxkcmVuVG9SZW1vdmUuZm9yRWFjaChyZW1vdmVDaGlsZCA9PiB7XG4gICAgICAgICAgICAvLyBkbyBub3QgcmVtb3ZlIGNoaWxkIGFzIHBhcnQgb2YgbGltaXQgaWYgd2UgYXJlIHJlLWFkZGluZyBpdFxuICAgICAgICAgICAgaWYoIXRoaXMuc3RyZWFtSW5zZXJ0c1tyZW1vdmVDaGlsZC5pZF0pe1xuICAgICAgICAgICAgICB0aGlzLnJlbW92ZVN0cmVhbUNoaWxkRWxlbWVudChyZW1vdmVDaGlsZClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICB9LFxuICAgICAgICBvbkJlZm9yZU5vZGVBZGRlZDogKGVsKSA9PiB7XG4gICAgICAgICAgRE9NLm1heWJlQWRkUHJpdmF0ZUhvb2tzKGVsLCBwaHhWaWV3cG9ydFRvcCwgcGh4Vmlld3BvcnRCb3R0b20pXG4gICAgICAgICAgdGhpcy50cmFja0JlZm9yZShcImFkZGVkXCIsIGVsKVxuICAgICAgICAgIHJldHVybiBlbFxuICAgICAgICB9LFxuICAgICAgICBvbk5vZGVBZGRlZDogKGVsKSA9PiB7XG4gICAgICAgICAgaWYoZWwuZ2V0QXR0cmlidXRlKXsgdGhpcy5tYXliZVJlT3JkZXJTdHJlYW0oZWwpIH1cblxuICAgICAgICAgIC8vIGhhY2sgdG8gZml4IFNhZmFyaSBoYW5kbGluZyBvZiBpbWcgc3Jjc2V0IGFuZCB2aWRlbyB0YWdzXG4gICAgICAgICAgaWYoZWwgaW5zdGFuY2VvZiBIVE1MSW1hZ2VFbGVtZW50ICYmIGVsLnNyY3NldCl7XG4gICAgICAgICAgICBlbC5zcmNzZXQgPSBlbC5zcmNzZXRcbiAgICAgICAgICB9IGVsc2UgaWYoZWwgaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50ICYmIGVsLmF1dG9wbGF5KXtcbiAgICAgICAgICAgIGVsLnBsYXkoKVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZihET00uaXNOb3dUcmlnZ2VyRm9ybUV4dGVybmFsKGVsLCBwaHhUcmlnZ2VyRXh0ZXJuYWwpKXtcbiAgICAgICAgICAgIGV4dGVybmFsRm9ybVRyaWdnZXJlZCA9IGVsXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYoZWwuZ2V0QXR0cmlidXRlICYmIGVsLmdldEF0dHJpYnV0ZShcIm5hbWVcIikgJiYgRE9NLmlzRm9ybUlucHV0KGVsKSl7XG4gICAgICAgICAgICB0cmFja2VkSW5wdXRzLnB1c2goZWwpXG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIG5lc3RlZCB2aWV3IGhhbmRsaW5nXG4gICAgICAgICAgaWYoKERPTS5pc1BoeENoaWxkKGVsKSAmJiB2aWV3Lm93bnNFbGVtZW50KGVsKSkgfHwgRE9NLmlzUGh4U3RpY2t5KGVsKSAmJiB2aWV3Lm93bnNFbGVtZW50KGVsLnBhcmVudE5vZGUpKXtcbiAgICAgICAgICAgIHRoaXMudHJhY2tBZnRlcihcInBoeENoaWxkQWRkZWRcIiwgZWwpXG4gICAgICAgICAgfVxuICAgICAgICAgIGFkZGVkLnB1c2goZWwpXG4gICAgICAgIH0sXG4gICAgICAgIG9uTm9kZURpc2NhcmRlZDogKGVsKSA9PiB0aGlzLm9uTm9kZURpc2NhcmRlZChlbCksXG4gICAgICAgIG9uQmVmb3JlTm9kZURpc2NhcmRlZDogKGVsKSA9PiB7XG4gICAgICAgICAgaWYoZWwuZ2V0QXR0cmlidXRlICYmIGVsLmdldEF0dHJpYnV0ZShQSFhfUFJVTkUpICE9PSBudWxsKXsgcmV0dXJuIHRydWUgfVxuICAgICAgICAgIGlmKGVsLnBhcmVudEVsZW1lbnQgIT09IG51bGwgJiYgZWwuaWQgJiZcbiAgICAgICAgICAgIERPTS5pc1BoeFVwZGF0ZShlbC5wYXJlbnRFbGVtZW50LCBwaHhVcGRhdGUsIFtQSFhfU1RSRUFNLCBcImFwcGVuZFwiLCBcInByZXBlbmRcIl0pKXtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZih0aGlzLm1heWJlUGVuZGluZ1JlbW92ZShlbCkpeyByZXR1cm4gZmFsc2UgfVxuICAgICAgICAgIGlmKHRoaXMuc2tpcENJRFNpYmxpbmcoZWwpKXsgcmV0dXJuIGZhbHNlIH1cblxuICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0sXG4gICAgICAgIG9uRWxVcGRhdGVkOiAoZWwpID0+IHtcbiAgICAgICAgICBpZihET00uaXNOb3dUcmlnZ2VyRm9ybUV4dGVybmFsKGVsLCBwaHhUcmlnZ2VyRXh0ZXJuYWwpKXtcbiAgICAgICAgICAgIGV4dGVybmFsRm9ybVRyaWdnZXJlZCA9IGVsXG4gICAgICAgICAgfVxuICAgICAgICAgIHVwZGF0ZXMucHVzaChlbClcbiAgICAgICAgICB0aGlzLm1heWJlUmVPcmRlclN0cmVhbShlbClcbiAgICAgICAgfSxcbiAgICAgICAgb25CZWZvcmVFbFVwZGF0ZWQ6IChmcm9tRWwsIHRvRWwpID0+IHtcbiAgICAgICAgICBET00ubWF5YmVBZGRQcml2YXRlSG9va3ModG9FbCwgcGh4Vmlld3BvcnRUb3AsIHBoeFZpZXdwb3J0Qm90dG9tKVxuICAgICAgICAgIERPTS5jbGVhbkNoaWxkTm9kZXModG9FbCwgcGh4VXBkYXRlKVxuICAgICAgICAgIGlmKHRoaXMuc2tpcENJRFNpYmxpbmcodG9FbCkpeyByZXR1cm4gZmFsc2UgfVxuICAgICAgICAgIGlmKERPTS5pc1BoeFN0aWNreShmcm9tRWwpKXsgcmV0dXJuIGZhbHNlIH1cbiAgICAgICAgICBpZihET00uaXNJZ25vcmVkKGZyb21FbCwgcGh4VXBkYXRlKSB8fCAoZnJvbUVsLmZvcm0gJiYgZnJvbUVsLmZvcm0uaXNTYW1lTm9kZShleHRlcm5hbEZvcm1UcmlnZ2VyZWQpKSl7XG4gICAgICAgICAgICB0aGlzLnRyYWNrQmVmb3JlKFwidXBkYXRlZFwiLCBmcm9tRWwsIHRvRWwpXG4gICAgICAgICAgICBET00ubWVyZ2VBdHRycyhmcm9tRWwsIHRvRWwsIHtpc0lnbm9yZWQ6IHRydWV9KVxuICAgICAgICAgICAgdXBkYXRlcy5wdXNoKGZyb21FbClcbiAgICAgICAgICAgIERPTS5hcHBseVN0aWNreU9wZXJhdGlvbnMoZnJvbUVsKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgfVxuICAgICAgICAgIGlmKGZyb21FbC50eXBlID09PSBcIm51bWJlclwiICYmIChmcm9tRWwudmFsaWRpdHkgJiYgZnJvbUVsLnZhbGlkaXR5LmJhZElucHV0KSl7IHJldHVybiBmYWxzZSB9XG4gICAgICAgICAgaWYoIURPTS5zeW5jUGVuZGluZ1JlZihmcm9tRWwsIHRvRWwsIGRpc2FibGVXaXRoKSl7XG4gICAgICAgICAgICBpZihET00uaXNVcGxvYWRJbnB1dChmcm9tRWwpKXtcbiAgICAgICAgICAgICAgdGhpcy50cmFja0JlZm9yZShcInVwZGF0ZWRcIiwgZnJvbUVsLCB0b0VsKVxuICAgICAgICAgICAgICB1cGRhdGVzLnB1c2goZnJvbUVsKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgRE9NLmFwcGx5U3RpY2t5T3BlcmF0aW9ucyhmcm9tRWwpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBuZXN0ZWQgdmlldyBoYW5kbGluZ1xuICAgICAgICAgIGlmKERPTS5pc1BoeENoaWxkKHRvRWwpKXtcbiAgICAgICAgICAgIGxldCBwcmV2U2Vzc2lvbiA9IGZyb21FbC5nZXRBdHRyaWJ1dGUoUEhYX1NFU1NJT04pXG4gICAgICAgICAgICBET00ubWVyZ2VBdHRycyhmcm9tRWwsIHRvRWwsIHtleGNsdWRlOiBbUEhYX1NUQVRJQ119KVxuICAgICAgICAgICAgaWYocHJldlNlc3Npb24gIT09IFwiXCIpeyBmcm9tRWwuc2V0QXR0cmlidXRlKFBIWF9TRVNTSU9OLCBwcmV2U2Vzc2lvbikgfVxuICAgICAgICAgICAgZnJvbUVsLnNldEF0dHJpYnV0ZShQSFhfUk9PVF9JRCwgdGhpcy5yb290SUQpXG4gICAgICAgICAgICBET00uYXBwbHlTdGlja3lPcGVyYXRpb25zKGZyb21FbClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGlucHV0IGhhbmRsaW5nXG4gICAgICAgICAgRE9NLmNvcHlQcml2YXRlcyh0b0VsLCBmcm9tRWwpXG5cbiAgICAgICAgICBsZXQgaXNGb2N1c2VkRm9ybUVsID0gZm9jdXNlZCAmJiBmcm9tRWwuaXNTYW1lTm9kZShmb2N1c2VkKSAmJiBET00uaXNGb3JtSW5wdXQoZnJvbUVsKVxuICAgICAgICAgIGlmKGlzRm9jdXNlZEZvcm1FbCAmJiBmcm9tRWwudHlwZSAhPT0gXCJoaWRkZW5cIil7XG4gICAgICAgICAgICB0aGlzLnRyYWNrQmVmb3JlKFwidXBkYXRlZFwiLCBmcm9tRWwsIHRvRWwpXG4gICAgICAgICAgICBET00ubWVyZ2VGb2N1c2VkSW5wdXQoZnJvbUVsLCB0b0VsKVxuICAgICAgICAgICAgRE9NLnN5bmNBdHRyc1RvUHJvcHMoZnJvbUVsKVxuICAgICAgICAgICAgdXBkYXRlcy5wdXNoKGZyb21FbClcbiAgICAgICAgICAgIERPTS5hcHBseVN0aWNreU9wZXJhdGlvbnMoZnJvbUVsKVxuICAgICAgICAgICAgdHJhY2tlZElucHV0cy5wdXNoKGZyb21FbClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZihET00uaXNQaHhVcGRhdGUodG9FbCwgcGh4VXBkYXRlLCBbXCJhcHBlbmRcIiwgXCJwcmVwZW5kXCJdKSl7XG4gICAgICAgICAgICAgIGFwcGVuZFByZXBlbmRVcGRhdGVzLnB1c2gobmV3IERPTVBvc3RNb3JwaFJlc3RvcmVyKGZyb21FbCwgdG9FbCwgdG9FbC5nZXRBdHRyaWJ1dGUocGh4VXBkYXRlKSkpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIERPTS5zeW5jQXR0cnNUb1Byb3BzKHRvRWwpXG4gICAgICAgICAgICBET00uYXBwbHlTdGlja3lPcGVyYXRpb25zKHRvRWwpXG4gICAgICAgICAgICBpZih0b0VsLmdldEF0dHJpYnV0ZShcIm5hbWVcIikgJiYgRE9NLmlzRm9ybUlucHV0KHRvRWwpKXtcbiAgICAgICAgICAgICAgdHJhY2tlZElucHV0cy5wdXNoKHRvRWwpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnRyYWNrQmVmb3JlKFwidXBkYXRlZFwiLCBmcm9tRWwsIHRvRWwpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9KVxuXG4gICAgaWYobGl2ZVNvY2tldC5pc0RlYnVnRW5hYmxlZCgpKXsgZGV0ZWN0RHVwbGljYXRlSWRzKCkgfVxuXG4gICAgaWYoYXBwZW5kUHJlcGVuZFVwZGF0ZXMubGVuZ3RoID4gMCl7XG4gICAgICBsaXZlU29ja2V0LnRpbWUoXCJwb3N0LW1vcnBoIGFwcGVuZC9wcmVwZW5kIHJlc3RvcmF0aW9uXCIsICgpID0+IHtcbiAgICAgICAgYXBwZW5kUHJlcGVuZFVwZGF0ZXMuZm9yRWFjaCh1cGRhdGUgPT4gdXBkYXRlLnBlcmZvcm0oKSlcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgdHJhY2tlZElucHV0cy5mb3JFYWNoKGlucHV0ID0+IHtcbiAgICAgIERPTS5tYXliZUhpZGVGZWVkYmFjayh0YXJnZXRDb250YWluZXIsIGlucHV0LCBwaHhGZWVkYmFja0ZvcilcbiAgICB9KVxuXG4gICAgbGl2ZVNvY2tldC5zaWxlbmNlRXZlbnRzKCgpID0+IERPTS5yZXN0b3JlRm9jdXMoZm9jdXNlZCwgc2VsZWN0aW9uU3RhcnQsIHNlbGVjdGlvbkVuZCkpXG4gICAgRE9NLmRpc3BhdGNoRXZlbnQoZG9jdW1lbnQsIFwicGh4OnVwZGF0ZVwiKVxuICAgIGFkZGVkLmZvckVhY2goZWwgPT4gdGhpcy50cmFja0FmdGVyKFwiYWRkZWRcIiwgZWwpKVxuICAgIHVwZGF0ZXMuZm9yRWFjaChlbCA9PiB0aGlzLnRyYWNrQWZ0ZXIoXCJ1cGRhdGVkXCIsIGVsKSlcblxuICAgIHRoaXMudHJhbnNpdGlvblBlbmRpbmdSZW1vdmVzKClcblxuICAgIGlmKGV4dGVybmFsRm9ybVRyaWdnZXJlZCl7XG4gICAgICBsaXZlU29ja2V0LnVubG9hZCgpXG4gICAgICAvLyB1c2UgcHJvdG90eXBlJ3Mgc3VibWl0IGluIGNhc2UgdGhlcmUncyBhIGZvcm0gY29udHJvbCB3aXRoIG5hbWUgb3IgaWQgb2YgXCJzdWJtaXRcIlxuICAgICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0hUTUxGb3JtRWxlbWVudC9zdWJtaXRcbiAgICAgIE9iamVjdC5nZXRQcm90b3R5cGVPZihleHRlcm5hbEZvcm1UcmlnZ2VyZWQpLnN1Ym1pdC5jYWxsKGV4dGVybmFsRm9ybVRyaWdnZXJlZClcbiAgICB9XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIG9uTm9kZURpc2NhcmRlZChlbCl7XG4gICAgLy8gbmVzdGVkIHZpZXcgaGFuZGxpbmdcbiAgICBpZihET00uaXNQaHhDaGlsZChlbCkgfHwgRE9NLmlzUGh4U3RpY2t5KGVsKSl7IHRoaXMubGl2ZVNvY2tldC5kZXN0cm95Vmlld0J5RWwoZWwpIH1cbiAgICB0aGlzLnRyYWNrQWZ0ZXIoXCJkaXNjYXJkZWRcIiwgZWwpXG4gIH1cblxuICBtYXliZVBlbmRpbmdSZW1vdmUobm9kZSl7XG4gICAgaWYobm9kZS5nZXRBdHRyaWJ1dGUgJiYgbm9kZS5nZXRBdHRyaWJ1dGUodGhpcy5waHhSZW1vdmUpICE9PSBudWxsKXtcbiAgICAgIHRoaXMucGVuZGluZ1JlbW92ZXMucHVzaChub2RlKVxuICAgICAgcmV0dXJuIHRydWVcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICB9XG5cbiAgcmVtb3ZlU3RyZWFtQ2hpbGRFbGVtZW50KGNoaWxkKXtcbiAgICBpZighdGhpcy5tYXliZVBlbmRpbmdSZW1vdmUoY2hpbGQpKXtcbiAgICAgIGNoaWxkLnJlbW92ZSgpXG4gICAgICB0aGlzLm9uTm9kZURpc2NhcmRlZChjaGlsZClcbiAgICB9XG4gIH1cblxuICBnZXRTdHJlYW1JbnNlcnQoZWwpe1xuICAgIGxldCBpbnNlcnQgPSBlbC5pZCA/IHRoaXMuc3RyZWFtSW5zZXJ0c1tlbC5pZF0gOiB7fVxuICAgIHJldHVybiBpbnNlcnQgfHwge31cbiAgfVxuXG4gIG1heWJlUmVPcmRlclN0cmVhbShlbCl7XG4gICAgbGV0IHtyZWYsIHN0cmVhbUF0LCBsaW1pdH0gPSB0aGlzLmdldFN0cmVhbUluc2VydChlbClcbiAgICBpZihzdHJlYW1BdCA9PT0gdW5kZWZpbmVkKXsgcmV0dXJuIH1cblxuICAgIC8vIHdlIG5lZWQgdG8gdGhlIFBIWF9TVFJFQU1fUkVGIGhlcmUgYXMgd2VsbCBhcyBhZGRDaGlsZCBpcyBpbnZva2VkIG9ubHkgZm9yIHBhcmVudHNcbiAgICBET00ucHV0U3RpY2t5KGVsLCBQSFhfU1RSRUFNX1JFRiwgZWwgPT4gZWwuc2V0QXR0cmlidXRlKFBIWF9TVFJFQU1fUkVGLCByZWYpKVxuXG4gICAgaWYoc3RyZWFtQXQgPT09IDApe1xuICAgICAgZWwucGFyZW50RWxlbWVudC5pbnNlcnRCZWZvcmUoZWwsIGVsLnBhcmVudEVsZW1lbnQuZmlyc3RFbGVtZW50Q2hpbGQpXG4gICAgfSBlbHNlIGlmKHN0cmVhbUF0ID4gMCl7XG4gICAgICBsZXQgY2hpbGRyZW4gPSBBcnJheS5mcm9tKGVsLnBhcmVudEVsZW1lbnQuY2hpbGRyZW4pXG4gICAgICBsZXQgb2xkSW5kZXggPSBjaGlsZHJlbi5pbmRleE9mKGVsKVxuICAgICAgaWYoc3RyZWFtQXQgPj0gY2hpbGRyZW4ubGVuZ3RoIC0gMSl7XG4gICAgICAgIGVsLnBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQoZWwpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZXQgc2libGluZyA9IGNoaWxkcmVuW3N0cmVhbUF0XVxuICAgICAgICBpZihvbGRJbmRleCA+IHN0cmVhbUF0KXtcbiAgICAgICAgICBlbC5wYXJlbnRFbGVtZW50Lmluc2VydEJlZm9yZShlbCwgc2libGluZylcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBlbC5wYXJlbnRFbGVtZW50Lmluc2VydEJlZm9yZShlbCwgc2libGluZy5uZXh0RWxlbWVudFNpYmxpbmcpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0cmFuc2l0aW9uUGVuZGluZ1JlbW92ZXMoKXtcbiAgICBsZXQge3BlbmRpbmdSZW1vdmVzLCBsaXZlU29ja2V0fSA9IHRoaXNcbiAgICBpZihwZW5kaW5nUmVtb3Zlcy5sZW5ndGggPiAwKXtcbiAgICAgIGxpdmVTb2NrZXQudHJhbnNpdGlvblJlbW92ZXMocGVuZGluZ1JlbW92ZXMpXG4gICAgICBsaXZlU29ja2V0LnJlcXVlc3RET01VcGRhdGUoKCkgPT4ge1xuICAgICAgICBwZW5kaW5nUmVtb3Zlcy5mb3JFYWNoKGVsID0+IHtcbiAgICAgICAgICBsZXQgY2hpbGQgPSBET00uZmlyc3RQaHhDaGlsZChlbClcbiAgICAgICAgICBpZihjaGlsZCl7IGxpdmVTb2NrZXQuZGVzdHJveVZpZXdCeUVsKGNoaWxkKSB9XG4gICAgICAgICAgZWwucmVtb3ZlKClcbiAgICAgICAgfSlcbiAgICAgICAgdGhpcy50cmFja0FmdGVyKFwidHJhbnNpdGlvbnNEaXNjYXJkZWRcIiwgcGVuZGluZ1JlbW92ZXMpXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIGlzQ0lEUGF0Y2goKXsgcmV0dXJuIHRoaXMuY2lkUGF0Y2ggfVxuXG4gIHNraXBDSURTaWJsaW5nKGVsKXtcbiAgICByZXR1cm4gZWwubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmIGVsLmdldEF0dHJpYnV0ZShQSFhfU0tJUCkgIT09IG51bGxcbiAgfVxuXG4gIHRhcmdldENJRENvbnRhaW5lcihodG1sKXtcbiAgICBpZighdGhpcy5pc0NJRFBhdGNoKCkpeyByZXR1cm4gfVxuICAgIGxldCBbZmlyc3QsIC4uLnJlc3RdID0gRE9NLmZpbmRDb21wb25lbnROb2RlTGlzdCh0aGlzLmNvbnRhaW5lciwgdGhpcy50YXJnZXRDSUQpXG4gICAgaWYocmVzdC5sZW5ndGggPT09IDAgJiYgRE9NLmNoaWxkTm9kZUxlbmd0aChodG1sKSA9PT0gMSl7XG4gICAgICByZXR1cm4gZmlyc3RcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZpcnN0ICYmIGZpcnN0LnBhcmVudE5vZGVcbiAgICB9XG4gIH1cblxuICAvLyBidWlsZHMgSFRNTCBmb3IgbW9ycGhkb20gcGF0Y2hcbiAgLy8gLSBmb3IgZnVsbCBwYXRjaGVzIG9mIExpdmVWaWV3IG9yIGEgY29tcG9uZW50IHdpdGggYSBzaW5nbGVcbiAgLy8gICByb290IG5vZGUsIHNpbXBseSByZXR1cm5zIHRoZSBIVE1MXG4gIC8vIC0gZm9yIHBhdGNoZXMgb2YgYSBjb21wb25lbnQgd2l0aCBtdWx0aXBsZSByb290IG5vZGVzLCB0aGVcbiAgLy8gICBwYXJlbnQgbm9kZSBiZWNvbWVzIHRoZSB0YXJnZXQgY29udGFpbmVyIGFuZCBub24tY29tcG9uZW50XG4gIC8vICAgc2libGluZ3MgYXJlIG1hcmtlZCBhcyBza2lwLlxuICBidWlsZERpZmZIVE1MKGNvbnRhaW5lciwgaHRtbCwgcGh4VXBkYXRlLCB0YXJnZXRDb250YWluZXIpe1xuICAgIGxldCBpc0NJRFBhdGNoID0gdGhpcy5pc0NJRFBhdGNoKClcbiAgICBsZXQgaXNDSURXaXRoU2luZ2xlUm9vdCA9IGlzQ0lEUGF0Y2ggJiYgdGFyZ2V0Q29udGFpbmVyLmdldEF0dHJpYnV0ZShQSFhfQ09NUE9ORU5UKSA9PT0gdGhpcy50YXJnZXRDSUQudG9TdHJpbmcoKVxuICAgIGlmKCFpc0NJRFBhdGNoIHx8IGlzQ0lEV2l0aFNpbmdsZVJvb3Qpe1xuICAgICAgcmV0dXJuIGh0bWxcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gY29tcG9uZW50IHBhdGNoIHdpdGggbXVsdGlwbGUgQ0lEIHJvb3RzXG4gICAgICBsZXQgZGlmZkNvbnRhaW5lciA9IG51bGxcbiAgICAgIGxldCB0ZW1wbGF0ZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ0ZW1wbGF0ZVwiKVxuICAgICAgZGlmZkNvbnRhaW5lciA9IERPTS5jbG9uZU5vZGUodGFyZ2V0Q29udGFpbmVyKVxuICAgICAgbGV0IFtmaXJzdENvbXBvbmVudCwgLi4ucmVzdF0gPSBET00uZmluZENvbXBvbmVudE5vZGVMaXN0KGRpZmZDb250YWluZXIsIHRoaXMudGFyZ2V0Q0lEKVxuICAgICAgdGVtcGxhdGUuaW5uZXJIVE1MID0gaHRtbFxuICAgICAgcmVzdC5mb3JFYWNoKGVsID0+IGVsLnJlbW92ZSgpKVxuICAgICAgQXJyYXkuZnJvbShkaWZmQ29udGFpbmVyLmNoaWxkTm9kZXMpLmZvckVhY2goY2hpbGQgPT4ge1xuICAgICAgICAvLyB3ZSBjYW4gb25seSBza2lwIHRyYWNrYWJsZSBub2RlcyB3aXRoIGFuIElEXG4gICAgICAgIGlmKGNoaWxkLmlkICYmIGNoaWxkLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSAmJiBjaGlsZC5nZXRBdHRyaWJ1dGUoUEhYX0NPTVBPTkVOVCkgIT09IHRoaXMudGFyZ2V0Q0lELnRvU3RyaW5nKCkpe1xuICAgICAgICAgIGNoaWxkLnNldEF0dHJpYnV0ZShQSFhfU0tJUCwgXCJcIilcbiAgICAgICAgICBjaGlsZC5pbm5lckhUTUwgPSBcIlwiXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICBBcnJheS5mcm9tKHRlbXBsYXRlLmNvbnRlbnQuY2hpbGROb2RlcykuZm9yRWFjaChlbCA9PiBkaWZmQ29udGFpbmVyLmluc2VydEJlZm9yZShlbCwgZmlyc3RDb21wb25lbnQpKVxuICAgICAgZmlyc3RDb21wb25lbnQucmVtb3ZlKClcbiAgICAgIHJldHVybiBkaWZmQ29udGFpbmVyLm91dGVySFRNTFxuICAgIH1cbiAgfVxuXG4gIGluZGV4T2YocGFyZW50LCBjaGlsZCl7IHJldHVybiBBcnJheS5mcm9tKHBhcmVudC5jaGlsZHJlbikuaW5kZXhPZihjaGlsZCkgfVxufVxuIiwgImltcG9ydCB7XG4gIENPTVBPTkVOVFMsXG4gIERZTkFNSUNTLFxuICBURU1QTEFURVMsXG4gIEVWRU5UUyxcbiAgUEhYX0NPTVBPTkVOVCxcbiAgUEhYX1NLSVAsXG4gIFJFUExZLFxuICBTVEFUSUMsXG4gIFRJVExFLFxuICBTVFJFQU0sXG59IGZyb20gXCIuL2NvbnN0YW50c1wiXG5cbmltcG9ydCB7XG4gIGlzT2JqZWN0LFxuICBsb2dFcnJvcixcbiAgaXNDaWQsXG59IGZyb20gXCIuL3V0aWxzXCJcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmVuZGVyZWQge1xuICBzdGF0aWMgZXh0cmFjdChkaWZmKXtcbiAgICBsZXQge1tSRVBMWV06IHJlcGx5LCBbRVZFTlRTXTogZXZlbnRzLCBbVElUTEVdOiB0aXRsZX0gPSBkaWZmXG4gICAgZGVsZXRlIGRpZmZbUkVQTFldXG4gICAgZGVsZXRlIGRpZmZbRVZFTlRTXVxuICAgIGRlbGV0ZSBkaWZmW1RJVExFXVxuICAgIHJldHVybiB7ZGlmZiwgdGl0bGUsIHJlcGx5OiByZXBseSB8fCBudWxsLCBldmVudHM6IGV2ZW50cyB8fCBbXX1cbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHZpZXdJZCwgcmVuZGVyZWQpe1xuICAgIHRoaXMudmlld0lkID0gdmlld0lkXG4gICAgdGhpcy5yZW5kZXJlZCA9IHt9XG4gICAgdGhpcy5tZXJnZURpZmYocmVuZGVyZWQpXG4gIH1cblxuICBwYXJlbnRWaWV3SWQoKXsgcmV0dXJuIHRoaXMudmlld0lkIH1cblxuICB0b1N0cmluZyhvbmx5Q2lkcyl7XG4gICAgbGV0IFtzdHIsIHN0cmVhbXNdID0gdGhpcy5yZWN1cnNpdmVUb1N0cmluZyh0aGlzLnJlbmRlcmVkLCB0aGlzLnJlbmRlcmVkW0NPTVBPTkVOVFNdLCBvbmx5Q2lkcylcbiAgICByZXR1cm4gW3N0ciwgc3RyZWFtc11cbiAgfVxuXG4gIHJlY3Vyc2l2ZVRvU3RyaW5nKHJlbmRlcmVkLCBjb21wb25lbnRzID0gcmVuZGVyZWRbQ09NUE9ORU5UU10sIG9ubHlDaWRzKXtcbiAgICBvbmx5Q2lkcyA9IG9ubHlDaWRzID8gbmV3IFNldChvbmx5Q2lkcykgOiBudWxsXG4gICAgbGV0IG91dHB1dCA9IHtidWZmZXI6IFwiXCIsIGNvbXBvbmVudHM6IGNvbXBvbmVudHMsIG9ubHlDaWRzOiBvbmx5Q2lkcywgc3RyZWFtczogbmV3IFNldCgpfVxuICAgIHRoaXMudG9PdXRwdXRCdWZmZXIocmVuZGVyZWQsIG51bGwsIG91dHB1dClcbiAgICByZXR1cm4gW291dHB1dC5idWZmZXIsIG91dHB1dC5zdHJlYW1zXVxuICB9XG5cbiAgY29tcG9uZW50Q0lEcyhkaWZmKXsgcmV0dXJuIE9iamVjdC5rZXlzKGRpZmZbQ09NUE9ORU5UU10gfHwge30pLm1hcChpID0+IHBhcnNlSW50KGkpKSB9XG5cbiAgaXNDb21wb25lbnRPbmx5RGlmZihkaWZmKXtcbiAgICBpZighZGlmZltDT01QT05FTlRTXSl7IHJldHVybiBmYWxzZSB9XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGRpZmYpLmxlbmd0aCA9PT0gMVxuICB9XG5cbiAgZ2V0Q29tcG9uZW50KGRpZmYsIGNpZCl7IHJldHVybiBkaWZmW0NPTVBPTkVOVFNdW2NpZF0gfVxuXG4gIG1lcmdlRGlmZihkaWZmKXtcbiAgICBsZXQgbmV3YyA9IGRpZmZbQ09NUE9ORU5UU11cbiAgICBsZXQgY2FjaGUgPSB7fVxuICAgIGRlbGV0ZSBkaWZmW0NPTVBPTkVOVFNdXG4gICAgdGhpcy5yZW5kZXJlZCA9IHRoaXMubXV0YWJsZU1lcmdlKHRoaXMucmVuZGVyZWQsIGRpZmYpXG4gICAgdGhpcy5yZW5kZXJlZFtDT01QT05FTlRTXSA9IHRoaXMucmVuZGVyZWRbQ09NUE9ORU5UU10gfHwge31cblxuICAgIGlmKG5ld2Mpe1xuICAgICAgbGV0IG9sZGMgPSB0aGlzLnJlbmRlcmVkW0NPTVBPTkVOVFNdXG5cbiAgICAgIGZvcihsZXQgY2lkIGluIG5ld2Mpe1xuICAgICAgICBuZXdjW2NpZF0gPSB0aGlzLmNhY2hlZEZpbmRDb21wb25lbnQoY2lkLCBuZXdjW2NpZF0sIG9sZGMsIG5ld2MsIGNhY2hlKVxuICAgICAgfVxuXG4gICAgICBmb3IobGV0IGNpZCBpbiBuZXdjKXsgb2xkY1tjaWRdID0gbmV3Y1tjaWRdIH1cbiAgICAgIGRpZmZbQ09NUE9ORU5UU10gPSBuZXdjXG4gICAgfVxuICB9XG5cbiAgY2FjaGVkRmluZENvbXBvbmVudChjaWQsIGNkaWZmLCBvbGRjLCBuZXdjLCBjYWNoZSl7XG4gICAgaWYoY2FjaGVbY2lkXSl7XG4gICAgICByZXR1cm4gY2FjaGVbY2lkXVxuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgbmRpZmYsIHN0YXQsIHNjaWQgPSBjZGlmZltTVEFUSUNdXG5cbiAgICAgIGlmKGlzQ2lkKHNjaWQpKXtcbiAgICAgICAgbGV0IHRkaWZmXG5cbiAgICAgICAgaWYoc2NpZCA+IDApe1xuICAgICAgICAgIHRkaWZmID0gdGhpcy5jYWNoZWRGaW5kQ29tcG9uZW50KHNjaWQsIG5ld2Nbc2NpZF0sIG9sZGMsIG5ld2MsIGNhY2hlKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRkaWZmID0gb2xkY1stc2NpZF1cbiAgICAgICAgfVxuXG4gICAgICAgIHN0YXQgPSB0ZGlmZltTVEFUSUNdXG4gICAgICAgIG5kaWZmID0gdGhpcy5jbG9uZU1lcmdlKHRkaWZmLCBjZGlmZilcbiAgICAgICAgbmRpZmZbU1RBVElDXSA9IHN0YXRcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5kaWZmID0gY2RpZmZbU1RBVElDXSAhPT0gdW5kZWZpbmVkID8gY2RpZmYgOiB0aGlzLmNsb25lTWVyZ2Uob2xkY1tjaWRdIHx8IHt9LCBjZGlmZilcbiAgICAgIH1cblxuICAgICAgY2FjaGVbY2lkXSA9IG5kaWZmXG4gICAgICByZXR1cm4gbmRpZmZcbiAgICB9XG4gIH1cblxuICBtdXRhYmxlTWVyZ2UodGFyZ2V0LCBzb3VyY2Upe1xuICAgIGlmKHNvdXJjZVtTVEFUSUNdICE9PSB1bmRlZmluZWQpe1xuICAgICAgcmV0dXJuIHNvdXJjZVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRvTXV0YWJsZU1lcmdlKHRhcmdldCwgc291cmNlKVxuICAgICAgcmV0dXJuIHRhcmdldFxuICAgIH1cbiAgfVxuXG4gIGRvTXV0YWJsZU1lcmdlKHRhcmdldCwgc291cmNlKXtcbiAgICBmb3IobGV0IGtleSBpbiBzb3VyY2Upe1xuICAgICAgbGV0IHZhbCA9IHNvdXJjZVtrZXldXG4gICAgICBsZXQgdGFyZ2V0VmFsID0gdGFyZ2V0W2tleV1cbiAgICAgIGxldCBpc09ialZhbCA9IGlzT2JqZWN0KHZhbClcbiAgICAgIGlmKGlzT2JqVmFsICYmIHZhbFtTVEFUSUNdID09PSB1bmRlZmluZWQgJiYgaXNPYmplY3QodGFyZ2V0VmFsKSl7XG4gICAgICAgIHRoaXMuZG9NdXRhYmxlTWVyZ2UodGFyZ2V0VmFsLCB2YWwpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0YXJnZXRba2V5XSA9IHZhbFxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNsb25lTWVyZ2UodGFyZ2V0LCBzb3VyY2Upe1xuICAgIGxldCBtZXJnZWQgPSB7Li4udGFyZ2V0LCAuLi5zb3VyY2V9XG4gICAgZm9yKGxldCBrZXkgaW4gbWVyZ2VkKXtcbiAgICAgIGxldCB2YWwgPSBzb3VyY2Vba2V5XVxuICAgICAgbGV0IHRhcmdldFZhbCA9IHRhcmdldFtrZXldXG4gICAgICBpZihpc09iamVjdCh2YWwpICYmIHZhbFtTVEFUSUNdID09PSB1bmRlZmluZWQgJiYgaXNPYmplY3QodGFyZ2V0VmFsKSl7XG4gICAgICAgIG1lcmdlZFtrZXldID0gdGhpcy5jbG9uZU1lcmdlKHRhcmdldFZhbCwgdmFsKVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbWVyZ2VkXG4gIH1cblxuICBjb21wb25lbnRUb1N0cmluZyhjaWQpe1xuICAgIGxldCBbc3RyLCBzdHJlYW1zXSA9IHRoaXMucmVjdXJzaXZlQ0lEVG9TdHJpbmcodGhpcy5yZW5kZXJlZFtDT01QT05FTlRTXSwgY2lkLCBudWxsLCBmYWxzZSlcbiAgICByZXR1cm4gW3N0ciwgc3RyZWFtc11cbiAgfVxuXG4gIHBydW5lQ0lEcyhjaWRzKXtcbiAgICBjaWRzLmZvckVhY2goY2lkID0+IGRlbGV0ZSB0aGlzLnJlbmRlcmVkW0NPTVBPTkVOVFNdW2NpZF0pXG4gIH1cblxuICAvLyBwcml2YXRlXG5cbiAgZ2V0KCl7IHJldHVybiB0aGlzLnJlbmRlcmVkIH1cblxuICBpc05ld0ZpbmdlcnByaW50KGRpZmYgPSB7fSl7IHJldHVybiAhIWRpZmZbU1RBVElDXSB9XG5cbiAgdGVtcGxhdGVTdGF0aWMocGFydCwgdGVtcGxhdGVzKXtcbiAgICBpZih0eXBlb2YgKHBhcnQpID09PSBcIm51bWJlclwiKSB7XG4gICAgICByZXR1cm4gdGVtcGxhdGVzW3BhcnRdXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBwYXJ0XG4gICAgfVxuICB9XG5cbiAgdG9PdXRwdXRCdWZmZXIocmVuZGVyZWQsIHRlbXBsYXRlcywgb3V0cHV0KXtcbiAgICBpZihyZW5kZXJlZFtEWU5BTUlDU10peyByZXR1cm4gdGhpcy5jb21wcmVoZW5zaW9uVG9CdWZmZXIocmVuZGVyZWQsIHRlbXBsYXRlcywgb3V0cHV0KSB9XG4gICAgbGV0IHtbU1RBVElDXTogc3RhdGljc30gPSByZW5kZXJlZFxuICAgIHN0YXRpY3MgPSB0aGlzLnRlbXBsYXRlU3RhdGljKHN0YXRpY3MsIHRlbXBsYXRlcylcblxuICAgIG91dHB1dC5idWZmZXIgKz0gc3RhdGljc1swXVxuICAgIGZvcihsZXQgaSA9IDE7IGkgPCBzdGF0aWNzLmxlbmd0aDsgaSsrKXtcbiAgICAgIHRoaXMuZHluYW1pY1RvQnVmZmVyKHJlbmRlcmVkW2kgLSAxXSwgdGVtcGxhdGVzLCBvdXRwdXQpXG4gICAgICBvdXRwdXQuYnVmZmVyICs9IHN0YXRpY3NbaV1cbiAgICB9XG4gIH1cblxuICBjb21wcmVoZW5zaW9uVG9CdWZmZXIocmVuZGVyZWQsIHRlbXBsYXRlcywgb3V0cHV0KXtcbiAgICBsZXQge1tEWU5BTUlDU106IGR5bmFtaWNzLCBbU1RBVElDXTogc3RhdGljcywgW1NUUkVBTV06IHN0cmVhbX0gPSByZW5kZXJlZFxuICAgIGxldCBbX3JlZiwgX2luc2VydHMsIGRlbGV0ZUlkcywgcmVzZXRdID0gc3RyZWFtIHx8IFtudWxsLCB7fSwgW10sIG51bGxdXG4gICAgc3RhdGljcyA9IHRoaXMudGVtcGxhdGVTdGF0aWMoc3RhdGljcywgdGVtcGxhdGVzKVxuICAgIGxldCBjb21wVGVtcGxhdGVzID0gdGVtcGxhdGVzIHx8IHJlbmRlcmVkW1RFTVBMQVRFU11cbiAgICBmb3IobGV0IGQgPSAwOyBkIDwgZHluYW1pY3MubGVuZ3RoOyBkKyspe1xuICAgICAgbGV0IGR5bmFtaWMgPSBkeW5hbWljc1tkXVxuICAgICAgb3V0cHV0LmJ1ZmZlciArPSBzdGF0aWNzWzBdXG4gICAgICBmb3IobGV0IGkgPSAxOyBpIDwgc3RhdGljcy5sZW5ndGg7IGkrKyl7XG4gICAgICAgIHRoaXMuZHluYW1pY1RvQnVmZmVyKGR5bmFtaWNbaSAtIDFdLCBjb21wVGVtcGxhdGVzLCBvdXRwdXQpXG4gICAgICAgIG91dHB1dC5idWZmZXIgKz0gc3RhdGljc1tpXVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmKHN0cmVhbSAhPT0gdW5kZWZpbmVkICYmIChyZW5kZXJlZFtEWU5BTUlDU10ubGVuZ3RoID4gMCB8fCBkZWxldGVJZHMubGVuZ3RoID4gMCB8fCByZXNldCkpe1xuICAgICAgZGVsZXRlIHJlbmRlcmVkW1NUUkVBTV1cbiAgICAgIHJlbmRlcmVkW0RZTkFNSUNTXSA9IFtdXG4gICAgICBvdXRwdXQuc3RyZWFtcy5hZGQoc3RyZWFtKVxuICAgIH1cbiAgfVxuXG4gIGR5bmFtaWNUb0J1ZmZlcihyZW5kZXJlZCwgdGVtcGxhdGVzLCBvdXRwdXQpe1xuICAgIGlmKHR5cGVvZiAocmVuZGVyZWQpID09PSBcIm51bWJlclwiKXtcbiAgICAgIGxldCBbc3RyLCBzdHJlYW1zXSA9IHRoaXMucmVjdXJzaXZlQ0lEVG9TdHJpbmcob3V0cHV0LmNvbXBvbmVudHMsIHJlbmRlcmVkLCBvdXRwdXQub25seUNpZHMpXG4gICAgICBvdXRwdXQuYnVmZmVyICs9IHN0clxuICAgICAgb3V0cHV0LnN0cmVhbXMgPSBuZXcgU2V0KFsuLi5vdXRwdXQuc3RyZWFtcywgLi4uc3RyZWFtc10pXG4gICAgfSBlbHNlIGlmKGlzT2JqZWN0KHJlbmRlcmVkKSl7XG4gICAgICB0aGlzLnRvT3V0cHV0QnVmZmVyKHJlbmRlcmVkLCB0ZW1wbGF0ZXMsIG91dHB1dClcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0cHV0LmJ1ZmZlciArPSByZW5kZXJlZFxuICAgIH1cbiAgfVxuXG4gIHJlY3Vyc2l2ZUNJRFRvU3RyaW5nKGNvbXBvbmVudHMsIGNpZCwgb25seUNpZHMsIGFsbG93Um9vdENvbW1lbnRzID0gdHJ1ZSl7XG4gICAgbGV0IGNvbXBvbmVudCA9IGNvbXBvbmVudHNbY2lkXSB8fCBsb2dFcnJvcihgbm8gY29tcG9uZW50IGZvciBDSUQgJHtjaWR9YCwgY29tcG9uZW50cylcbiAgICBsZXQgdGVtcGxhdGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidGVtcGxhdGVcIilcbiAgICBsZXQgW2h0bWwsIHN0cmVhbXNdID0gdGhpcy5yZWN1cnNpdmVUb1N0cmluZyhjb21wb25lbnQsIGNvbXBvbmVudHMsIG9ubHlDaWRzKVxuICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IGh0bWxcbiAgICBsZXQgY29udGFpbmVyID0gdGVtcGxhdGUuY29udGVudFxuICAgIGxldCBza2lwID0gb25seUNpZHMgJiYgIW9ubHlDaWRzLmhhcyhjaWQpXG5cbiAgICBsZXQgW2hhc0NoaWxkTm9kZXMsIGhhc0NoaWxkQ29tcG9uZW50c10gPVxuICAgICAgQXJyYXkuZnJvbShjb250YWluZXIuY2hpbGROb2RlcykucmVkdWNlKChbaGFzTm9kZXMsIGhhc0NvbXBvbmVudHNdLCBjaGlsZCwgaSkgPT4ge1xuICAgICAgICBpZihjaGlsZC5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpe1xuICAgICAgICAgIGlmKGNoaWxkLmdldEF0dHJpYnV0ZShQSFhfQ09NUE9ORU5UKSl7XG4gICAgICAgICAgICByZXR1cm4gW2hhc05vZGVzLCB0cnVlXVxuICAgICAgICAgIH1cbiAgICAgICAgICBjaGlsZC5zZXRBdHRyaWJ1dGUoUEhYX0NPTVBPTkVOVCwgY2lkKVxuICAgICAgICAgIGlmKCFjaGlsZC5pZCl7IGNoaWxkLmlkID0gYCR7dGhpcy5wYXJlbnRWaWV3SWQoKX0tJHtjaWR9LSR7aX1gIH1cbiAgICAgICAgICBpZihza2lwKXtcbiAgICAgICAgICAgIGNoaWxkLnNldEF0dHJpYnV0ZShQSFhfU0tJUCwgXCJcIilcbiAgICAgICAgICAgIGNoaWxkLmlubmVySFRNTCA9IFwiXCJcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIFt0cnVlLCBoYXNDb21wb25lbnRzXVxuICAgICAgICB9IGVsc2UgaWYoY2hpbGQubm9kZVR5cGUgPT09IE5vZGUuQ09NTUVOVF9OT0RFKXtcbiAgICAgICAgICAvLyB3ZSBoYXZlIHRvIHN0cmlwIHJvb3QgY29tbWVudHMgd2hlbiByZW5kZXJpbmcgYSBjb21wb25lbnQgZGlyZWN0bHlcbiAgICAgICAgICAvLyBmb3IgcGF0Y2hpbmcgYmVjYXVzZSB0aGUgbW9ycGhkb20gdGFyZ2V0IG11c3QgYmUgZXhhY3RseSB0aGUgcm9vdCBlbnRyeXBvaW50XG4gICAgICAgICAgaWYoIWFsbG93Um9vdENvbW1lbnRzKXsgY2hpbGQucmVtb3ZlKCkgfVxuICAgICAgICAgIHJldHVybiBbaGFzTm9kZXMsIGhhc0NvbXBvbmVudHNdXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYoY2hpbGQubm9kZVZhbHVlLnRyaW0oKSAhPT0gXCJcIil7XG4gICAgICAgICAgICBsb2dFcnJvcihcIm9ubHkgSFRNTCBlbGVtZW50IHRhZ3MgYXJlIGFsbG93ZWQgYXQgdGhlIHJvb3Qgb2YgY29tcG9uZW50cy5cXG5cXG5cIiArXG4gICAgICAgICAgICAgIGBnb3Q6IFwiJHtjaGlsZC5ub2RlVmFsdWUudHJpbSgpfVwiXFxuXFxuYCArXG4gICAgICAgICAgICAgIFwid2l0aGluOlxcblwiLCB0ZW1wbGF0ZS5pbm5lckhUTUwudHJpbSgpKVxuICAgICAgICAgICAgY2hpbGQucmVwbGFjZVdpdGgodGhpcy5jcmVhdGVTcGFuKGNoaWxkLm5vZGVWYWx1ZSwgY2lkKSlcbiAgICAgICAgICAgIHJldHVybiBbdHJ1ZSwgaGFzQ29tcG9uZW50c11cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2hpbGQucmVtb3ZlKClcbiAgICAgICAgICAgIHJldHVybiBbaGFzTm9kZXMsIGhhc0NvbXBvbmVudHNdXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LCBbZmFsc2UsIGZhbHNlXSlcblxuICAgIGlmKCFoYXNDaGlsZE5vZGVzICYmICFoYXNDaGlsZENvbXBvbmVudHMpe1xuICAgICAgbG9nRXJyb3IoXCJleHBlY3RlZCBhdCBsZWFzdCBvbmUgSFRNTCBlbGVtZW50IHRhZyBpbnNpZGUgYSBjb21wb25lbnQsIGJ1dCB0aGUgY29tcG9uZW50IGlzIGVtcHR5OlxcblwiLFxuICAgICAgICB0ZW1wbGF0ZS5pbm5lckhUTUwudHJpbSgpKVxuICAgICAgcmV0dXJuIFt0aGlzLmNyZWF0ZVNwYW4oXCJcIiwgY2lkKS5vdXRlckhUTUwsIHN0cmVhbXNdXG4gICAgfSBlbHNlIGlmKCFoYXNDaGlsZE5vZGVzICYmIGhhc0NoaWxkQ29tcG9uZW50cyl7XG4gICAgICBsb2dFcnJvcihcImV4cGVjdGVkIGF0IGxlYXN0IG9uZSBIVE1MIGVsZW1lbnQgdGFnIGRpcmVjdGx5IGluc2lkZSBhIGNvbXBvbmVudCwgYnV0IG9ubHkgc3ViY29tcG9uZW50cyB3ZXJlIGZvdW5kLiBBIGNvbXBvbmVudCBtdXN0IHJlbmRlciBhdCBsZWFzdCBvbmUgSFRNTCB0YWcgZGlyZWN0bHkgaW5zaWRlIGl0c2VsZi5cIixcbiAgICAgICAgdGVtcGxhdGUuaW5uZXJIVE1MLnRyaW0oKSlcbiAgICAgIHJldHVybiBbdGVtcGxhdGUuaW5uZXJIVE1MLCBzdHJlYW1zXVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gW3RlbXBsYXRlLmlubmVySFRNTCwgc3RyZWFtc11cbiAgICB9XG4gIH1cblxuICBjcmVhdGVTcGFuKHRleHQsIGNpZCl7XG4gICAgbGV0IHNwYW4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3BhblwiKVxuICAgIHNwYW4uaW5uZXJUZXh0ID0gdGV4dFxuICAgIHNwYW4uc2V0QXR0cmlidXRlKFBIWF9DT01QT05FTlQsIGNpZClcbiAgICByZXR1cm4gc3BhblxuICB9XG59IiwgImxldCB2aWV3SG9va0lEID0gMVxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVmlld0hvb2sge1xuICBzdGF0aWMgbWFrZUlEKCl7IHJldHVybiB2aWV3SG9va0lEKysgfVxuICBzdGF0aWMgZWxlbWVudElEKGVsKXsgcmV0dXJuIGVsLnBoeEhvb2tJZCB9XG5cbiAgY29uc3RydWN0b3IodmlldywgZWwsIGNhbGxiYWNrcyl7XG4gICAgdGhpcy5fX3ZpZXcgPSB2aWV3XG4gICAgdGhpcy5saXZlU29ja2V0ID0gdmlldy5saXZlU29ja2V0XG4gICAgdGhpcy5fX2NhbGxiYWNrcyA9IGNhbGxiYWNrc1xuICAgIHRoaXMuX19saXN0ZW5lcnMgPSBuZXcgU2V0KClcbiAgICB0aGlzLl9faXNEaXNjb25uZWN0ZWQgPSBmYWxzZVxuICAgIHRoaXMuZWwgPSBlbFxuICAgIHRoaXMuZWwucGh4SG9va0lkID0gdGhpcy5jb25zdHJ1Y3Rvci5tYWtlSUQoKVxuICAgIGZvcihsZXQga2V5IGluIHRoaXMuX19jYWxsYmFja3MpeyB0aGlzW2tleV0gPSB0aGlzLl9fY2FsbGJhY2tzW2tleV0gfVxuICB9XG5cbiAgX19tb3VudGVkKCl7IHRoaXMubW91bnRlZCAmJiB0aGlzLm1vdW50ZWQoKSB9XG4gIF9fdXBkYXRlZCgpeyB0aGlzLnVwZGF0ZWQgJiYgdGhpcy51cGRhdGVkKCkgfVxuICBfX2JlZm9yZVVwZGF0ZSgpeyB0aGlzLmJlZm9yZVVwZGF0ZSAmJiB0aGlzLmJlZm9yZVVwZGF0ZSgpIH1cbiAgX19kZXN0cm95ZWQoKXsgdGhpcy5kZXN0cm95ZWQgJiYgdGhpcy5kZXN0cm95ZWQoKSB9XG4gIF9fcmVjb25uZWN0ZWQoKXtcbiAgICBpZih0aGlzLl9faXNEaXNjb25uZWN0ZWQpe1xuICAgICAgdGhpcy5fX2lzRGlzY29ubmVjdGVkID0gZmFsc2VcbiAgICAgIHRoaXMucmVjb25uZWN0ZWQgJiYgdGhpcy5yZWNvbm5lY3RlZCgpXG4gICAgfVxuICB9XG4gIF9fZGlzY29ubmVjdGVkKCl7XG4gICAgdGhpcy5fX2lzRGlzY29ubmVjdGVkID0gdHJ1ZVxuICAgIHRoaXMuZGlzY29ubmVjdGVkICYmIHRoaXMuZGlzY29ubmVjdGVkKClcbiAgfVxuXG4gIHB1c2hFdmVudChldmVudCwgcGF5bG9hZCA9IHt9LCBvblJlcGx5ID0gZnVuY3Rpb24gKCl7IH0pe1xuICAgIHJldHVybiB0aGlzLl9fdmlldy5wdXNoSG9va0V2ZW50KHRoaXMuZWwsIG51bGwsIGV2ZW50LCBwYXlsb2FkLCBvblJlcGx5KVxuICB9XG5cbiAgcHVzaEV2ZW50VG8ocGh4VGFyZ2V0LCBldmVudCwgcGF5bG9hZCA9IHt9LCBvblJlcGx5ID0gZnVuY3Rpb24gKCl7IH0pe1xuICAgIHJldHVybiB0aGlzLl9fdmlldy53aXRoaW5UYXJnZXRzKHBoeFRhcmdldCwgKHZpZXcsIHRhcmdldEN0eCkgPT4ge1xuICAgICAgcmV0dXJuIHZpZXcucHVzaEhvb2tFdmVudCh0aGlzLmVsLCB0YXJnZXRDdHgsIGV2ZW50LCBwYXlsb2FkLCBvblJlcGx5KVxuICAgIH0pXG4gIH1cblxuICBoYW5kbGVFdmVudChldmVudCwgY2FsbGJhY2spe1xuICAgIGxldCBjYWxsYmFja1JlZiA9IChjdXN0b21FdmVudCwgYnlwYXNzKSA9PiBieXBhc3MgPyBldmVudCA6IGNhbGxiYWNrKGN1c3RvbUV2ZW50LmRldGFpbClcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihgcGh4OiR7ZXZlbnR9YCwgY2FsbGJhY2tSZWYpXG4gICAgdGhpcy5fX2xpc3RlbmVycy5hZGQoY2FsbGJhY2tSZWYpXG4gICAgcmV0dXJuIGNhbGxiYWNrUmVmXG4gIH1cblxuICByZW1vdmVIYW5kbGVFdmVudChjYWxsYmFja1JlZil7XG4gICAgbGV0IGV2ZW50ID0gY2FsbGJhY2tSZWYobnVsbCwgdHJ1ZSlcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihgcGh4OiR7ZXZlbnR9YCwgY2FsbGJhY2tSZWYpXG4gICAgdGhpcy5fX2xpc3RlbmVycy5kZWxldGUoY2FsbGJhY2tSZWYpXG4gIH1cblxuICB1cGxvYWQobmFtZSwgZmlsZXMpe1xuICAgIHJldHVybiB0aGlzLl9fdmlldy5kaXNwYXRjaFVwbG9hZHMobmFtZSwgZmlsZXMpXG4gIH1cblxuICB1cGxvYWRUbyhwaHhUYXJnZXQsIG5hbWUsIGZpbGVzKXtcbiAgICByZXR1cm4gdGhpcy5fX3ZpZXcud2l0aGluVGFyZ2V0cyhwaHhUYXJnZXQsIHZpZXcgPT4gdmlldy5kaXNwYXRjaFVwbG9hZHMobmFtZSwgZmlsZXMpKVxuICB9XG5cbiAgX19jbGVhbnVwX18oKXtcbiAgICB0aGlzLl9fbGlzdGVuZXJzLmZvckVhY2goY2FsbGJhY2tSZWYgPT4gdGhpcy5yZW1vdmVIYW5kbGVFdmVudChjYWxsYmFja1JlZikpXG4gIH1cbn1cbiIsICJpbXBvcnQgRE9NIGZyb20gXCIuL2RvbVwiXG5pbXBvcnQgQVJJQSBmcm9tIFwiLi9hcmlhXCJcblxubGV0IGZvY3VzU3RhY2sgPSBudWxsXG5cbmxldCBKUyA9IHtcbiAgZXhlYyhldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZGVmYXVsdHMpe1xuICAgIGxldCBbZGVmYXVsdEtpbmQsIGRlZmF1bHRBcmdzXSA9IGRlZmF1bHRzIHx8IFtudWxsLCB7Y2FsbGJhY2s6IGRlZmF1bHRzICYmIGRlZmF1bHRzLmNhbGxiYWNrfV1cbiAgICBsZXQgY29tbWFuZHMgPSBwaHhFdmVudC5jaGFyQXQoMCkgPT09IFwiW1wiID9cbiAgICAgIEpTT04ucGFyc2UocGh4RXZlbnQpIDogW1tkZWZhdWx0S2luZCwgZGVmYXVsdEFyZ3NdXVxuXG5cblxuICAgIGNvbW1hbmRzLmZvckVhY2goKFtraW5kLCBhcmdzXSkgPT4ge1xuICAgICAgaWYoa2luZCA9PT0gZGVmYXVsdEtpbmQgJiYgZGVmYXVsdEFyZ3MuZGF0YSl7XG4gICAgICAgIGFyZ3MuZGF0YSA9IE9iamVjdC5hc3NpZ24oYXJncy5kYXRhIHx8IHt9LCBkZWZhdWx0QXJncy5kYXRhKVxuICAgICAgICBhcmdzLmNhbGxiYWNrID0gYXJncy5jYWxsYmFjayB8fCBkZWZhdWx0QXJncy5jYWxsYmFja1xuICAgICAgfVxuICAgICAgdGhpcy5maWx0ZXJUb0Vscyhzb3VyY2VFbCwgYXJncykuZm9yRWFjaChlbCA9PiB7XG4gICAgICAgIHRoaXNbYGV4ZWNfJHtraW5kfWBdKGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgYXJncylcbiAgICAgIH0pXG4gICAgfSlcbiAgfSxcblxuICBpc1Zpc2libGUoZWwpe1xuICAgIHJldHVybiAhIShlbC5vZmZzZXRXaWR0aCB8fCBlbC5vZmZzZXRIZWlnaHQgfHwgZWwuZ2V0Q2xpZW50UmVjdHMoKS5sZW5ndGggPiAwKVxuICB9LFxuXG4gIC8vIHByaXZhdGVcblxuICAvLyBjb21tYW5kc1xuXG4gIGV4ZWNfZXhlYyhldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIFthdHRyLCB0b10pe1xuICAgIGxldCBub2RlcyA9IHRvID8gRE9NLmFsbChkb2N1bWVudCwgdG8pIDogW3NvdXJjZUVsXVxuICAgIG5vZGVzLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICBsZXQgZW5jb2RlZEpTID0gbm9kZS5nZXRBdHRyaWJ1dGUoYXR0cilcbiAgICAgIGlmKCFlbmNvZGVkSlMpeyB0aHJvdyBuZXcgRXJyb3IoYGV4cGVjdGVkICR7YXR0cn0gdG8gY29udGFpbiBKUyBjb21tYW5kIG9uIFwiJHt0b31cImApIH1cbiAgICAgIHZpZXcubGl2ZVNvY2tldC5leGVjSlMobm9kZSwgZW5jb2RlZEpTLCBldmVudFR5cGUpXG4gICAgfSlcbiAgfSxcblxuICBleGVjX2Rpc3BhdGNoKGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwge3RvLCBldmVudCwgZGV0YWlsLCBidWJibGVzfSl7XG4gICAgZGV0YWlsID0gZGV0YWlsIHx8IHt9XG4gICAgZGV0YWlsLmRpc3BhdGNoZXIgPSBzb3VyY2VFbFxuICAgIERPTS5kaXNwYXRjaEV2ZW50KGVsLCBldmVudCwge2RldGFpbCwgYnViYmxlc30pXG4gIH0sXG5cbiAgZXhlY19wdXNoKGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgYXJncyl7XG4gICAgaWYoIXZpZXcuaXNDb25uZWN0ZWQoKSl7IHJldHVybiB9XG5cbiAgICBsZXQge2V2ZW50LCBkYXRhLCB0YXJnZXQsIHBhZ2VfbG9hZGluZywgbG9hZGluZywgdmFsdWUsIGRpc3BhdGNoZXIsIGNhbGxiYWNrfSA9IGFyZ3NcbiAgICBsZXQgcHVzaE9wdHMgPSB7bG9hZGluZywgdmFsdWUsIHRhcmdldCwgcGFnZV9sb2FkaW5nOiAhIXBhZ2VfbG9hZGluZ31cbiAgICBsZXQgdGFyZ2V0U3JjID0gZXZlbnRUeXBlID09PSBcImNoYW5nZVwiICYmIGRpc3BhdGNoZXIgPyBkaXNwYXRjaGVyIDogc291cmNlRWxcbiAgICBsZXQgcGh4VGFyZ2V0ID0gdGFyZ2V0IHx8IHRhcmdldFNyYy5nZXRBdHRyaWJ1dGUodmlldy5iaW5kaW5nKFwidGFyZ2V0XCIpKSB8fCB0YXJnZXRTcmNcbiAgICB2aWV3LndpdGhpblRhcmdldHMocGh4VGFyZ2V0LCAodGFyZ2V0VmlldywgdGFyZ2V0Q3R4KSA9PiB7XG4gICAgICBpZihldmVudFR5cGUgPT09IFwiY2hhbmdlXCIpe1xuICAgICAgICBsZXQge25ld0NpZCwgX3RhcmdldH0gPSBhcmdzXG4gICAgICAgIF90YXJnZXQgPSBfdGFyZ2V0IHx8IChET00uaXNGb3JtSW5wdXQoc291cmNlRWwpID8gc291cmNlRWwubmFtZSA6IHVuZGVmaW5lZClcbiAgICAgICAgaWYoX3RhcmdldCl7IHB1c2hPcHRzLl90YXJnZXQgPSBfdGFyZ2V0IH1cbiAgICAgICAgdGFyZ2V0Vmlldy5wdXNoSW5wdXQoc291cmNlRWwsIHRhcmdldEN0eCwgbmV3Q2lkLCBldmVudCB8fCBwaHhFdmVudCwgcHVzaE9wdHMsIGNhbGxiYWNrKVxuICAgICAgfSBlbHNlIGlmKGV2ZW50VHlwZSA9PT0gXCJzdWJtaXRcIil7XG4gICAgICAgIGxldCB7c3VibWl0dGVyfSA9IGFyZ3NcbiAgICAgICAgdGFyZ2V0Vmlldy5zdWJtaXRGb3JtKHNvdXJjZUVsLCB0YXJnZXRDdHgsIGV2ZW50IHx8IHBoeEV2ZW50LCBzdWJtaXR0ZXIsIHB1c2hPcHRzLCBjYWxsYmFjaylcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRhcmdldFZpZXcucHVzaEV2ZW50KGV2ZW50VHlwZSwgc291cmNlRWwsIHRhcmdldEN0eCwgZXZlbnQgfHwgcGh4RXZlbnQsIGRhdGEsIHB1c2hPcHRzLCBjYWxsYmFjaylcbiAgICAgIH1cbiAgICB9KVxuICB9LFxuXG4gIGV4ZWNfbmF2aWdhdGUoZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsLCB7aHJlZiwgcmVwbGFjZX0pe1xuICAgIHZpZXcubGl2ZVNvY2tldC5oaXN0b3J5UmVkaXJlY3QoaHJlZiwgcmVwbGFjZSA/IFwicmVwbGFjZVwiIDogXCJwdXNoXCIpXG4gIH0sXG5cbiAgZXhlY19wYXRjaChldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIHtocmVmLCByZXBsYWNlfSl7XG4gICAgdmlldy5saXZlU29ja2V0LnB1c2hIaXN0b3J5UGF0Y2goaHJlZiwgcmVwbGFjZSA/IFwicmVwbGFjZVwiIDogXCJwdXNoXCIsIHNvdXJjZUVsKVxuICB9LFxuXG4gIGV4ZWNfZm9jdXMoZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsKXtcbiAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IEFSSUEuYXR0ZW1wdEZvY3VzKGVsKSlcbiAgfSxcblxuICBleGVjX2ZvY3VzX2ZpcnN0KGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCl7XG4gICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiBBUklBLmZvY3VzRmlyc3RJbnRlcmFjdGl2ZShlbCkgfHwgQVJJQS5mb2N1c0ZpcnN0KGVsKSlcbiAgfSxcblxuICBleGVjX3B1c2hfZm9jdXMoZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsKXtcbiAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IGZvY3VzU3RhY2sgPSBlbCB8fCBzb3VyY2VFbClcbiAgfSxcblxuICBleGVjX3BvcF9mb2N1cyhldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwpe1xuICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgaWYoZm9jdXNTdGFjayl7IGZvY3VzU3RhY2suZm9jdXMoKSB9XG4gICAgICBmb2N1c1N0YWNrID0gbnVsbFxuICAgIH0pXG4gIH0sXG5cbiAgZXhlY19hZGRfY2xhc3MoZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsLCB7bmFtZXMsIHRyYW5zaXRpb24sIHRpbWV9KXtcbiAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgbmFtZXMsIFtdLCB0cmFuc2l0aW9uLCB0aW1lLCB2aWV3KVxuICB9LFxuXG4gIGV4ZWNfcmVtb3ZlX2NsYXNzKGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwge25hbWVzLCB0cmFuc2l0aW9uLCB0aW1lfSl7XG4gICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIFtdLCBuYW1lcywgdHJhbnNpdGlvbiwgdGltZSwgdmlldylcbiAgfSxcblxuICBleGVjX3RyYW5zaXRpb24oZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsLCB7dGltZSwgdHJhbnNpdGlvbn0pe1xuICAgIHRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKGVsLCBbXSwgW10sIHRyYW5zaXRpb24sIHRpbWUsIHZpZXcpXG4gIH0sXG5cbiAgZXhlY190b2dnbGUoZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsLCB7ZGlzcGxheSwgaW5zLCBvdXRzLCB0aW1lfSl7XG4gICAgdGhpcy50b2dnbGUoZXZlbnRUeXBlLCB2aWV3LCBlbCwgZGlzcGxheSwgaW5zLCBvdXRzLCB0aW1lKVxuICB9LFxuXG4gIGV4ZWNfc2hvdyhldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIHtkaXNwbGF5LCB0cmFuc2l0aW9uLCB0aW1lfSl7XG4gICAgdGhpcy5zaG93KGV2ZW50VHlwZSwgdmlldywgZWwsIGRpc3BsYXksIHRyYW5zaXRpb24sIHRpbWUpXG4gIH0sXG5cbiAgZXhlY19oaWRlKGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwge2Rpc3BsYXksIHRyYW5zaXRpb24sIHRpbWV9KXtcbiAgICB0aGlzLmhpZGUoZXZlbnRUeXBlLCB2aWV3LCBlbCwgZGlzcGxheSwgdHJhbnNpdGlvbiwgdGltZSlcbiAgfSxcblxuICBleGVjX3NldF9hdHRyKGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwge2F0dHI6IFthdHRyLCB2YWxdfSl7XG4gICAgdGhpcy5zZXRPclJlbW92ZUF0dHJzKGVsLCBbW2F0dHIsIHZhbF1dLCBbXSlcbiAgfSxcblxuICBleGVjX3JlbW92ZV9hdHRyKGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwge2F0dHJ9KXtcbiAgICB0aGlzLnNldE9yUmVtb3ZlQXR0cnMoZWwsIFtdLCBbYXR0cl0pXG4gIH0sXG5cbiAgLy8gdXRpbHMgZm9yIGNvbW1hbmRzXG5cbiAgc2hvdyhldmVudFR5cGUsIHZpZXcsIGVsLCBkaXNwbGF5LCB0cmFuc2l0aW9uLCB0aW1lKXtcbiAgICBpZighdGhpcy5pc1Zpc2libGUoZWwpKXtcbiAgICAgIHRoaXMudG9nZ2xlKGV2ZW50VHlwZSwgdmlldywgZWwsIGRpc3BsYXksIHRyYW5zaXRpb24sIG51bGwsIHRpbWUpXG4gICAgfVxuICB9LFxuXG4gIGhpZGUoZXZlbnRUeXBlLCB2aWV3LCBlbCwgZGlzcGxheSwgdHJhbnNpdGlvbiwgdGltZSl7XG4gICAgaWYodGhpcy5pc1Zpc2libGUoZWwpKXtcbiAgICAgIHRoaXMudG9nZ2xlKGV2ZW50VHlwZSwgdmlldywgZWwsIGRpc3BsYXksIG51bGwsIHRyYW5zaXRpb24sIHRpbWUpXG4gICAgfVxuICB9LFxuXG4gIHRvZ2dsZShldmVudFR5cGUsIHZpZXcsIGVsLCBkaXNwbGF5LCBpbnMsIG91dHMsIHRpbWUpe1xuICAgIGxldCBbaW5DbGFzc2VzLCBpblN0YXJ0Q2xhc3NlcywgaW5FbmRDbGFzc2VzXSA9IGlucyB8fCBbW10sIFtdLCBbXV1cbiAgICBsZXQgW291dENsYXNzZXMsIG91dFN0YXJ0Q2xhc3Nlcywgb3V0RW5kQ2xhc3Nlc10gPSBvdXRzIHx8IFtbXSwgW10sIFtdXVxuICAgIGlmKGluQ2xhc3Nlcy5sZW5ndGggPiAwIHx8IG91dENsYXNzZXMubGVuZ3RoID4gMCl7XG4gICAgICBpZih0aGlzLmlzVmlzaWJsZShlbCkpe1xuICAgICAgICBsZXQgb25TdGFydCA9ICgpID0+IHtcbiAgICAgICAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgb3V0U3RhcnRDbGFzc2VzLCBpbkNsYXNzZXMuY29uY2F0KGluU3RhcnRDbGFzc2VzKS5jb25jYXQoaW5FbmRDbGFzc2VzKSlcbiAgICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKGVsLCBvdXRDbGFzc2VzLCBbXSlcbiAgICAgICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIG91dEVuZENsYXNzZXMsIG91dFN0YXJ0Q2xhc3NlcykpXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcInBoeDpoaWRlLXN0YXJ0XCIpKVxuICAgICAgICB2aWV3LnRyYW5zaXRpb24odGltZSwgb25TdGFydCwgKCkgPT4ge1xuICAgICAgICAgIHRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKGVsLCBbXSwgb3V0Q2xhc3Nlcy5jb25jYXQob3V0RW5kQ2xhc3NlcykpXG4gICAgICAgICAgRE9NLnB1dFN0aWNreShlbCwgXCJ0b2dnbGVcIiwgY3VycmVudEVsID0+IGN1cnJlbnRFbC5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCIpXG4gICAgICAgICAgZWwuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJwaHg6aGlkZS1lbmRcIikpXG4gICAgICAgIH0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZihldmVudFR5cGUgPT09IFwicmVtb3ZlXCIpeyByZXR1cm4gfVxuICAgICAgICBsZXQgb25TdGFydCA9ICgpID0+IHtcbiAgICAgICAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgaW5TdGFydENsYXNzZXMsIG91dENsYXNzZXMuY29uY2F0KG91dFN0YXJ0Q2xhc3NlcykuY29uY2F0KG91dEVuZENsYXNzZXMpKVxuICAgICAgICAgIGxldCBzdGlja3lEaXNwbGF5ID0gZGlzcGxheSB8fCB0aGlzLmRlZmF1bHREaXNwbGF5KGVsKVxuICAgICAgICAgIERPTS5wdXRTdGlja3koZWwsIFwidG9nZ2xlXCIsIGN1cnJlbnRFbCA9PiBjdXJyZW50RWwuc3R5bGUuZGlzcGxheSA9IHN0aWNreURpc3BsYXkpXG4gICAgICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgaW5DbGFzc2VzLCBbXSlcbiAgICAgICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIGluRW5kQ2xhc3NlcywgaW5TdGFydENsYXNzZXMpKVxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgZWwuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJwaHg6c2hvdy1zdGFydFwiKSlcbiAgICAgICAgdmlldy50cmFuc2l0aW9uKHRpbWUsIG9uU3RhcnQsICgpID0+IHtcbiAgICAgICAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgW10sIGluQ2xhc3Nlcy5jb25jYXQoaW5FbmRDbGFzc2VzKSlcbiAgICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcInBoeDpzaG93LWVuZFwiKSlcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYodGhpcy5pc1Zpc2libGUoZWwpKXtcbiAgICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgZWwuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJwaHg6aGlkZS1zdGFydFwiKSlcbiAgICAgICAgICBET00ucHV0U3RpY2t5KGVsLCBcInRvZ2dsZVwiLCBjdXJyZW50RWwgPT4gY3VycmVudEVsLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIilcbiAgICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcInBoeDpoaWRlLWVuZFwiKSlcbiAgICAgICAgfSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwicGh4OnNob3ctc3RhcnRcIikpXG4gICAgICAgICAgbGV0IHN0aWNreURpc3BsYXkgPSBkaXNwbGF5IHx8IHRoaXMuZGVmYXVsdERpc3BsYXkoZWwpXG4gICAgICAgICAgRE9NLnB1dFN0aWNreShlbCwgXCJ0b2dnbGVcIiwgY3VycmVudEVsID0+IGN1cnJlbnRFbC5zdHlsZS5kaXNwbGF5ID0gc3RpY2t5RGlzcGxheSlcbiAgICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcInBoeDpzaG93LWVuZFwiKSlcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgYWRkT3JSZW1vdmVDbGFzc2VzKGVsLCBhZGRzLCByZW1vdmVzLCB0cmFuc2l0aW9uLCB0aW1lLCB2aWV3KXtcbiAgICBsZXQgW3RyYW5zaXRpb25SdW4sIHRyYW5zaXRpb25TdGFydCwgdHJhbnNpdGlvbkVuZF0gPSB0cmFuc2l0aW9uIHx8IFtbXSwgW10sIFtdXVxuICAgIGlmKHRyYW5zaXRpb25SdW4ubGVuZ3RoID4gMCl7XG4gICAgICBsZXQgb25TdGFydCA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIHRyYW5zaXRpb25TdGFydCwgW10uY29uY2F0KHRyYW5zaXRpb25SdW4pLmNvbmNhdCh0cmFuc2l0aW9uRW5kKSlcbiAgICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIHRyYW5zaXRpb25SdW4sIFtdKVxuICAgICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIHRyYW5zaXRpb25FbmQsIHRyYW5zaXRpb25TdGFydCkpXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgICBsZXQgb25Eb25lID0gKCkgPT4gdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIGFkZHMuY29uY2F0KHRyYW5zaXRpb25FbmQpLCByZW1vdmVzLmNvbmNhdCh0cmFuc2l0aW9uUnVuKS5jb25jYXQodHJhbnNpdGlvblN0YXJ0KSlcbiAgICAgIHJldHVybiB2aWV3LnRyYW5zaXRpb24odGltZSwgb25TdGFydCwgb25Eb25lKVxuICAgIH1cblxuICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgbGV0IFtwcmV2QWRkcywgcHJldlJlbW92ZXNdID0gRE9NLmdldFN0aWNreShlbCwgXCJjbGFzc2VzXCIsIFtbXSwgW11dKVxuICAgICAgbGV0IGtlZXBBZGRzID0gYWRkcy5maWx0ZXIobmFtZSA9PiBwcmV2QWRkcy5pbmRleE9mKG5hbWUpIDwgMCAmJiAhZWwuY2xhc3NMaXN0LmNvbnRhaW5zKG5hbWUpKVxuICAgICAgbGV0IGtlZXBSZW1vdmVzID0gcmVtb3Zlcy5maWx0ZXIobmFtZSA9PiBwcmV2UmVtb3Zlcy5pbmRleE9mKG5hbWUpIDwgMCAmJiBlbC5jbGFzc0xpc3QuY29udGFpbnMobmFtZSkpXG4gICAgICBsZXQgbmV3QWRkcyA9IHByZXZBZGRzLmZpbHRlcihuYW1lID0+IHJlbW92ZXMuaW5kZXhPZihuYW1lKSA8IDApLmNvbmNhdChrZWVwQWRkcylcbiAgICAgIGxldCBuZXdSZW1vdmVzID0gcHJldlJlbW92ZXMuZmlsdGVyKG5hbWUgPT4gYWRkcy5pbmRleE9mKG5hbWUpIDwgMCkuY29uY2F0KGtlZXBSZW1vdmVzKVxuXG4gICAgICBET00ucHV0U3RpY2t5KGVsLCBcImNsYXNzZXNcIiwgY3VycmVudEVsID0+IHtcbiAgICAgICAgY3VycmVudEVsLmNsYXNzTGlzdC5yZW1vdmUoLi4ubmV3UmVtb3ZlcylcbiAgICAgICAgY3VycmVudEVsLmNsYXNzTGlzdC5hZGQoLi4ubmV3QWRkcylcbiAgICAgICAgcmV0dXJuIFtuZXdBZGRzLCBuZXdSZW1vdmVzXVxuICAgICAgfSlcbiAgICB9KVxuICB9LFxuXG4gIHNldE9yUmVtb3ZlQXR0cnMoZWwsIHNldHMsIHJlbW92ZXMpe1xuICAgIGxldCBbcHJldlNldHMsIHByZXZSZW1vdmVzXSA9IERPTS5nZXRTdGlja3koZWwsIFwiYXR0cnNcIiwgW1tdLCBbXV0pXG5cbiAgICBsZXQgYWx0ZXJlZEF0dHJzID0gc2V0cy5tYXAoKFthdHRyLCBfdmFsXSkgPT4gYXR0cikuY29uY2F0KHJlbW92ZXMpO1xuICAgIGxldCBuZXdTZXRzID0gcHJldlNldHMuZmlsdGVyKChbYXR0ciwgX3ZhbF0pID0+ICFhbHRlcmVkQXR0cnMuaW5jbHVkZXMoYXR0cikpLmNvbmNhdChzZXRzKTtcbiAgICBsZXQgbmV3UmVtb3ZlcyA9IHByZXZSZW1vdmVzLmZpbHRlcigoYXR0cikgPT4gIWFsdGVyZWRBdHRycy5pbmNsdWRlcyhhdHRyKSkuY29uY2F0KHJlbW92ZXMpO1xuXG4gICAgRE9NLnB1dFN0aWNreShlbCwgXCJhdHRyc1wiLCBjdXJyZW50RWwgPT4ge1xuICAgICAgbmV3UmVtb3Zlcy5mb3JFYWNoKGF0dHIgPT4gY3VycmVudEVsLnJlbW92ZUF0dHJpYnV0ZShhdHRyKSlcbiAgICAgIG5ld1NldHMuZm9yRWFjaCgoW2F0dHIsIHZhbF0pID0+IGN1cnJlbnRFbC5zZXRBdHRyaWJ1dGUoYXR0ciwgdmFsKSlcbiAgICAgIHJldHVybiBbbmV3U2V0cywgbmV3UmVtb3Zlc11cbiAgICB9KVxuICB9LFxuXG4gIGhhc0FsbENsYXNzZXMoZWwsIGNsYXNzZXMpeyByZXR1cm4gY2xhc3Nlcy5ldmVyeShuYW1lID0+IGVsLmNsYXNzTGlzdC5jb250YWlucyhuYW1lKSkgfSxcblxuICBpc1RvZ2dsZWRPdXQoZWwsIG91dENsYXNzZXMpe1xuICAgIHJldHVybiAhdGhpcy5pc1Zpc2libGUoZWwpIHx8IHRoaXMuaGFzQWxsQ2xhc3NlcyhlbCwgb3V0Q2xhc3NlcylcbiAgfSxcblxuICBmaWx0ZXJUb0Vscyhzb3VyY2VFbCwge3RvfSl7XG4gICAgcmV0dXJuIHRvID8gRE9NLmFsbChkb2N1bWVudCwgdG8pIDogW3NvdXJjZUVsXVxuICB9LFxuXG4gIGRlZmF1bHREaXNwbGF5KGVsKXtcbiAgICByZXR1cm4ge3RyOiBcInRhYmxlLXJvd1wiLCB0ZDogXCJ0YWJsZS1jZWxsXCJ9W2VsLnRhZ05hbWUudG9Mb3dlckNhc2UoKV0gfHwgXCJibG9ja1wiXG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSlMiLCAiaW1wb3J0IHtcbiAgQkVGT1JFX1VOTE9BRF9MT0FERVJfVElNRU9VVCxcbiAgQ0hFQ0tBQkxFX0lOUFVUUyxcbiAgQ09OU0VDVVRJVkVfUkVMT0FEUyxcbiAgUEhYX0FVVE9fUkVDT1ZFUixcbiAgUEhYX0NPTVBPTkVOVCxcbiAgUEhYX0NPTk5FQ1RFRF9DTEFTUyxcbiAgUEhYX0RJU0FCTEVfV0lUSCxcbiAgUEhYX0RJU0FCTEVfV0lUSF9SRVNUT1JFLFxuICBQSFhfRElTQUJMRUQsXG4gIFBIWF9MT0FESU5HX0NMQVNTLFxuICBQSFhfRVZFTlRfQ0xBU1NFUyxcbiAgUEhYX0VSUk9SX0NMQVNTLFxuICBQSFhfQ0xJRU5UX0VSUk9SX0NMQVNTLFxuICBQSFhfU0VSVkVSX0VSUk9SX0NMQVNTLFxuICBQSFhfRkVFREJBQ0tfRk9SLFxuICBQSFhfSEFTX1NVQk1JVFRFRCxcbiAgUEhYX0hPT0ssXG4gIFBIWF9QQUdFX0xPQURJTkcsXG4gIFBIWF9QQVJFTlRfSUQsXG4gIFBIWF9QUk9HUkVTUyxcbiAgUEhYX1JFQURPTkxZLFxuICBQSFhfUkVGLFxuICBQSFhfUkVGX1NSQyxcbiAgUEhYX1JPT1RfSUQsXG4gIFBIWF9TRVNTSU9OLFxuICBQSFhfU1RBVElDLFxuICBQSFhfVFJBQ0tfU1RBVElDLFxuICBQSFhfVFJBQ0tfVVBMT0FEUyxcbiAgUEhYX1VQREFURSxcbiAgUEhYX1VQTE9BRF9SRUYsXG4gIFBIWF9WSUVXX1NFTEVDVE9SLFxuICBQSFhfTUFJTixcbiAgUEhYX01PVU5URUQsXG4gIFBVU0hfVElNRU9VVCxcbiAgUEhYX1ZJRVdQT1JUX1RPUCxcbiAgUEhYX1ZJRVdQT1JUX0JPVFRPTSxcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCJcblxuaW1wb3J0IHtcbiAgY2xvbmUsXG4gIGNsb3Nlc3RQaHhCaW5kaW5nLFxuICBpc0VtcHR5LFxuICBpc0VxdWFsT2JqLFxuICBsb2dFcnJvcixcbiAgbWF5YmUsXG4gIGlzQ2lkLFxufSBmcm9tIFwiLi91dGlsc1wiXG5cbmltcG9ydCBCcm93c2VyIGZyb20gXCIuL2Jyb3dzZXJcIlxuaW1wb3J0IERPTSBmcm9tIFwiLi9kb21cIlxuaW1wb3J0IERPTVBhdGNoIGZyb20gXCIuL2RvbV9wYXRjaFwiXG5pbXBvcnQgTGl2ZVVwbG9hZGVyIGZyb20gXCIuL2xpdmVfdXBsb2FkZXJcIlxuaW1wb3J0IFJlbmRlcmVkIGZyb20gXCIuL3JlbmRlcmVkXCJcbmltcG9ydCBWaWV3SG9vayBmcm9tIFwiLi92aWV3X2hvb2tcIlxuaW1wb3J0IEpTIGZyb20gXCIuL2pzXCJcblxubGV0IHNlcmlhbGl6ZUZvcm0gPSAoZm9ybSwgbWV0YWRhdGEsIG9ubHlOYW1lcyA9IFtdKSA9PiB7XG4gIGxldCB7c3VibWl0dGVyLCAuLi5tZXRhfSA9IG1ldGFkYXRhXG5cbiAgLy8gVE9ETzogUmVwbGFjZSB3aXRoIGBuZXcgRm9ybURhdGEoZm9ybSwgc3VibWl0dGVyKWAgd2hlbiBzdXBwb3J0ZWQgYnkgbGF0ZXN0IGJyb3dzZXJzLFxuICAvLyAgICAgICBhbmQgbWVudGlvbiBgZm9ybWRhdGEtc3VibWl0dGVyLXBvbHlmaWxsYCBpbiB0aGUgZG9jcy5cbiAgbGV0IGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKGZvcm0pXG5cbiAgLy8gVE9ETzogUmVtb3ZlIHdoZW4gRm9ybURhdGEgY29uc3RydWN0b3Igc3VwcG9ydHMgdGhlIHN1Ym1pdHRlciBhcmd1bWVudC5cbiAgaWYoc3VibWl0dGVyICYmIHN1Ym1pdHRlci5oYXNBdHRyaWJ1dGUoXCJuYW1lXCIpICYmIHN1Ym1pdHRlci5mb3JtICYmIHN1Ym1pdHRlci5mb3JtID09PSBmb3JtKXtcbiAgICBmb3JtRGF0YS5hcHBlbmQoc3VibWl0dGVyLm5hbWUsIHN1Ym1pdHRlci52YWx1ZSlcbiAgfVxuXG4gIGxldCB0b1JlbW92ZSA9IFtdXG5cbiAgZm9ybURhdGEuZm9yRWFjaCgodmFsLCBrZXksIF9pbmRleCkgPT4ge1xuICAgIGlmKHZhbCBpbnN0YW5jZW9mIEZpbGUpeyB0b1JlbW92ZS5wdXNoKGtleSkgfVxuICB9KVxuXG4gIC8vIENsZWFudXAgYWZ0ZXIgYnVpbGRpbmcgZmlsZURhdGFcbiAgdG9SZW1vdmUuZm9yRWFjaChrZXkgPT4gZm9ybURhdGEuZGVsZXRlKGtleSkpXG5cbiAgbGV0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoKVxuICBmb3IobGV0IFtrZXksIHZhbF0gb2YgZm9ybURhdGEuZW50cmllcygpKXtcbiAgICBpZihvbmx5TmFtZXMubGVuZ3RoID09PSAwIHx8IG9ubHlOYW1lcy5pbmRleE9mKGtleSkgPj0gMCl7XG4gICAgICBwYXJhbXMuYXBwZW5kKGtleSwgdmFsKVxuICAgIH1cbiAgfVxuICBmb3IobGV0IG1ldGFLZXkgaW4gbWV0YSl7IHBhcmFtcy5hcHBlbmQobWV0YUtleSwgbWV0YVttZXRhS2V5XSkgfVxuXG4gIHJldHVybiBwYXJhbXMudG9TdHJpbmcoKVxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWaWV3IHtcbiAgY29uc3RydWN0b3IoZWwsIGxpdmVTb2NrZXQsIHBhcmVudFZpZXcsIGZsYXNoLCBsaXZlUmVmZXJlcil7XG4gICAgdGhpcy5pc0RlYWQgPSBmYWxzZVxuICAgIHRoaXMubGl2ZVNvY2tldCA9IGxpdmVTb2NrZXRcbiAgICB0aGlzLmZsYXNoID0gZmxhc2hcbiAgICB0aGlzLnBhcmVudCA9IHBhcmVudFZpZXdcbiAgICB0aGlzLnJvb3QgPSBwYXJlbnRWaWV3ID8gcGFyZW50Vmlldy5yb290IDogdGhpc1xuICAgIHRoaXMuZWwgPSBlbFxuICAgIHRoaXMuaWQgPSB0aGlzLmVsLmlkXG4gICAgdGhpcy5yZWYgPSAwXG4gICAgdGhpcy5jaGlsZEpvaW5zID0gMFxuICAgIHRoaXMubG9hZGVyVGltZXIgPSBudWxsXG4gICAgdGhpcy5wZW5kaW5nRGlmZnMgPSBbXVxuICAgIHRoaXMucHJ1bmluZ0NJRHMgPSBbXVxuICAgIHRoaXMucmVkaXJlY3QgPSBmYWxzZVxuICAgIHRoaXMuaHJlZiA9IG51bGxcbiAgICB0aGlzLmpvaW5Db3VudCA9IHRoaXMucGFyZW50ID8gdGhpcy5wYXJlbnQuam9pbkNvdW50IC0gMSA6IDBcbiAgICB0aGlzLmpvaW5QZW5kaW5nID0gdHJ1ZVxuICAgIHRoaXMuZGVzdHJveWVkID0gZmFsc2VcbiAgICB0aGlzLmpvaW5DYWxsYmFjayA9IGZ1bmN0aW9uKG9uRG9uZSl7IG9uRG9uZSAmJiBvbkRvbmUoKSB9XG4gICAgdGhpcy5zdG9wQ2FsbGJhY2sgPSBmdW5jdGlvbigpeyB9XG4gICAgdGhpcy5wZW5kaW5nSm9pbk9wcyA9IHRoaXMucGFyZW50ID8gbnVsbCA6IFtdXG4gICAgdGhpcy52aWV3SG9va3MgPSB7fVxuICAgIHRoaXMudXBsb2FkZXJzID0ge31cbiAgICB0aGlzLmZvcm1TdWJtaXRzID0gW11cbiAgICB0aGlzLmNoaWxkcmVuID0gdGhpcy5wYXJlbnQgPyBudWxsIDoge31cbiAgICB0aGlzLnJvb3QuY2hpbGRyZW5bdGhpcy5pZF0gPSB7fVxuICAgIHRoaXMuY2hhbm5lbCA9IHRoaXMubGl2ZVNvY2tldC5jaGFubmVsKGBsdjoke3RoaXMuaWR9YCwgKCkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcmVkaXJlY3Q6IHRoaXMucmVkaXJlY3QgPyB0aGlzLmhyZWYgOiB1bmRlZmluZWQsXG4gICAgICAgIHVybDogdGhpcy5yZWRpcmVjdCA/IHVuZGVmaW5lZCA6IHRoaXMuaHJlZiB8fCB1bmRlZmluZWQsXG4gICAgICAgIHBhcmFtczogdGhpcy5jb25uZWN0UGFyYW1zKGxpdmVSZWZlcmVyKSxcbiAgICAgICAgc2Vzc2lvbjogdGhpcy5nZXRTZXNzaW9uKCksXG4gICAgICAgIHN0YXRpYzogdGhpcy5nZXRTdGF0aWMoKSxcbiAgICAgICAgZmxhc2g6IHRoaXMuZmxhc2gsXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIHNldEhyZWYoaHJlZil7IHRoaXMuaHJlZiA9IGhyZWYgfVxuXG4gIHNldFJlZGlyZWN0KGhyZWYpe1xuICAgIHRoaXMucmVkaXJlY3QgPSB0cnVlXG4gICAgdGhpcy5ocmVmID0gaHJlZlxuICB9XG5cbiAgaXNNYWluKCl7IHJldHVybiB0aGlzLmVsLmhhc0F0dHJpYnV0ZShQSFhfTUFJTikgfVxuXG4gIGNvbm5lY3RQYXJhbXMobGl2ZVJlZmVyZXIpe1xuICAgIGxldCBwYXJhbXMgPSB0aGlzLmxpdmVTb2NrZXQucGFyYW1zKHRoaXMuZWwpXG4gICAgbGV0IG1hbmlmZXN0ID1cbiAgICAgIERPTS5hbGwoZG9jdW1lbnQsIGBbJHt0aGlzLmJpbmRpbmcoUEhYX1RSQUNLX1NUQVRJQyl9XWApXG4gICAgICAgIC5tYXAobm9kZSA9PiBub2RlLnNyYyB8fCBub2RlLmhyZWYpLmZpbHRlcih1cmwgPT4gdHlwZW9mICh1cmwpID09PSBcInN0cmluZ1wiKVxuXG4gICAgaWYobWFuaWZlc3QubGVuZ3RoID4gMCl7IHBhcmFtc1tcIl90cmFja19zdGF0aWNcIl0gPSBtYW5pZmVzdCB9XG4gICAgcGFyYW1zW1wiX21vdW50c1wiXSA9IHRoaXMuam9pbkNvdW50XG4gICAgcGFyYW1zW1wiX2xpdmVfcmVmZXJlclwiXSA9IGxpdmVSZWZlcmVyXG5cbiAgICByZXR1cm4gcGFyYW1zXG4gIH1cblxuICBpc0Nvbm5lY3RlZCgpeyByZXR1cm4gdGhpcy5jaGFubmVsLmNhblB1c2goKSB9XG5cbiAgZ2V0U2Vzc2lvbigpeyByZXR1cm4gdGhpcy5lbC5nZXRBdHRyaWJ1dGUoUEhYX1NFU1NJT04pIH1cblxuICBnZXRTdGF0aWMoKXtcbiAgICBsZXQgdmFsID0gdGhpcy5lbC5nZXRBdHRyaWJ1dGUoUEhYX1NUQVRJQylcbiAgICByZXR1cm4gdmFsID09PSBcIlwiID8gbnVsbCA6IHZhbFxuICB9XG5cbiAgZGVzdHJveShjYWxsYmFjayA9IGZ1bmN0aW9uICgpeyB9KXtcbiAgICB0aGlzLmRlc3Ryb3lBbGxDaGlsZHJlbigpXG4gICAgdGhpcy5kZXN0cm95ZWQgPSB0cnVlXG4gICAgZGVsZXRlIHRoaXMucm9vdC5jaGlsZHJlblt0aGlzLmlkXVxuICAgIGlmKHRoaXMucGFyZW50KXsgZGVsZXRlIHRoaXMucm9vdC5jaGlsZHJlblt0aGlzLnBhcmVudC5pZF1bdGhpcy5pZF0gfVxuICAgIGNsZWFyVGltZW91dCh0aGlzLmxvYWRlclRpbWVyKVxuICAgIGxldCBvbkZpbmlzaGVkID0gKCkgPT4ge1xuICAgICAgY2FsbGJhY2soKVxuICAgICAgZm9yKGxldCBpZCBpbiB0aGlzLnZpZXdIb29rcyl7XG4gICAgICAgIHRoaXMuZGVzdHJveUhvb2sodGhpcy52aWV3SG9va3NbaWRdKVxuICAgICAgfVxuICAgIH1cblxuICAgIERPTS5tYXJrUGh4Q2hpbGREZXN0cm95ZWQodGhpcy5lbClcblxuICAgIHRoaXMubG9nKFwiZGVzdHJveWVkXCIsICgpID0+IFtcInRoZSBjaGlsZCBoYXMgYmVlbiByZW1vdmVkIGZyb20gdGhlIHBhcmVudFwiXSlcbiAgICB0aGlzLmNoYW5uZWwubGVhdmUoKVxuICAgICAgLnJlY2VpdmUoXCJva1wiLCBvbkZpbmlzaGVkKVxuICAgICAgLnJlY2VpdmUoXCJlcnJvclwiLCBvbkZpbmlzaGVkKVxuICAgICAgLnJlY2VpdmUoXCJ0aW1lb3V0XCIsIG9uRmluaXNoZWQpXG4gIH1cblxuICBzZXRDb250YWluZXJDbGFzc2VzKC4uLmNsYXNzZXMpe1xuICAgIHRoaXMuZWwuY2xhc3NMaXN0LnJlbW92ZShcbiAgICAgIFBIWF9DT05ORUNURURfQ0xBU1MsXG4gICAgICBQSFhfTE9BRElOR19DTEFTUyxcbiAgICAgIFBIWF9FUlJPUl9DTEFTUyxcbiAgICAgIFBIWF9DTElFTlRfRVJST1JfQ0xBU1MsXG4gICAgICBQSFhfU0VSVkVSX0VSUk9SX0NMQVNTXG4gICAgKVxuICAgIHRoaXMuZWwuY2xhc3NMaXN0LmFkZCguLi5jbGFzc2VzKVxuICB9XG5cbiAgc2hvd0xvYWRlcih0aW1lb3V0KXtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5sb2FkZXJUaW1lcilcbiAgICBpZih0aW1lb3V0KXtcbiAgICAgIHRoaXMubG9hZGVyVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHRoaXMuc2hvd0xvYWRlcigpLCB0aW1lb3V0KVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3IobGV0IGlkIGluIHRoaXMudmlld0hvb2tzKXsgdGhpcy52aWV3SG9va3NbaWRdLl9fZGlzY29ubmVjdGVkKCkgfVxuICAgICAgdGhpcy5zZXRDb250YWluZXJDbGFzc2VzKFBIWF9MT0FESU5HX0NMQVNTKVxuICAgIH1cbiAgfVxuXG4gIGV4ZWNBbGwoYmluZGluZyl7XG4gICAgRE9NLmFsbCh0aGlzLmVsLCBgWyR7YmluZGluZ31dYCwgZWwgPT4gdGhpcy5saXZlU29ja2V0LmV4ZWNKUyhlbCwgZWwuZ2V0QXR0cmlidXRlKGJpbmRpbmcpKSlcbiAgfVxuXG4gIGhpZGVMb2FkZXIoKXtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5sb2FkZXJUaW1lcilcbiAgICB0aGlzLnNldENvbnRhaW5lckNsYXNzZXMoUEhYX0NPTk5FQ1RFRF9DTEFTUylcbiAgICB0aGlzLmV4ZWNBbGwodGhpcy5iaW5kaW5nKFwiY29ubmVjdGVkXCIpKVxuICB9XG5cbiAgdHJpZ2dlclJlY29ubmVjdGVkKCl7XG4gICAgZm9yKGxldCBpZCBpbiB0aGlzLnZpZXdIb29rcyl7IHRoaXMudmlld0hvb2tzW2lkXS5fX3JlY29ubmVjdGVkKCkgfVxuICB9XG5cbiAgbG9nKGtpbmQsIG1zZ0NhbGxiYWNrKXtcbiAgICB0aGlzLmxpdmVTb2NrZXQubG9nKHRoaXMsIGtpbmQsIG1zZ0NhbGxiYWNrKVxuICB9XG5cbiAgdHJhbnNpdGlvbih0aW1lLCBvblN0YXJ0LCBvbkRvbmUgPSBmdW5jdGlvbigpe30pe1xuICAgIHRoaXMubGl2ZVNvY2tldC50cmFuc2l0aW9uKHRpbWUsIG9uU3RhcnQsIG9uRG9uZSlcbiAgfVxuXG4gIHdpdGhpblRhcmdldHMocGh4VGFyZ2V0LCBjYWxsYmFjayl7XG4gICAgaWYocGh4VGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgfHwgcGh4VGFyZ2V0IGluc3RhbmNlb2YgU1ZHRWxlbWVudCl7XG4gICAgICByZXR1cm4gdGhpcy5saXZlU29ja2V0Lm93bmVyKHBoeFRhcmdldCwgdmlldyA9PiBjYWxsYmFjayh2aWV3LCBwaHhUYXJnZXQpKVxuICAgIH1cblxuICAgIGlmKGlzQ2lkKHBoeFRhcmdldCkpe1xuICAgICAgbGV0IHRhcmdldHMgPSBET00uZmluZENvbXBvbmVudE5vZGVMaXN0KHRoaXMuZWwsIHBoeFRhcmdldClcbiAgICAgIGlmKHRhcmdldHMubGVuZ3RoID09PSAwKXtcbiAgICAgICAgbG9nRXJyb3IoYG5vIGNvbXBvbmVudCBmb3VuZCBtYXRjaGluZyBwaHgtdGFyZ2V0IG9mICR7cGh4VGFyZ2V0fWApXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYWxsYmFjayh0aGlzLCBwYXJzZUludChwaHhUYXJnZXQpKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgdGFyZ2V0cyA9IEFycmF5LmZyb20oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChwaHhUYXJnZXQpKVxuICAgICAgaWYodGFyZ2V0cy5sZW5ndGggPT09IDApeyBsb2dFcnJvcihgbm90aGluZyBmb3VuZCBtYXRjaGluZyB0aGUgcGh4LXRhcmdldCBzZWxlY3RvciBcIiR7cGh4VGFyZ2V0fVwiYCkgfVxuICAgICAgdGFyZ2V0cy5mb3JFYWNoKHRhcmdldCA9PiB0aGlzLmxpdmVTb2NrZXQub3duZXIodGFyZ2V0LCB2aWV3ID0+IGNhbGxiYWNrKHZpZXcsIHRhcmdldCkpKVxuICAgIH1cbiAgfVxuXG4gIGFwcGx5RGlmZih0eXBlLCByYXdEaWZmLCBjYWxsYmFjayl7XG4gICAgdGhpcy5sb2codHlwZSwgKCkgPT4gW1wiXCIsIGNsb25lKHJhd0RpZmYpXSlcbiAgICBsZXQge2RpZmYsIHJlcGx5LCBldmVudHMsIHRpdGxlfSA9IFJlbmRlcmVkLmV4dHJhY3QocmF3RGlmZilcbiAgICBjYWxsYmFjayh7ZGlmZiwgcmVwbHksIGV2ZW50c30pXG4gICAgaWYodGl0bGUpeyB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IERPTS5wdXRUaXRsZSh0aXRsZSkpIH1cbiAgfVxuXG4gIG9uSm9pbihyZXNwKXtcbiAgICBsZXQge3JlbmRlcmVkLCBjb250YWluZXJ9ID0gcmVzcFxuICAgIGlmKGNvbnRhaW5lcil7XG4gICAgICBsZXQgW3RhZywgYXR0cnNdID0gY29udGFpbmVyXG4gICAgICB0aGlzLmVsID0gRE9NLnJlcGxhY2VSb290Q29udGFpbmVyKHRoaXMuZWwsIHRhZywgYXR0cnMpXG4gICAgfVxuICAgIHRoaXMuY2hpbGRKb2lucyA9IDBcbiAgICB0aGlzLmpvaW5QZW5kaW5nID0gdHJ1ZVxuICAgIHRoaXMuZmxhc2ggPSBudWxsXG5cbiAgICBCcm93c2VyLmRyb3BMb2NhbCh0aGlzLmxpdmVTb2NrZXQubG9jYWxTdG9yYWdlLCB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUsIENPTlNFQ1VUSVZFX1JFTE9BRFMpXG4gICAgdGhpcy5hcHBseURpZmYoXCJtb3VudFwiLCByZW5kZXJlZCwgKHtkaWZmLCBldmVudHN9KSA9PiB7XG4gICAgICB0aGlzLnJlbmRlcmVkID0gbmV3IFJlbmRlcmVkKHRoaXMuaWQsIGRpZmYpXG4gICAgICBsZXQgW2h0bWwsIHN0cmVhbXNdID0gdGhpcy5yZW5kZXJDb250YWluZXIobnVsbCwgXCJqb2luXCIpXG4gICAgICB0aGlzLmRyb3BQZW5kaW5nUmVmcygpXG4gICAgICBsZXQgZm9ybXMgPSB0aGlzLmZvcm1zRm9yUmVjb3ZlcnkoaHRtbClcbiAgICAgIHRoaXMuam9pbkNvdW50KytcblxuICAgICAgaWYoZm9ybXMubGVuZ3RoID4gMCl7XG4gICAgICAgIGZvcm1zLmZvckVhY2goKFtmb3JtLCBuZXdGb3JtLCBuZXdDaWRdLCBpKSA9PiB7XG4gICAgICAgICAgdGhpcy5wdXNoRm9ybVJlY292ZXJ5KGZvcm0sIG5ld0NpZCwgcmVzcCA9PiB7XG4gICAgICAgICAgICBpZihpID09PSBmb3Jtcy5sZW5ndGggLSAxKXtcbiAgICAgICAgICAgICAgdGhpcy5vbkpvaW5Db21wbGV0ZShyZXNwLCBodG1sLCBzdHJlYW1zLCBldmVudHMpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgfSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMub25Kb2luQ29tcGxldGUocmVzcCwgaHRtbCwgc3RyZWFtcywgZXZlbnRzKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICBkcm9wUGVuZGluZ1JlZnMoKXtcbiAgICBET00uYWxsKGRvY3VtZW50LCBgWyR7UEhYX1JFRl9TUkN9PVwiJHt0aGlzLmlkfVwiXVske1BIWF9SRUZ9XWAsIGVsID0+IHtcbiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShQSFhfUkVGKVxuICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKFBIWF9SRUZfU1JDKVxuICAgIH0pXG4gIH1cblxuICBvbkpvaW5Db21wbGV0ZSh7bGl2ZV9wYXRjaH0sIGh0bWwsIHN0cmVhbXMsIGV2ZW50cyl7XG4gICAgLy8gSW4gb3JkZXIgdG8gcHJvdmlkZSBhIGJldHRlciBleHBlcmllbmNlLCB3ZSB3YW50IHRvIGpvaW5cbiAgICAvLyBhbGwgTGl2ZVZpZXdzIGZpcnN0IGFuZCBvbmx5IHRoZW4gYXBwbHkgdGhlaXIgcGF0Y2hlcy5cbiAgICBpZih0aGlzLmpvaW5Db3VudCA+IDEgfHwgKHRoaXMucGFyZW50ICYmICF0aGlzLnBhcmVudC5pc0pvaW5QZW5kaW5nKCkpKXtcbiAgICAgIHJldHVybiB0aGlzLmFwcGx5Sm9pblBhdGNoKGxpdmVfcGF0Y2gsIGh0bWwsIHN0cmVhbXMsIGV2ZW50cylcbiAgICB9XG5cbiAgICAvLyBPbmUgZG93bnNpZGUgb2YgdGhpcyBhcHByb2FjaCBpcyB0aGF0IHdlIG5lZWQgdG8gZmluZCBwaHhDaGlsZHJlblxuICAgIC8vIGluIHRoZSBodG1sIGZyYWdtZW50LCBpbnN0ZWFkIG9mIGRpcmVjdGx5IG9uIHRoZSBET00uIFRoZSBmcmFnbWVudFxuICAgIC8vIGFsc28gZG9lcyBub3QgaW5jbHVkZSBQSFhfU1RBVElDLCBzbyB3ZSBuZWVkIHRvIGNvcHkgaXQgb3ZlciBmcm9tXG4gICAgLy8gdGhlIERPTS5cbiAgICBsZXQgbmV3Q2hpbGRyZW4gPSBET00uZmluZFBoeENoaWxkcmVuSW5GcmFnbWVudChodG1sLCB0aGlzLmlkKS5maWx0ZXIodG9FbCA9PiB7XG4gICAgICBsZXQgZnJvbUVsID0gdG9FbC5pZCAmJiB0aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoYFtpZD1cIiR7dG9FbC5pZH1cIl1gKVxuICAgICAgbGV0IHBoeFN0YXRpYyA9IGZyb21FbCAmJiBmcm9tRWwuZ2V0QXR0cmlidXRlKFBIWF9TVEFUSUMpXG4gICAgICBpZihwaHhTdGF0aWMpeyB0b0VsLnNldEF0dHJpYnV0ZShQSFhfU1RBVElDLCBwaHhTdGF0aWMpIH1cbiAgICAgIHJldHVybiB0aGlzLmpvaW5DaGlsZCh0b0VsKVxuICAgIH0pXG5cbiAgICBpZihuZXdDaGlsZHJlbi5sZW5ndGggPT09IDApe1xuICAgICAgaWYodGhpcy5wYXJlbnQpe1xuICAgICAgICB0aGlzLnJvb3QucGVuZGluZ0pvaW5PcHMucHVzaChbdGhpcywgKCkgPT4gdGhpcy5hcHBseUpvaW5QYXRjaChsaXZlX3BhdGNoLCBodG1sLCBzdHJlYW1zLCBldmVudHMpXSlcbiAgICAgICAgdGhpcy5wYXJlbnQuYWNrSm9pbih0aGlzKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5vbkFsbENoaWxkSm9pbnNDb21wbGV0ZSgpXG4gICAgICAgIHRoaXMuYXBwbHlKb2luUGF0Y2gobGl2ZV9wYXRjaCwgaHRtbCwgc3RyZWFtcywgZXZlbnRzKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJvb3QucGVuZGluZ0pvaW5PcHMucHVzaChbdGhpcywgKCkgPT4gdGhpcy5hcHBseUpvaW5QYXRjaChsaXZlX3BhdGNoLCBodG1sLCBzdHJlYW1zLCBldmVudHMpXSlcbiAgICB9XG4gIH1cblxuICBhdHRhY2hUcnVlRG9jRWwoKXtcbiAgICB0aGlzLmVsID0gRE9NLmJ5SWQodGhpcy5pZClcbiAgICB0aGlzLmVsLnNldEF0dHJpYnV0ZShQSFhfUk9PVF9JRCwgdGhpcy5yb290LmlkKVxuICB9XG5cbiAgZXhlY05ld01vdW50ZWQoKXtcbiAgICBsZXQgcGh4Vmlld3BvcnRUb3AgPSB0aGlzLmJpbmRpbmcoUEhYX1ZJRVdQT1JUX1RPUClcbiAgICBsZXQgcGh4Vmlld3BvcnRCb3R0b20gPSB0aGlzLmJpbmRpbmcoUEhYX1ZJRVdQT1JUX0JPVFRPTSlcbiAgICBET00uYWxsKHRoaXMuZWwsIGBbJHtwaHhWaWV3cG9ydFRvcH1dLCBbJHtwaHhWaWV3cG9ydEJvdHRvbX1dYCwgaG9va0VsID0+IHtcbiAgICAgIERPTS5tYXliZUFkZFByaXZhdGVIb29rcyhob29rRWwsIHBoeFZpZXdwb3J0VG9wLCBwaHhWaWV3cG9ydEJvdHRvbSlcbiAgICAgIHRoaXMubWF5YmVBZGROZXdIb29rKGhvb2tFbClcbiAgICB9KVxuICAgIERPTS5hbGwodGhpcy5lbCwgYFske3RoaXMuYmluZGluZyhQSFhfSE9PSyl9XSwgW2RhdGEtcGh4LSR7UEhYX0hPT0t9XWAsIGhvb2tFbCA9PiB7XG4gICAgICB0aGlzLm1heWJlQWRkTmV3SG9vayhob29rRWwpXG4gICAgfSlcbiAgICBET00uYWxsKHRoaXMuZWwsIGBbJHt0aGlzLmJpbmRpbmcoUEhYX01PVU5URUQpfV1gLCBlbCA9PiB0aGlzLm1heWJlTW91bnRlZChlbCkpXG4gIH1cblxuICBhcHBseUpvaW5QYXRjaChsaXZlX3BhdGNoLCBodG1sLCBzdHJlYW1zLCBldmVudHMpe1xuICAgIHRoaXMuYXR0YWNoVHJ1ZURvY0VsKClcbiAgICBsZXQgcGF0Y2ggPSBuZXcgRE9NUGF0Y2godGhpcywgdGhpcy5lbCwgdGhpcy5pZCwgaHRtbCwgc3RyZWFtcywgbnVsbClcbiAgICBwYXRjaC5tYXJrUHJ1bmFibGVDb250ZW50Rm9yUmVtb3ZhbCgpXG4gICAgdGhpcy5wZXJmb3JtUGF0Y2gocGF0Y2gsIGZhbHNlKVxuICAgIHRoaXMuam9pbk5ld0NoaWxkcmVuKClcbiAgICB0aGlzLmV4ZWNOZXdNb3VudGVkKClcblxuICAgIHRoaXMuam9pblBlbmRpbmcgPSBmYWxzZVxuICAgIHRoaXMubGl2ZVNvY2tldC5kaXNwYXRjaEV2ZW50cyhldmVudHMpXG4gICAgdGhpcy5hcHBseVBlbmRpbmdVcGRhdGVzKClcblxuICAgIGlmKGxpdmVfcGF0Y2gpe1xuICAgICAgbGV0IHtraW5kLCB0b30gPSBsaXZlX3BhdGNoXG4gICAgICB0aGlzLmxpdmVTb2NrZXQuaGlzdG9yeVBhdGNoKHRvLCBraW5kKVxuICAgIH1cbiAgICB0aGlzLmhpZGVMb2FkZXIoKVxuICAgIGlmKHRoaXMuam9pbkNvdW50ID4gMSl7IHRoaXMudHJpZ2dlclJlY29ubmVjdGVkKCkgfVxuICAgIHRoaXMuc3RvcENhbGxiYWNrKClcbiAgfVxuXG4gIHRyaWdnZXJCZWZvcmVVcGRhdGVIb29rKGZyb21FbCwgdG9FbCl7XG4gICAgdGhpcy5saXZlU29ja2V0LnRyaWdnZXJET00oXCJvbkJlZm9yZUVsVXBkYXRlZFwiLCBbZnJvbUVsLCB0b0VsXSlcbiAgICBsZXQgaG9vayA9IHRoaXMuZ2V0SG9vayhmcm9tRWwpXG4gICAgbGV0IGlzSWdub3JlZCA9IGhvb2sgJiYgRE9NLmlzSWdub3JlZChmcm9tRWwsIHRoaXMuYmluZGluZyhQSFhfVVBEQVRFKSlcbiAgICBpZihob29rICYmICFmcm9tRWwuaXNFcXVhbE5vZGUodG9FbCkgJiYgIShpc0lnbm9yZWQgJiYgaXNFcXVhbE9iaihmcm9tRWwuZGF0YXNldCwgdG9FbC5kYXRhc2V0KSkpe1xuICAgICAgaG9vay5fX2JlZm9yZVVwZGF0ZSgpXG4gICAgICByZXR1cm4gaG9va1xuICAgIH1cbiAgfVxuXG4gIG1heWJlTW91bnRlZChlbCl7XG4gICAgbGV0IHBoeE1vdW50ZWQgPSBlbC5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFBIWF9NT1VOVEVEKSlcbiAgICBsZXQgaGFzQmVlbkludm9rZWQgPSBwaHhNb3VudGVkICYmIERPTS5wcml2YXRlKGVsLCBcIm1vdW50ZWRcIilcbiAgICBpZihwaHhNb3VudGVkICYmICFoYXNCZWVuSW52b2tlZCl7XG4gICAgICB0aGlzLmxpdmVTb2NrZXQuZXhlY0pTKGVsLCBwaHhNb3VudGVkKVxuICAgICAgRE9NLnB1dFByaXZhdGUoZWwsIFwibW91bnRlZFwiLCB0cnVlKVxuICAgIH1cbiAgfVxuXG4gIG1heWJlQWRkTmV3SG9vayhlbCwgZm9yY2Upe1xuICAgIGxldCBuZXdIb29rID0gdGhpcy5hZGRIb29rKGVsKVxuICAgIGlmKG5ld0hvb2speyBuZXdIb29rLl9fbW91bnRlZCgpIH1cbiAgfVxuXG4gIHBlcmZvcm1QYXRjaChwYXRjaCwgcHJ1bmVDaWRzKXtcbiAgICBsZXQgcmVtb3ZlZEVscyA9IFtdXG4gICAgbGV0IHBoeENoaWxkcmVuQWRkZWQgPSBmYWxzZVxuICAgIGxldCB1cGRhdGVkSG9va0lkcyA9IG5ldyBTZXQoKVxuXG4gICAgcGF0Y2guYWZ0ZXIoXCJhZGRlZFwiLCBlbCA9PiB7XG4gICAgICB0aGlzLmxpdmVTb2NrZXQudHJpZ2dlckRPTShcIm9uTm9kZUFkZGVkXCIsIFtlbF0pXG4gICAgICB0aGlzLm1heWJlQWRkTmV3SG9vayhlbClcbiAgICAgIGlmKGVsLmdldEF0dHJpYnV0ZSl7IHRoaXMubWF5YmVNb3VudGVkKGVsKSB9XG4gICAgfSlcblxuICAgIHBhdGNoLmFmdGVyKFwicGh4Q2hpbGRBZGRlZFwiLCBlbCA9PiB7XG4gICAgICBpZihET00uaXNQaHhTdGlja3koZWwpKXtcbiAgICAgICAgdGhpcy5saXZlU29ja2V0LmpvaW5Sb290Vmlld3MoKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGh4Q2hpbGRyZW5BZGRlZCA9IHRydWVcbiAgICAgIH1cbiAgICB9KVxuXG4gICAgcGF0Y2guYmVmb3JlKFwidXBkYXRlZFwiLCAoZnJvbUVsLCB0b0VsKSA9PiB7XG4gICAgICBsZXQgaG9vayA9IHRoaXMudHJpZ2dlckJlZm9yZVVwZGF0ZUhvb2soZnJvbUVsLCB0b0VsKVxuICAgICAgaWYoaG9vayl7IHVwZGF0ZWRIb29rSWRzLmFkZChmcm9tRWwuaWQpIH1cbiAgICB9KVxuXG4gICAgcGF0Y2guYWZ0ZXIoXCJ1cGRhdGVkXCIsIGVsID0+IHtcbiAgICAgIGlmKHVwZGF0ZWRIb29rSWRzLmhhcyhlbC5pZCkpeyB0aGlzLmdldEhvb2soZWwpLl9fdXBkYXRlZCgpIH1cbiAgICB9KVxuXG4gICAgcGF0Y2guYWZ0ZXIoXCJkaXNjYXJkZWRcIiwgKGVsKSA9PiB7XG4gICAgICBpZihlbC5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpeyByZW1vdmVkRWxzLnB1c2goZWwpIH1cbiAgICB9KVxuXG4gICAgcGF0Y2guYWZ0ZXIoXCJ0cmFuc2l0aW9uc0Rpc2NhcmRlZFwiLCBlbHMgPT4gdGhpcy5hZnRlckVsZW1lbnRzUmVtb3ZlZChlbHMsIHBydW5lQ2lkcykpXG4gICAgcGF0Y2gucGVyZm9ybSgpXG4gICAgdGhpcy5hZnRlckVsZW1lbnRzUmVtb3ZlZChyZW1vdmVkRWxzLCBwcnVuZUNpZHMpXG5cbiAgICByZXR1cm4gcGh4Q2hpbGRyZW5BZGRlZFxuICB9XG5cbiAgYWZ0ZXJFbGVtZW50c1JlbW92ZWQoZWxlbWVudHMsIHBydW5lQ2lkcyl7XG4gICAgbGV0IGRlc3Ryb3llZENJRHMgPSBbXVxuICAgIGVsZW1lbnRzLmZvckVhY2gocGFyZW50ID0+IHtcbiAgICAgIGxldCBjb21wb25lbnRzID0gRE9NLmFsbChwYXJlbnQsIGBbJHtQSFhfQ09NUE9ORU5UfV1gKVxuICAgICAgbGV0IGhvb2tzID0gRE9NLmFsbChwYXJlbnQsIGBbJHt0aGlzLmJpbmRpbmcoUEhYX0hPT0spfV1gKVxuICAgICAgY29tcG9uZW50cy5jb25jYXQocGFyZW50KS5mb3JFYWNoKGVsID0+IHtcbiAgICAgICAgbGV0IGNpZCA9IHRoaXMuY29tcG9uZW50SUQoZWwpXG4gICAgICAgIGlmKGlzQ2lkKGNpZCkgJiYgZGVzdHJveWVkQ0lEcy5pbmRleE9mKGNpZCkgPT09IC0xKXsgZGVzdHJveWVkQ0lEcy5wdXNoKGNpZCkgfVxuICAgICAgfSlcbiAgICAgIGhvb2tzLmNvbmNhdChwYXJlbnQpLmZvckVhY2goaG9va0VsID0+IHtcbiAgICAgICAgbGV0IGhvb2sgPSB0aGlzLmdldEhvb2soaG9va0VsKVxuICAgICAgICBob29rICYmIHRoaXMuZGVzdHJveUhvb2soaG9vaylcbiAgICAgIH0pXG4gICAgfSlcbiAgICAvLyBXZSBzaG91bGQgbm90IHBydW5lQ2lkcyBvbiBqb2lucy4gT3RoZXJ3aXNlLCBpbiBjYXNlIG9mXG4gICAgLy8gcmVqb2lucywgd2UgbWF5IG5vdGlmeSBjaWRzIHRoYXQgbm8gbG9uZ2VyIGJlbG9uZyB0byB0aGVcbiAgICAvLyBjdXJyZW50IExpdmVWaWV3IHRvIGJlIHJlbW92ZWQuXG4gICAgaWYocHJ1bmVDaWRzKXtcbiAgICAgIHRoaXMubWF5YmVQdXNoQ29tcG9uZW50c0Rlc3Ryb3llZChkZXN0cm95ZWRDSURzKVxuICAgIH1cbiAgfVxuXG4gIGpvaW5OZXdDaGlsZHJlbigpe1xuICAgIERPTS5maW5kUGh4Q2hpbGRyZW4odGhpcy5lbCwgdGhpcy5pZCkuZm9yRWFjaChlbCA9PiB0aGlzLmpvaW5DaGlsZChlbCkpXG4gIH1cblxuICBnZXRDaGlsZEJ5SWQoaWQpeyByZXR1cm4gdGhpcy5yb290LmNoaWxkcmVuW3RoaXMuaWRdW2lkXSB9XG5cbiAgZ2V0RGVzY2VuZGVudEJ5RWwoZWwpe1xuICAgIGlmKGVsLmlkID09PSB0aGlzLmlkKXtcbiAgICAgIHJldHVybiB0aGlzXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmNoaWxkcmVuW2VsLmdldEF0dHJpYnV0ZShQSFhfUEFSRU5UX0lEKV1bZWwuaWRdXG4gICAgfVxuICB9XG5cbiAgZGVzdHJveURlc2NlbmRlbnQoaWQpe1xuICAgIGZvcihsZXQgcGFyZW50SWQgaW4gdGhpcy5yb290LmNoaWxkcmVuKXtcbiAgICAgIGZvcihsZXQgY2hpbGRJZCBpbiB0aGlzLnJvb3QuY2hpbGRyZW5bcGFyZW50SWRdKXtcbiAgICAgICAgaWYoY2hpbGRJZCA9PT0gaWQpeyByZXR1cm4gdGhpcy5yb290LmNoaWxkcmVuW3BhcmVudElkXVtjaGlsZElkXS5kZXN0cm95KCkgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGpvaW5DaGlsZChlbCl7XG4gICAgbGV0IGNoaWxkID0gdGhpcy5nZXRDaGlsZEJ5SWQoZWwuaWQpXG4gICAgaWYoIWNoaWxkKXtcbiAgICAgIGxldCB2aWV3ID0gbmV3IFZpZXcoZWwsIHRoaXMubGl2ZVNvY2tldCwgdGhpcylcbiAgICAgIHRoaXMucm9vdC5jaGlsZHJlblt0aGlzLmlkXVt2aWV3LmlkXSA9IHZpZXdcbiAgICAgIHZpZXcuam9pbigpXG4gICAgICB0aGlzLmNoaWxkSm9pbnMrK1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH1cblxuICBpc0pvaW5QZW5kaW5nKCl7IHJldHVybiB0aGlzLmpvaW5QZW5kaW5nIH1cblxuICBhY2tKb2luKF9jaGlsZCl7XG4gICAgdGhpcy5jaGlsZEpvaW5zLS1cblxuICAgIGlmKHRoaXMuY2hpbGRKb2lucyA9PT0gMCl7XG4gICAgICBpZih0aGlzLnBhcmVudCl7XG4gICAgICAgIHRoaXMucGFyZW50LmFja0pvaW4odGhpcylcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMub25BbGxDaGlsZEpvaW5zQ29tcGxldGUoKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG9uQWxsQ2hpbGRKb2luc0NvbXBsZXRlKCl7XG4gICAgdGhpcy5qb2luQ2FsbGJhY2soKCkgPT4ge1xuICAgICAgdGhpcy5wZW5kaW5nSm9pbk9wcy5mb3JFYWNoKChbdmlldywgb3BdKSA9PiB7XG4gICAgICAgIGlmKCF2aWV3LmlzRGVzdHJveWVkKCkpeyBvcCgpIH1cbiAgICAgIH0pXG4gICAgICB0aGlzLnBlbmRpbmdKb2luT3BzID0gW11cbiAgICB9KVxuICB9XG5cbiAgdXBkYXRlKGRpZmYsIGV2ZW50cyl7XG4gICAgaWYodGhpcy5pc0pvaW5QZW5kaW5nKCkgfHwgKHRoaXMubGl2ZVNvY2tldC5oYXNQZW5kaW5nTGluaygpICYmIHRoaXMucm9vdC5pc01haW4oKSkpe1xuICAgICAgcmV0dXJuIHRoaXMucGVuZGluZ0RpZmZzLnB1c2goe2RpZmYsIGV2ZW50c30pXG4gICAgfVxuXG4gICAgdGhpcy5yZW5kZXJlZC5tZXJnZURpZmYoZGlmZilcbiAgICBsZXQgcGh4Q2hpbGRyZW5BZGRlZCA9IGZhbHNlXG5cbiAgICAvLyBXaGVuIHRoZSBkaWZmIG9ubHkgY29udGFpbnMgY29tcG9uZW50IGRpZmZzLCB0aGVuIHdhbGsgY29tcG9uZW50c1xuICAgIC8vIGFuZCBwYXRjaCBvbmx5IHRoZSBwYXJlbnQgY29tcG9uZW50IGNvbnRhaW5lcnMgZm91bmQgaW4gdGhlIGRpZmYuXG4gICAgLy8gT3RoZXJ3aXNlLCBwYXRjaCBlbnRpcmUgTFYgY29udGFpbmVyLlxuICAgIGlmKHRoaXMucmVuZGVyZWQuaXNDb21wb25lbnRPbmx5RGlmZihkaWZmKSl7XG4gICAgICB0aGlzLmxpdmVTb2NrZXQudGltZShcImNvbXBvbmVudCBwYXRjaCBjb21wbGV0ZVwiLCAoKSA9PiB7XG4gICAgICAgIGxldCBwYXJlbnRDaWRzID0gRE9NLmZpbmRQYXJlbnRDSURzKHRoaXMuZWwsIHRoaXMucmVuZGVyZWQuY29tcG9uZW50Q0lEcyhkaWZmKSlcbiAgICAgICAgcGFyZW50Q2lkcy5mb3JFYWNoKHBhcmVudENJRCA9PiB7XG4gICAgICAgICAgaWYodGhpcy5jb21wb25lbnRQYXRjaCh0aGlzLnJlbmRlcmVkLmdldENvbXBvbmVudChkaWZmLCBwYXJlbnRDSUQpLCBwYXJlbnRDSUQpKXsgcGh4Q2hpbGRyZW5BZGRlZCA9IHRydWUgfVxuICAgICAgICB9KVxuICAgICAgfSlcbiAgICB9IGVsc2UgaWYoIWlzRW1wdHkoZGlmZikpe1xuICAgICAgdGhpcy5saXZlU29ja2V0LnRpbWUoXCJmdWxsIHBhdGNoIGNvbXBsZXRlXCIsICgpID0+IHtcbiAgICAgICAgbGV0IFtodG1sLCBzdHJlYW1zXSA9IHRoaXMucmVuZGVyQ29udGFpbmVyKGRpZmYsIFwidXBkYXRlXCIpXG4gICAgICAgIGxldCBwYXRjaCA9IG5ldyBET01QYXRjaCh0aGlzLCB0aGlzLmVsLCB0aGlzLmlkLCBodG1sLCBzdHJlYW1zLCBudWxsKVxuICAgICAgICBwaHhDaGlsZHJlbkFkZGVkID0gdGhpcy5wZXJmb3JtUGF0Y2gocGF0Y2gsIHRydWUpXG4gICAgICB9KVxuICAgIH1cblxuICAgIHRoaXMubGl2ZVNvY2tldC5kaXNwYXRjaEV2ZW50cyhldmVudHMpXG4gICAgaWYocGh4Q2hpbGRyZW5BZGRlZCl7IHRoaXMuam9pbk5ld0NoaWxkcmVuKCkgfVxuICB9XG5cbiAgcmVuZGVyQ29udGFpbmVyKGRpZmYsIGtpbmQpe1xuICAgIHJldHVybiB0aGlzLmxpdmVTb2NrZXQudGltZShgdG9TdHJpbmcgZGlmZiAoJHtraW5kfSlgLCAoKSA9PiB7XG4gICAgICBsZXQgdGFnID0gdGhpcy5lbC50YWdOYW1lXG4gICAgICAvLyBEb24ndCBza2lwIGFueSBjb21wb25lbnQgaW4gdGhlIGRpZmYgbm9yIGFueSBtYXJrZWQgYXMgcHJ1bmVkXG4gICAgICAvLyAoYXMgdGhleSBtYXkgaGF2ZSBiZWVuIGFkZGVkIGJhY2spXG4gICAgICBsZXQgY2lkcyA9IGRpZmYgPyB0aGlzLnJlbmRlcmVkLmNvbXBvbmVudENJRHMoZGlmZikuY29uY2F0KHRoaXMucHJ1bmluZ0NJRHMpIDogbnVsbFxuICAgICAgbGV0IFtodG1sLCBzdHJlYW1zXSA9IHRoaXMucmVuZGVyZWQudG9TdHJpbmcoY2lkcylcbiAgICAgIHJldHVybiBbYDwke3RhZ30+JHtodG1sfTwvJHt0YWd9PmAsIHN0cmVhbXNdXG4gICAgfSlcbiAgfVxuXG4gIGNvbXBvbmVudFBhdGNoKGRpZmYsIGNpZCl7XG4gICAgaWYoaXNFbXB0eShkaWZmKSkgcmV0dXJuIGZhbHNlXG4gICAgbGV0IFtodG1sLCBzdHJlYW1zXSA9IHRoaXMucmVuZGVyZWQuY29tcG9uZW50VG9TdHJpbmcoY2lkKVxuICAgIGxldCBwYXRjaCA9IG5ldyBET01QYXRjaCh0aGlzLCB0aGlzLmVsLCB0aGlzLmlkLCBodG1sLCBzdHJlYW1zLCBjaWQpXG4gICAgbGV0IGNoaWxkcmVuQWRkZWQgPSB0aGlzLnBlcmZvcm1QYXRjaChwYXRjaCwgdHJ1ZSlcbiAgICByZXR1cm4gY2hpbGRyZW5BZGRlZFxuICB9XG5cbiAgZ2V0SG9vayhlbCl7IHJldHVybiB0aGlzLnZpZXdIb29rc1tWaWV3SG9vay5lbGVtZW50SUQoZWwpXSB9XG5cbiAgYWRkSG9vayhlbCl7XG4gICAgaWYoVmlld0hvb2suZWxlbWVudElEKGVsKSB8fCAhZWwuZ2V0QXR0cmlidXRlKXsgcmV0dXJuIH1cbiAgICBsZXQgaG9va05hbWUgPSBlbC5nZXRBdHRyaWJ1dGUoYGRhdGEtcGh4LSR7UEhYX0hPT0t9YCkgfHwgZWwuZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhQSFhfSE9PSykpXG4gICAgaWYoaG9va05hbWUgJiYgIXRoaXMub3duc0VsZW1lbnQoZWwpKXsgcmV0dXJuIH1cbiAgICBsZXQgY2FsbGJhY2tzID0gdGhpcy5saXZlU29ja2V0LmdldEhvb2tDYWxsYmFja3MoaG9va05hbWUpXG5cbiAgICBpZihjYWxsYmFja3Mpe1xuICAgICAgaWYoIWVsLmlkKXsgbG9nRXJyb3IoYG5vIERPTSBJRCBmb3IgaG9vayBcIiR7aG9va05hbWV9XCIuIEhvb2tzIHJlcXVpcmUgYSB1bmlxdWUgSUQgb24gZWFjaCBlbGVtZW50LmAsIGVsKSB9XG4gICAgICBsZXQgaG9vayA9IG5ldyBWaWV3SG9vayh0aGlzLCBlbCwgY2FsbGJhY2tzKVxuICAgICAgdGhpcy52aWV3SG9va3NbVmlld0hvb2suZWxlbWVudElEKGhvb2suZWwpXSA9IGhvb2tcbiAgICAgIHJldHVybiBob29rXG4gICAgfSBlbHNlIGlmKGhvb2tOYW1lICE9PSBudWxsKXtcbiAgICAgIGxvZ0Vycm9yKGB1bmtub3duIGhvb2sgZm91bmQgZm9yIFwiJHtob29rTmFtZX1cImAsIGVsKVxuICAgIH1cbiAgfVxuXG4gIGRlc3Ryb3lIb29rKGhvb2spe1xuICAgIGhvb2suX19kZXN0cm95ZWQoKVxuICAgIGhvb2suX19jbGVhbnVwX18oKVxuICAgIGRlbGV0ZSB0aGlzLnZpZXdIb29rc1tWaWV3SG9vay5lbGVtZW50SUQoaG9vay5lbCldXG4gIH1cblxuICBhcHBseVBlbmRpbmdVcGRhdGVzKCl7XG4gICAgdGhpcy5wZW5kaW5nRGlmZnMuZm9yRWFjaCgoe2RpZmYsIGV2ZW50c30pID0+IHRoaXMudXBkYXRlKGRpZmYsIGV2ZW50cykpXG4gICAgdGhpcy5wZW5kaW5nRGlmZnMgPSBbXVxuICAgIHRoaXMuZWFjaENoaWxkKGNoaWxkID0+IGNoaWxkLmFwcGx5UGVuZGluZ1VwZGF0ZXMoKSlcbiAgfVxuXG4gIGVhY2hDaGlsZChjYWxsYmFjayl7XG4gICAgbGV0IGNoaWxkcmVuID0gdGhpcy5yb290LmNoaWxkcmVuW3RoaXMuaWRdIHx8IHt9XG4gICAgZm9yKGxldCBpZCBpbiBjaGlsZHJlbil7IGNhbGxiYWNrKHRoaXMuZ2V0Q2hpbGRCeUlkKGlkKSkgfVxuICB9XG5cbiAgb25DaGFubmVsKGV2ZW50LCBjYil7XG4gICAgdGhpcy5saXZlU29ja2V0Lm9uQ2hhbm5lbCh0aGlzLmNoYW5uZWwsIGV2ZW50LCByZXNwID0+IHtcbiAgICAgIGlmKHRoaXMuaXNKb2luUGVuZGluZygpKXtcbiAgICAgICAgdGhpcy5yb290LnBlbmRpbmdKb2luT3BzLnB1c2goW3RoaXMsICgpID0+IGNiKHJlc3ApXSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubGl2ZVNvY2tldC5yZXF1ZXN0RE9NVXBkYXRlKCgpID0+IGNiKHJlc3ApKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICBiaW5kQ2hhbm5lbCgpe1xuICAgIC8vIFRoZSBkaWZmIGV2ZW50IHNob3VsZCBiZSBoYW5kbGVkIGJ5IHRoZSByZWd1bGFyIHVwZGF0ZSBvcGVyYXRpb25zLlxuICAgIC8vIEFsbCBvdGhlciBvcGVyYXRpb25zIGFyZSBxdWV1ZWQgdG8gYmUgYXBwbGllZCBvbmx5IGFmdGVyIGpvaW4uXG4gICAgdGhpcy5saXZlU29ja2V0Lm9uQ2hhbm5lbCh0aGlzLmNoYW5uZWwsIFwiZGlmZlwiLCAocmF3RGlmZikgPT4ge1xuICAgICAgdGhpcy5saXZlU29ja2V0LnJlcXVlc3RET01VcGRhdGUoKCkgPT4ge1xuICAgICAgICB0aGlzLmFwcGx5RGlmZihcInVwZGF0ZVwiLCByYXdEaWZmLCAoe2RpZmYsIGV2ZW50c30pID0+IHRoaXMudXBkYXRlKGRpZmYsIGV2ZW50cykpXG4gICAgICB9KVxuICAgIH0pXG4gICAgdGhpcy5vbkNoYW5uZWwoXCJyZWRpcmVjdFwiLCAoe3RvLCBmbGFzaH0pID0+IHRoaXMub25SZWRpcmVjdCh7dG8sIGZsYXNofSkpXG4gICAgdGhpcy5vbkNoYW5uZWwoXCJsaXZlX3BhdGNoXCIsIChyZWRpcikgPT4gdGhpcy5vbkxpdmVQYXRjaChyZWRpcikpXG4gICAgdGhpcy5vbkNoYW5uZWwoXCJsaXZlX3JlZGlyZWN0XCIsIChyZWRpcikgPT4gdGhpcy5vbkxpdmVSZWRpcmVjdChyZWRpcikpXG4gICAgdGhpcy5jaGFubmVsLm9uRXJyb3IocmVhc29uID0+IHRoaXMub25FcnJvcihyZWFzb24pKVxuICAgIHRoaXMuY2hhbm5lbC5vbkNsb3NlKHJlYXNvbiA9PiB0aGlzLm9uQ2xvc2UocmVhc29uKSlcbiAgfVxuXG4gIGRlc3Ryb3lBbGxDaGlsZHJlbigpeyB0aGlzLmVhY2hDaGlsZChjaGlsZCA9PiBjaGlsZC5kZXN0cm95KCkpIH1cblxuICBvbkxpdmVSZWRpcmVjdChyZWRpcil7XG4gICAgbGV0IHt0bywga2luZCwgZmxhc2h9ID0gcmVkaXJcbiAgICBsZXQgdXJsID0gdGhpcy5leHBhbmRVUkwodG8pXG4gICAgdGhpcy5saXZlU29ja2V0Lmhpc3RvcnlSZWRpcmVjdCh1cmwsIGtpbmQsIGZsYXNoKVxuICB9XG5cbiAgb25MaXZlUGF0Y2gocmVkaXIpe1xuICAgIGxldCB7dG8sIGtpbmR9ID0gcmVkaXJcbiAgICB0aGlzLmhyZWYgPSB0aGlzLmV4cGFuZFVSTCh0bylcbiAgICB0aGlzLmxpdmVTb2NrZXQuaGlzdG9yeVBhdGNoKHRvLCBraW5kKVxuICB9XG5cbiAgZXhwYW5kVVJMKHRvKXtcbiAgICByZXR1cm4gdG8uc3RhcnRzV2l0aChcIi9cIikgPyBgJHt3aW5kb3cubG9jYXRpb24ucHJvdG9jb2x9Ly8ke3dpbmRvdy5sb2NhdGlvbi5ob3N0fSR7dG99YCA6IHRvXG4gIH1cblxuICBvblJlZGlyZWN0KHt0bywgZmxhc2h9KXsgdGhpcy5saXZlU29ja2V0LnJlZGlyZWN0KHRvLCBmbGFzaCkgfVxuXG4gIGlzRGVzdHJveWVkKCl7IHJldHVybiB0aGlzLmRlc3Ryb3llZCB9XG5cbiAgam9pbkRlYWQoKXsgdGhpcy5pc0RlYWQgPSB0cnVlIH1cblxuICBqb2luKGNhbGxiYWNrKXtcbiAgICB0aGlzLnNob3dMb2FkZXIodGhpcy5saXZlU29ja2V0LmxvYWRlclRpbWVvdXQpXG4gICAgdGhpcy5iaW5kQ2hhbm5lbCgpXG4gICAgaWYodGhpcy5pc01haW4oKSl7XG4gICAgICB0aGlzLnN0b3BDYWxsYmFjayA9IHRoaXMubGl2ZVNvY2tldC53aXRoUGFnZUxvYWRpbmcoe3RvOiB0aGlzLmhyZWYsIGtpbmQ6IFwiaW5pdGlhbFwifSlcbiAgICB9XG4gICAgdGhpcy5qb2luQ2FsbGJhY2sgPSAob25Eb25lKSA9PiB7XG4gICAgICBvbkRvbmUgPSBvbkRvbmUgfHwgZnVuY3Rpb24oKXt9XG4gICAgICBjYWxsYmFjayA/IGNhbGxiYWNrKHRoaXMuam9pbkNvdW50LCBvbkRvbmUpIDogb25Eb25lKClcbiAgICB9XG4gICAgdGhpcy5saXZlU29ja2V0LndyYXBQdXNoKHRoaXMsIHt0aW1lb3V0OiBmYWxzZX0sICgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmNoYW5uZWwuam9pbigpXG4gICAgICAgIC5yZWNlaXZlKFwib2tcIiwgZGF0YSA9PiB7XG4gICAgICAgICAgaWYoIXRoaXMuaXNEZXN0cm95ZWQoKSl7XG4gICAgICAgICAgICB0aGlzLmxpdmVTb2NrZXQucmVxdWVzdERPTVVwZGF0ZSgoKSA9PiB0aGlzLm9uSm9pbihkYXRhKSlcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5yZWNlaXZlKFwiZXJyb3JcIiwgcmVzcCA9PiAhdGhpcy5pc0Rlc3Ryb3llZCgpICYmIHRoaXMub25Kb2luRXJyb3IocmVzcCkpXG4gICAgICAgIC5yZWNlaXZlKFwidGltZW91dFwiLCAoKSA9PiAhdGhpcy5pc0Rlc3Ryb3llZCgpICYmIHRoaXMub25Kb2luRXJyb3Ioe3JlYXNvbjogXCJ0aW1lb3V0XCJ9KSlcbiAgICB9KVxuICB9XG5cbiAgb25Kb2luRXJyb3IocmVzcCl7XG4gICAgaWYocmVzcC5yZWFzb24gPT09IFwicmVsb2FkXCIpe1xuICAgICAgdGhpcy5sb2coXCJlcnJvclwiLCAoKSA9PiBbYGZhaWxlZCBtb3VudCB3aXRoICR7cmVzcC5zdGF0dXN9LiBGYWxsaW5nIGJhY2sgdG8gcGFnZSByZXF1ZXN0YCwgcmVzcF0pXG4gICAgICBpZih0aGlzLmlzTWFpbigpKXsgdGhpcy5vblJlZGlyZWN0KHt0bzogdGhpcy5ocmVmfSkgfVxuICAgICAgcmV0dXJuXG4gICAgfSBlbHNlIGlmKHJlc3AucmVhc29uID09PSBcInVuYXV0aG9yaXplZFwiIHx8IHJlc3AucmVhc29uID09PSBcInN0YWxlXCIpe1xuICAgICAgdGhpcy5sb2coXCJlcnJvclwiLCAoKSA9PiBbXCJ1bmF1dGhvcml6ZWQgbGl2ZV9yZWRpcmVjdC4gRmFsbGluZyBiYWNrIHRvIHBhZ2UgcmVxdWVzdFwiLCByZXNwXSlcbiAgICAgIGlmKHRoaXMuaXNNYWluKCkpeyB0aGlzLm9uUmVkaXJlY3Qoe3RvOiB0aGlzLmhyZWZ9KSB9XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYocmVzcC5yZWRpcmVjdCB8fCByZXNwLmxpdmVfcmVkaXJlY3Qpe1xuICAgICAgdGhpcy5qb2luUGVuZGluZyA9IGZhbHNlXG4gICAgICB0aGlzLmNoYW5uZWwubGVhdmUoKVxuICAgIH1cbiAgICBpZihyZXNwLnJlZGlyZWN0KXsgcmV0dXJuIHRoaXMub25SZWRpcmVjdChyZXNwLnJlZGlyZWN0KSB9XG4gICAgaWYocmVzcC5saXZlX3JlZGlyZWN0KXsgcmV0dXJuIHRoaXMub25MaXZlUmVkaXJlY3QocmVzcC5saXZlX3JlZGlyZWN0KSB9XG4gICAgdGhpcy5kaXNwbGF5RXJyb3IoW1BIWF9MT0FESU5HX0NMQVNTLCBQSFhfRVJST1JfQ0xBU1MsIFBIWF9TRVJWRVJfRVJST1JfQ0xBU1NdKVxuICAgIHRoaXMubG9nKFwiZXJyb3JcIiwgKCkgPT4gW1widW5hYmxlIHRvIGpvaW5cIiwgcmVzcF0pXG4gICAgaWYodGhpcy5saXZlU29ja2V0LmlzQ29ubmVjdGVkKCkpeyB0aGlzLmxpdmVTb2NrZXQucmVsb2FkV2l0aEppdHRlcih0aGlzKSB9XG4gIH1cblxuICBvbkNsb3NlKHJlYXNvbil7XG4gICAgaWYodGhpcy5pc0Rlc3Ryb3llZCgpKXsgcmV0dXJuIH1cbiAgICBpZih0aGlzLmxpdmVTb2NrZXQuaGFzUGVuZGluZ0xpbmsoKSAmJiByZWFzb24gIT09IFwibGVhdmVcIil7XG4gICAgICByZXR1cm4gdGhpcy5saXZlU29ja2V0LnJlbG9hZFdpdGhKaXR0ZXIodGhpcylcbiAgICB9XG4gICAgdGhpcy5kZXN0cm95QWxsQ2hpbGRyZW4oKVxuICAgIHRoaXMubGl2ZVNvY2tldC5kcm9wQWN0aXZlRWxlbWVudCh0aGlzKVxuICAgIC8vIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgY2FuIGJlIG51bGwgaW4gSW50ZXJuZXQgRXhwbG9yZXIgMTFcbiAgICBpZihkb2N1bWVudC5hY3RpdmVFbGVtZW50KXsgZG9jdW1lbnQuYWN0aXZlRWxlbWVudC5ibHVyKCkgfVxuICAgIGlmKHRoaXMubGl2ZVNvY2tldC5pc1VubG9hZGVkKCkpe1xuICAgICAgdGhpcy5zaG93TG9hZGVyKEJFRk9SRV9VTkxPQURfTE9BREVSX1RJTUVPVVQpXG4gICAgfVxuICB9XG5cbiAgb25FcnJvcihyZWFzb24pe1xuICAgIHRoaXMub25DbG9zZShyZWFzb24pXG4gICAgaWYodGhpcy5saXZlU29ja2V0LmlzQ29ubmVjdGVkKCkpeyB0aGlzLmxvZyhcImVycm9yXCIsICgpID0+IFtcInZpZXcgY3Jhc2hlZFwiLCByZWFzb25dKSB9XG4gICAgaWYoIXRoaXMubGl2ZVNvY2tldC5pc1VubG9hZGVkKCkpe1xuICAgICAgaWYodGhpcy5saXZlU29ja2V0LmlzQ29ubmVjdGVkKCkpe1xuICAgICAgICB0aGlzLmRpc3BsYXlFcnJvcihbUEhYX0xPQURJTkdfQ0xBU1MsIFBIWF9FUlJPUl9DTEFTUywgUEhYX1NFUlZFUl9FUlJPUl9DTEFTU10pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmRpc3BsYXlFcnJvcihbUEhYX0xPQURJTkdfQ0xBU1MsIFBIWF9FUlJPUl9DTEFTUywgUEhYX0NMSUVOVF9FUlJPUl9DTEFTU10pXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZGlzcGxheUVycm9yKGNsYXNzZXMpe1xuICAgIGlmKHRoaXMuaXNNYWluKCkpeyBET00uZGlzcGF0Y2hFdmVudCh3aW5kb3csIFwicGh4OnBhZ2UtbG9hZGluZy1zdGFydFwiLCB7ZGV0YWlsOiB7dG86IHRoaXMuaHJlZiwga2luZDogXCJlcnJvclwifX0pIH1cbiAgICB0aGlzLnNob3dMb2FkZXIoKVxuICAgIHRoaXMuc2V0Q29udGFpbmVyQ2xhc3NlcyguLi5jbGFzc2VzKVxuICAgIHRoaXMuZXhlY0FsbCh0aGlzLmJpbmRpbmcoXCJkaXNjb25uZWN0ZWRcIikpXG4gIH1cblxuICBwdXNoV2l0aFJlcGx5KHJlZkdlbmVyYXRvciwgZXZlbnQsIHBheWxvYWQsIG9uUmVwbHkgPSBmdW5jdGlvbiAoKXsgfSl7XG4gICAgaWYoIXRoaXMuaXNDb25uZWN0ZWQoKSl7IHJldHVybiB9XG5cbiAgICBsZXQgW3JlZiwgW2VsXSwgb3B0c10gPSByZWZHZW5lcmF0b3IgPyByZWZHZW5lcmF0b3IoKSA6IFtudWxsLCBbXSwge31dXG4gICAgbGV0IG9uTG9hZGluZ0RvbmUgPSBmdW5jdGlvbigpeyB9XG4gICAgaWYob3B0cy5wYWdlX2xvYWRpbmcgfHwgKGVsICYmIChlbC5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFBIWF9QQUdFX0xPQURJTkcpKSAhPT0gbnVsbCkpKXtcbiAgICAgIG9uTG9hZGluZ0RvbmUgPSB0aGlzLmxpdmVTb2NrZXQud2l0aFBhZ2VMb2FkaW5nKHtraW5kOiBcImVsZW1lbnRcIiwgdGFyZ2V0OiBlbH0pXG4gICAgfVxuXG4gICAgaWYodHlwZW9mIChwYXlsb2FkLmNpZCkgIT09IFwibnVtYmVyXCIpeyBkZWxldGUgcGF5bG9hZC5jaWQgfVxuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmxpdmVTb2NrZXQud3JhcFB1c2godGhpcywge3RpbWVvdXQ6IHRydWV9LCAoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmNoYW5uZWwucHVzaChldmVudCwgcGF5bG9hZCwgUFVTSF9USU1FT1VUKS5yZWNlaXZlKFwib2tcIiwgcmVzcCA9PiB7XG4gICAgICAgICAgbGV0IGZpbmlzaCA9IChob29rUmVwbHkpID0+IHtcbiAgICAgICAgICAgIGlmKHJlc3AucmVkaXJlY3QpeyB0aGlzLm9uUmVkaXJlY3QocmVzcC5yZWRpcmVjdCkgfVxuICAgICAgICAgICAgaWYocmVzcC5saXZlX3BhdGNoKXsgdGhpcy5vbkxpdmVQYXRjaChyZXNwLmxpdmVfcGF0Y2gpIH1cbiAgICAgICAgICAgIGlmKHJlc3AubGl2ZV9yZWRpcmVjdCl7IHRoaXMub25MaXZlUmVkaXJlY3QocmVzcC5saXZlX3JlZGlyZWN0KSB9XG4gICAgICAgICAgICBvbkxvYWRpbmdEb25lKClcbiAgICAgICAgICAgIG9uUmVwbHkocmVzcCwgaG9va1JlcGx5KVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZihyZXNwLmRpZmYpe1xuICAgICAgICAgICAgdGhpcy5saXZlU29ja2V0LnJlcXVlc3RET01VcGRhdGUoKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLmFwcGx5RGlmZihcInVwZGF0ZVwiLCByZXNwLmRpZmYsICh7ZGlmZiwgcmVwbHksIGV2ZW50c30pID0+IHtcbiAgICAgICAgICAgICAgICBpZihyZWYgIT09IG51bGwpeyB0aGlzLnVuZG9SZWZzKHJlZikgfVxuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlKGRpZmYsIGV2ZW50cylcbiAgICAgICAgICAgICAgICBmaW5pc2gocmVwbHkpXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZihyZWYgIT09IG51bGwpeyB0aGlzLnVuZG9SZWZzKHJlZikgfVxuICAgICAgICAgICAgZmluaXNoKG51bGwpXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfSlcbiAgICApXG4gIH1cblxuICB1bmRvUmVmcyhyZWYpe1xuICAgIGlmKCF0aGlzLmlzQ29ubmVjdGVkKCkpeyByZXR1cm4gfSAvLyBleGl0IGlmIGV4dGVybmFsIGZvcm0gdHJpZ2dlcmVkXG5cbiAgICBET00uYWxsKGRvY3VtZW50LCBgWyR7UEhYX1JFRl9TUkN9PVwiJHt0aGlzLmlkfVwiXVske1BIWF9SRUZ9PVwiJHtyZWZ9XCJdYCwgZWwgPT4ge1xuICAgICAgbGV0IGRpc2FibGVkVmFsID0gZWwuZ2V0QXR0cmlidXRlKFBIWF9ESVNBQkxFRClcbiAgICAgIC8vIHJlbW92ZSByZWZzXG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1JFRilcbiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShQSFhfUkVGX1NSQylcbiAgICAgIC8vIHJlc3RvcmUgaW5wdXRzXG4gICAgICBpZihlbC5nZXRBdHRyaWJ1dGUoUEhYX1JFQURPTkxZKSAhPT0gbnVsbCl7XG4gICAgICAgIGVsLnJlYWRPbmx5ID0gZmFsc2VcbiAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKFBIWF9SRUFET05MWSlcbiAgICAgIH1cbiAgICAgIGlmKGRpc2FibGVkVmFsICE9PSBudWxsKXtcbiAgICAgICAgZWwuZGlzYWJsZWQgPSBkaXNhYmxlZFZhbCA9PT0gXCJ0cnVlXCIgPyB0cnVlIDogZmFsc2VcbiAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKFBIWF9ESVNBQkxFRClcbiAgICAgIH1cbiAgICAgIC8vIHJlbW92ZSBjbGFzc2VzXG4gICAgICBQSFhfRVZFTlRfQ0xBU1NFUy5mb3JFYWNoKGNsYXNzTmFtZSA9PiBET00ucmVtb3ZlQ2xhc3MoZWwsIGNsYXNzTmFtZSkpXG4gICAgICAvLyByZXN0b3JlIGRpc2FibGVzXG4gICAgICBsZXQgZGlzYWJsZVJlc3RvcmUgPSBlbC5nZXRBdHRyaWJ1dGUoUEhYX0RJU0FCTEVfV0lUSF9SRVNUT1JFKVxuICAgICAgaWYoZGlzYWJsZVJlc3RvcmUgIT09IG51bGwpe1xuICAgICAgICBlbC5pbm5lclRleHQgPSBkaXNhYmxlUmVzdG9yZVxuICAgICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX0RJU0FCTEVfV0lUSF9SRVNUT1JFKVxuICAgICAgfVxuICAgICAgbGV0IHRvRWwgPSBET00ucHJpdmF0ZShlbCwgUEhYX1JFRilcbiAgICAgIGlmKHRvRWwpe1xuICAgICAgICBsZXQgaG9vayA9IHRoaXMudHJpZ2dlckJlZm9yZVVwZGF0ZUhvb2soZWwsIHRvRWwpXG4gICAgICAgIERPTVBhdGNoLnBhdGNoRWwoZWwsIHRvRWwsIHRoaXMubGl2ZVNvY2tldC5nZXRBY3RpdmVFbGVtZW50KCkpXG4gICAgICAgIGlmKGhvb2speyBob29rLl9fdXBkYXRlZCgpIH1cbiAgICAgICAgRE9NLmRlbGV0ZVByaXZhdGUoZWwsIFBIWF9SRUYpXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIHB1dFJlZihlbGVtZW50cywgZXZlbnQsIG9wdHMgPSB7fSl7XG4gICAgbGV0IG5ld1JlZiA9IHRoaXMucmVmKytcbiAgICBsZXQgZGlzYWJsZVdpdGggPSB0aGlzLmJpbmRpbmcoUEhYX0RJU0FCTEVfV0lUSClcbiAgICBpZihvcHRzLmxvYWRpbmcpeyBlbGVtZW50cyA9IGVsZW1lbnRzLmNvbmNhdChET00uYWxsKGRvY3VtZW50LCBvcHRzLmxvYWRpbmcpKX1cblxuICAgIGVsZW1lbnRzLmZvckVhY2goZWwgPT4ge1xuICAgICAgZWwuY2xhc3NMaXN0LmFkZChgcGh4LSR7ZXZlbnR9LWxvYWRpbmdgKVxuICAgICAgZWwuc2V0QXR0cmlidXRlKFBIWF9SRUYsIG5ld1JlZilcbiAgICAgIGVsLnNldEF0dHJpYnV0ZShQSFhfUkVGX1NSQywgdGhpcy5lbC5pZClcbiAgICAgIGxldCBkaXNhYmxlVGV4dCA9IGVsLmdldEF0dHJpYnV0ZShkaXNhYmxlV2l0aClcbiAgICAgIGlmKGRpc2FibGVUZXh0ICE9PSBudWxsKXtcbiAgICAgICAgaWYoIWVsLmdldEF0dHJpYnV0ZShQSFhfRElTQUJMRV9XSVRIX1JFU1RPUkUpKXtcbiAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoUEhYX0RJU0FCTEVfV0lUSF9SRVNUT1JFLCBlbC5pbm5lclRleHQpXG4gICAgICAgIH1cbiAgICAgICAgaWYoZGlzYWJsZVRleHQgIT09IFwiXCIpeyBlbC5pbm5lclRleHQgPSBkaXNhYmxlVGV4dCB9XG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZShcImRpc2FibGVkXCIsIFwiXCIpXG4gICAgICB9XG4gICAgfSlcbiAgICByZXR1cm4gW25ld1JlZiwgZWxlbWVudHMsIG9wdHNdXG4gIH1cblxuICBjb21wb25lbnRJRChlbCl7XG4gICAgbGV0IGNpZCA9IGVsLmdldEF0dHJpYnV0ZSAmJiBlbC5nZXRBdHRyaWJ1dGUoUEhYX0NPTVBPTkVOVClcbiAgICByZXR1cm4gY2lkID8gcGFyc2VJbnQoY2lkKSA6IG51bGxcbiAgfVxuXG4gIHRhcmdldENvbXBvbmVudElEKHRhcmdldCwgdGFyZ2V0Q3R4LCBvcHRzID0ge30pe1xuICAgIGlmKGlzQ2lkKHRhcmdldEN0eCkpeyByZXR1cm4gdGFyZ2V0Q3R4IH1cblxuICAgIGxldCBjaWRPclNlbGVjdG9yID0gdGFyZ2V0LmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoXCJ0YXJnZXRcIikpXG4gICAgaWYoaXNDaWQoY2lkT3JTZWxlY3Rvcikpe1xuICAgICAgcmV0dXJuIHBhcnNlSW50KGNpZE9yU2VsZWN0b3IpXG4gICAgfSBlbHNlIGlmKHRhcmdldEN0eCAmJiAoY2lkT3JTZWxlY3RvciAhPT0gbnVsbCB8fCBvcHRzLnRhcmdldCkpe1xuICAgICAgcmV0dXJuIHRoaXMuY2xvc2VzdENvbXBvbmVudElEKHRhcmdldEN0eClcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG4gIH1cblxuICBjbG9zZXN0Q29tcG9uZW50SUQodGFyZ2V0Q3R4KXtcbiAgICBpZihpc0NpZCh0YXJnZXRDdHgpKXtcbiAgICAgIHJldHVybiB0YXJnZXRDdHhcbiAgICB9IGVsc2UgaWYodGFyZ2V0Q3R4KXtcbiAgICAgIHJldHVybiBtYXliZSh0YXJnZXRDdHguY2xvc2VzdChgWyR7UEhYX0NPTVBPTkVOVH1dYCksIGVsID0+IHRoaXMub3duc0VsZW1lbnQoZWwpICYmIHRoaXMuY29tcG9uZW50SUQoZWwpKVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbFxuICAgIH1cbiAgfVxuXG4gIHB1c2hIb29rRXZlbnQoZWwsIHRhcmdldEN0eCwgZXZlbnQsIHBheWxvYWQsIG9uUmVwbHkpe1xuICAgIGlmKCF0aGlzLmlzQ29ubmVjdGVkKCkpe1xuICAgICAgdGhpcy5sb2coXCJob29rXCIsICgpID0+IFtcInVuYWJsZSB0byBwdXNoIGhvb2sgZXZlbnQuIExpdmVWaWV3IG5vdCBjb25uZWN0ZWRcIiwgZXZlbnQsIHBheWxvYWRdKVxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIGxldCBbcmVmLCBlbHMsIG9wdHNdID0gdGhpcy5wdXRSZWYoW2VsXSwgXCJob29rXCIpXG4gICAgdGhpcy5wdXNoV2l0aFJlcGx5KCgpID0+IFtyZWYsIGVscywgb3B0c10sIFwiZXZlbnRcIiwge1xuICAgICAgdHlwZTogXCJob29rXCIsXG4gICAgICBldmVudDogZXZlbnQsXG4gICAgICB2YWx1ZTogcGF5bG9hZCxcbiAgICAgIGNpZDogdGhpcy5jbG9zZXN0Q29tcG9uZW50SUQodGFyZ2V0Q3R4KVxuICAgIH0sIChyZXNwLCByZXBseSkgPT4gb25SZXBseShyZXBseSwgcmVmKSlcblxuICAgIHJldHVybiByZWZcbiAgfVxuXG4gIGV4dHJhY3RNZXRhKGVsLCBtZXRhLCB2YWx1ZSl7XG4gICAgbGV0IHByZWZpeCA9IHRoaXMuYmluZGluZyhcInZhbHVlLVwiKVxuICAgIGZvcihsZXQgaSA9IDA7IGkgPCBlbC5hdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKXtcbiAgICAgIGlmKCFtZXRhKXsgbWV0YSA9IHt9IH1cbiAgICAgIGxldCBuYW1lID0gZWwuYXR0cmlidXRlc1tpXS5uYW1lXG4gICAgICBpZihuYW1lLnN0YXJ0c1dpdGgocHJlZml4KSl7IG1ldGFbbmFtZS5yZXBsYWNlKHByZWZpeCwgXCJcIildID0gZWwuZ2V0QXR0cmlidXRlKG5hbWUpIH1cbiAgICB9XG4gICAgaWYoZWwudmFsdWUgIT09IHVuZGVmaW5lZCAmJiAhKGVsIGluc3RhbmNlb2YgSFRNTEZvcm1FbGVtZW50KSl7XG4gICAgICBpZighbWV0YSl7IG1ldGEgPSB7fSB9XG4gICAgICBtZXRhLnZhbHVlID0gZWwudmFsdWVcblxuICAgICAgaWYoZWwudGFnTmFtZSA9PT0gXCJJTlBVVFwiICYmIENIRUNLQUJMRV9JTlBVVFMuaW5kZXhPZihlbC50eXBlKSA+PSAwICYmICFlbC5jaGVja2VkKXtcbiAgICAgICAgZGVsZXRlIG1ldGEudmFsdWVcbiAgICAgIH1cbiAgICB9XG4gICAgaWYodmFsdWUpe1xuICAgICAgaWYoIW1ldGEpeyBtZXRhID0ge30gfVxuICAgICAgZm9yKGxldCBrZXkgaW4gdmFsdWUpeyBtZXRhW2tleV0gPSB2YWx1ZVtrZXldIH1cbiAgICB9XG4gICAgcmV0dXJuIG1ldGFcbiAgfVxuXG5cbiAgcHVzaEV2ZW50KHR5cGUsIGVsLCB0YXJnZXRDdHgsIHBoeEV2ZW50LCBtZXRhLCBvcHRzID0ge30sIG9uUmVwbHkpe1xuICAgIHRoaXMucHVzaFdpdGhSZXBseSgoKSA9PiB0aGlzLnB1dFJlZihbZWxdLCB0eXBlLCBvcHRzKSwgXCJldmVudFwiLCB7XG4gICAgICB0eXBlOiB0eXBlLFxuICAgICAgZXZlbnQ6IHBoeEV2ZW50LFxuICAgICAgdmFsdWU6IHRoaXMuZXh0cmFjdE1ldGEoZWwsIG1ldGEsIG9wdHMudmFsdWUpLFxuICAgICAgY2lkOiB0aGlzLnRhcmdldENvbXBvbmVudElEKGVsLCB0YXJnZXRDdHgsIG9wdHMpXG4gICAgfSwgKHJlc3AsIHJlcGx5KSA9PiBvblJlcGx5ICYmIG9uUmVwbHkocmVwbHkpKVxuICB9XG5cbiAgcHVzaEZpbGVQcm9ncmVzcyhmaWxlRWwsIGVudHJ5UmVmLCBwcm9ncmVzcywgb25SZXBseSA9IGZ1bmN0aW9uICgpeyB9KXtcbiAgICB0aGlzLmxpdmVTb2NrZXQud2l0aGluT3duZXJzKGZpbGVFbC5mb3JtLCAodmlldywgdGFyZ2V0Q3R4KSA9PiB7XG4gICAgICB2aWV3LnB1c2hXaXRoUmVwbHkobnVsbCwgXCJwcm9ncmVzc1wiLCB7XG4gICAgICAgIGV2ZW50OiBmaWxlRWwuZ2V0QXR0cmlidXRlKHZpZXcuYmluZGluZyhQSFhfUFJPR1JFU1MpKSxcbiAgICAgICAgcmVmOiBmaWxlRWwuZ2V0QXR0cmlidXRlKFBIWF9VUExPQURfUkVGKSxcbiAgICAgICAgZW50cnlfcmVmOiBlbnRyeVJlZixcbiAgICAgICAgcHJvZ3Jlc3M6IHByb2dyZXNzLFxuICAgICAgICBjaWQ6IHZpZXcudGFyZ2V0Q29tcG9uZW50SUQoZmlsZUVsLmZvcm0sIHRhcmdldEN0eClcbiAgICAgIH0sIG9uUmVwbHkpXG4gICAgfSlcbiAgfVxuXG4gIHB1c2hJbnB1dChpbnB1dEVsLCB0YXJnZXRDdHgsIGZvcmNlQ2lkLCBwaHhFdmVudCwgb3B0cywgY2FsbGJhY2spe1xuICAgIGxldCB1cGxvYWRzXG4gICAgbGV0IGNpZCA9IGlzQ2lkKGZvcmNlQ2lkKSA/IGZvcmNlQ2lkIDogdGhpcy50YXJnZXRDb21wb25lbnRJRChpbnB1dEVsLmZvcm0sIHRhcmdldEN0eClcbiAgICBsZXQgcmVmR2VuZXJhdG9yID0gKCkgPT4gdGhpcy5wdXRSZWYoW2lucHV0RWwsIGlucHV0RWwuZm9ybV0sIFwiY2hhbmdlXCIsIG9wdHMpXG4gICAgbGV0IGZvcm1EYXRhXG4gICAgbGV0IG1ldGEgID0gdGhpcy5leHRyYWN0TWV0YShpbnB1dEVsLmZvcm0pXG4gICAgaWYoaW5wdXRFbC5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFwiY2hhbmdlXCIpKSl7XG4gICAgICBmb3JtRGF0YSA9IHNlcmlhbGl6ZUZvcm0oaW5wdXRFbC5mb3JtLCB7X3RhcmdldDogb3B0cy5fdGFyZ2V0LCAuLi5tZXRhfSwgW2lucHV0RWwubmFtZV0pXG4gICAgfSBlbHNlIHtcbiAgICAgIGZvcm1EYXRhID0gc2VyaWFsaXplRm9ybShpbnB1dEVsLmZvcm0sIHtfdGFyZ2V0OiBvcHRzLl90YXJnZXQsIC4uLm1ldGF9KVxuICAgIH1cbiAgICBpZihET00uaXNVcGxvYWRJbnB1dChpbnB1dEVsKSAmJiBpbnB1dEVsLmZpbGVzICYmIGlucHV0RWwuZmlsZXMubGVuZ3RoID4gMCl7XG4gICAgICBMaXZlVXBsb2FkZXIudHJhY2tGaWxlcyhpbnB1dEVsLCBBcnJheS5mcm9tKGlucHV0RWwuZmlsZXMpKVxuICAgIH1cbiAgICB1cGxvYWRzID0gTGl2ZVVwbG9hZGVyLnNlcmlhbGl6ZVVwbG9hZHMoaW5wdXRFbClcblxuICAgIGxldCBldmVudCA9IHtcbiAgICAgIHR5cGU6IFwiZm9ybVwiLFxuICAgICAgZXZlbnQ6IHBoeEV2ZW50LFxuICAgICAgdmFsdWU6IGZvcm1EYXRhLFxuICAgICAgdXBsb2FkczogdXBsb2FkcyxcbiAgICAgIGNpZDogY2lkXG4gICAgfVxuICAgIHRoaXMucHVzaFdpdGhSZXBseShyZWZHZW5lcmF0b3IsIFwiZXZlbnRcIiwgZXZlbnQsIHJlc3AgPT4ge1xuICAgICAgRE9NLnNob3dFcnJvcihpbnB1dEVsLCB0aGlzLmxpdmVTb2NrZXQuYmluZGluZyhQSFhfRkVFREJBQ0tfRk9SKSlcbiAgICAgIGlmKERPTS5pc1VwbG9hZElucHV0KGlucHV0RWwpICYmIERPTS5pc0F1dG9VcGxvYWQoaW5wdXRFbCkpe1xuICAgICAgICBpZihMaXZlVXBsb2FkZXIuZmlsZXNBd2FpdGluZ1ByZWZsaWdodChpbnB1dEVsKS5sZW5ndGggPiAwKXtcbiAgICAgICAgICBsZXQgW3JlZiwgX2Vsc10gPSByZWZHZW5lcmF0b3IoKVxuICAgICAgICAgIHRoaXMudXBsb2FkRmlsZXMoaW5wdXRFbC5mb3JtLCB0YXJnZXRDdHgsIHJlZiwgY2lkLCAoX3VwbG9hZHMpID0+IHtcbiAgICAgICAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKHJlc3ApXG4gICAgICAgICAgICB0aGlzLnRyaWdnZXJBd2FpdGluZ1N1Ym1pdChpbnB1dEVsLmZvcm0pXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2socmVzcClcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgdHJpZ2dlckF3YWl0aW5nU3VibWl0KGZvcm1FbCl7XG4gICAgbGV0IGF3YWl0aW5nU3VibWl0ID0gdGhpcy5nZXRTY2hlZHVsZWRTdWJtaXQoZm9ybUVsKVxuICAgIGlmKGF3YWl0aW5nU3VibWl0KXtcbiAgICAgIGxldCBbX2VsLCBfcmVmLCBfb3B0cywgY2FsbGJhY2tdID0gYXdhaXRpbmdTdWJtaXRcbiAgICAgIHRoaXMuY2FuY2VsU3VibWl0KGZvcm1FbClcbiAgICAgIGNhbGxiYWNrKClcbiAgICB9XG4gIH1cblxuICBnZXRTY2hlZHVsZWRTdWJtaXQoZm9ybUVsKXtcbiAgICByZXR1cm4gdGhpcy5mb3JtU3VibWl0cy5maW5kKChbZWwsIF9yZWYsIF9vcHRzLCBfY2FsbGJhY2tdKSA9PiBlbC5pc1NhbWVOb2RlKGZvcm1FbCkpXG4gIH1cblxuICBzY2hlZHVsZVN1Ym1pdChmb3JtRWwsIHJlZiwgb3B0cywgY2FsbGJhY2spe1xuICAgIGlmKHRoaXMuZ2V0U2NoZWR1bGVkU3VibWl0KGZvcm1FbCkpeyByZXR1cm4gdHJ1ZSB9XG4gICAgdGhpcy5mb3JtU3VibWl0cy5wdXNoKFtmb3JtRWwsIHJlZiwgb3B0cywgY2FsbGJhY2tdKVxuICB9XG5cbiAgY2FuY2VsU3VibWl0KGZvcm1FbCl7XG4gICAgdGhpcy5mb3JtU3VibWl0cyA9IHRoaXMuZm9ybVN1Ym1pdHMuZmlsdGVyKChbZWwsIHJlZiwgX2NhbGxiYWNrXSkgPT4ge1xuICAgICAgaWYoZWwuaXNTYW1lTm9kZShmb3JtRWwpKXtcbiAgICAgICAgdGhpcy51bmRvUmVmcyhyZWYpXG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgZGlzYWJsZUZvcm0oZm9ybUVsLCBvcHRzID0ge30pe1xuICAgIGxldCBmaWx0ZXJJZ25vcmVkID0gZWwgPT4ge1xuICAgICAgbGV0IHVzZXJJZ25vcmVkID0gY2xvc2VzdFBoeEJpbmRpbmcoZWwsIGAke3RoaXMuYmluZGluZyhQSFhfVVBEQVRFKX09aWdub3JlYCwgZWwuZm9ybSlcbiAgICAgIHJldHVybiAhKHVzZXJJZ25vcmVkIHx8IGNsb3Nlc3RQaHhCaW5kaW5nKGVsLCBcImRhdGEtcGh4LXVwZGF0ZT1pZ25vcmVcIiwgZWwuZm9ybSkpXG4gICAgfVxuICAgIGxldCBmaWx0ZXJEaXNhYmxlcyA9IGVsID0+IHtcbiAgICAgIHJldHVybiBlbC5oYXNBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFBIWF9ESVNBQkxFX1dJVEgpKVxuICAgIH1cbiAgICBsZXQgZmlsdGVyQnV0dG9uID0gZWwgPT4gZWwudGFnTmFtZSA9PSBcIkJVVFRPTlwiXG5cbiAgICBsZXQgZmlsdGVySW5wdXQgPSBlbCA9PiBbXCJJTlBVVFwiLCBcIlRFWFRBUkVBXCIsIFwiU0VMRUNUXCJdLmluY2x1ZGVzKGVsLnRhZ05hbWUpXG5cbiAgICBsZXQgZm9ybUVsZW1lbnRzID0gQXJyYXkuZnJvbShmb3JtRWwuZWxlbWVudHMpXG4gICAgbGV0IGRpc2FibGVzID0gZm9ybUVsZW1lbnRzLmZpbHRlcihmaWx0ZXJEaXNhYmxlcylcbiAgICBsZXQgYnV0dG9ucyA9IGZvcm1FbGVtZW50cy5maWx0ZXIoZmlsdGVyQnV0dG9uKS5maWx0ZXIoZmlsdGVySWdub3JlZClcbiAgICBsZXQgaW5wdXRzID0gZm9ybUVsZW1lbnRzLmZpbHRlcihmaWx0ZXJJbnB1dCkuZmlsdGVyKGZpbHRlcklnbm9yZWQpXG5cbiAgICBidXR0b25zLmZvckVhY2goYnV0dG9uID0+IHtcbiAgICAgIGJ1dHRvbi5zZXRBdHRyaWJ1dGUoUEhYX0RJU0FCTEVELCBidXR0b24uZGlzYWJsZWQpXG4gICAgICBidXR0b24uZGlzYWJsZWQgPSB0cnVlXG4gICAgfSlcbiAgICBpbnB1dHMuZm9yRWFjaChpbnB1dCA9PiB7XG4gICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoUEhYX1JFQURPTkxZLCBpbnB1dC5yZWFkT25seSlcbiAgICAgIGlucHV0LnJlYWRPbmx5ID0gdHJ1ZVxuICAgICAgaWYoaW5wdXQuZmlsZXMpe1xuICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoUEhYX0RJU0FCTEVELCBpbnB1dC5kaXNhYmxlZClcbiAgICAgICAgaW5wdXQuZGlzYWJsZWQgPSB0cnVlXG4gICAgICB9XG4gICAgfSlcbiAgICBmb3JtRWwuc2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhQSFhfUEFHRV9MT0FESU5HKSwgXCJcIilcbiAgICByZXR1cm4gdGhpcy5wdXRSZWYoW2Zvcm1FbF0uY29uY2F0KGRpc2FibGVzKS5jb25jYXQoYnV0dG9ucykuY29uY2F0KGlucHV0cyksIFwic3VibWl0XCIsIG9wdHMpXG4gIH1cblxuICBwdXNoRm9ybVN1Ym1pdChmb3JtRWwsIHRhcmdldEN0eCwgcGh4RXZlbnQsIHN1Ym1pdHRlciwgb3B0cywgb25SZXBseSl7XG4gICAgbGV0IHJlZkdlbmVyYXRvciA9ICgpID0+IHRoaXMuZGlzYWJsZUZvcm0oZm9ybUVsLCBvcHRzKVxuICAgIGxldCBjaWQgPSB0aGlzLnRhcmdldENvbXBvbmVudElEKGZvcm1FbCwgdGFyZ2V0Q3R4KVxuICAgIGlmKExpdmVVcGxvYWRlci5oYXNVcGxvYWRzSW5Qcm9ncmVzcyhmb3JtRWwpKXtcbiAgICAgIGxldCBbcmVmLCBfZWxzXSA9IHJlZkdlbmVyYXRvcigpXG4gICAgICBsZXQgcHVzaCA9ICgpID0+IHRoaXMucHVzaEZvcm1TdWJtaXQoZm9ybUVsLCBzdWJtaXR0ZXIsIHRhcmdldEN0eCwgcGh4RXZlbnQsIG9wdHMsIG9uUmVwbHkpXG4gICAgICByZXR1cm4gdGhpcy5zY2hlZHVsZVN1Ym1pdChmb3JtRWwsIHJlZiwgb3B0cywgcHVzaClcbiAgICB9IGVsc2UgaWYoTGl2ZVVwbG9hZGVyLmlucHV0c0F3YWl0aW5nUHJlZmxpZ2h0KGZvcm1FbCkubGVuZ3RoID4gMCl7XG4gICAgICBsZXQgW3JlZiwgZWxzXSA9IHJlZkdlbmVyYXRvcigpXG4gICAgICBsZXQgcHJveHlSZWZHZW4gPSAoKSA9PiBbcmVmLCBlbHMsIG9wdHNdXG4gICAgICB0aGlzLnVwbG9hZEZpbGVzKGZvcm1FbCwgdGFyZ2V0Q3R4LCByZWYsIGNpZCwgKF91cGxvYWRzKSA9PiB7XG4gICAgICAgIGxldCBtZXRhID0gdGhpcy5leHRyYWN0TWV0YShmb3JtRWwpXG4gICAgICAgIGxldCBmb3JtRGF0YSA9IHNlcmlhbGl6ZUZvcm0oZm9ybUVsLCB7c3VibWl0dGVyLCAuLi5tZXRhfSlcbiAgICAgICAgdGhpcy5wdXNoV2l0aFJlcGx5KHByb3h5UmVmR2VuLCBcImV2ZW50XCIsIHtcbiAgICAgICAgICB0eXBlOiBcImZvcm1cIixcbiAgICAgICAgICBldmVudDogcGh4RXZlbnQsXG4gICAgICAgICAgdmFsdWU6IGZvcm1EYXRhLFxuICAgICAgICAgIGNpZDogY2lkXG4gICAgICAgIH0sIG9uUmVwbHkpXG4gICAgICB9KVxuICAgIH0gZWxzZSBpZighKGZvcm1FbC5oYXNBdHRyaWJ1dGUoUEhYX1JFRikgJiYgZm9ybUVsLmNsYXNzTGlzdC5jb250YWlucyhcInBoeC1zdWJtaXQtbG9hZGluZ1wiKSkpe1xuICAgICAgbGV0IG1ldGEgPSB0aGlzLmV4dHJhY3RNZXRhKGZvcm1FbClcbiAgICAgIGxldCBmb3JtRGF0YSA9IHNlcmlhbGl6ZUZvcm0oZm9ybUVsLCB7c3VibWl0dGVyLCAuLi5tZXRhfSlcbiAgICAgIHRoaXMucHVzaFdpdGhSZXBseShyZWZHZW5lcmF0b3IsIFwiZXZlbnRcIiwge1xuICAgICAgICB0eXBlOiBcImZvcm1cIixcbiAgICAgICAgZXZlbnQ6IHBoeEV2ZW50LFxuICAgICAgICB2YWx1ZTogZm9ybURhdGEsXG4gICAgICAgIGNpZDogY2lkXG4gICAgICB9LCBvblJlcGx5KVxuICAgIH1cbiAgfVxuXG4gIHVwbG9hZEZpbGVzKGZvcm1FbCwgdGFyZ2V0Q3R4LCByZWYsIGNpZCwgb25Db21wbGV0ZSl7XG4gICAgbGV0IGpvaW5Db3VudEF0VXBsb2FkID0gdGhpcy5qb2luQ291bnRcbiAgICBsZXQgaW5wdXRFbHMgPSBMaXZlVXBsb2FkZXIuYWN0aXZlRmlsZUlucHV0cyhmb3JtRWwpXG4gICAgbGV0IG51bUZpbGVJbnB1dHNJblByb2dyZXNzID0gaW5wdXRFbHMubGVuZ3RoXG5cbiAgICAvLyBnZXQgZWFjaCBmaWxlIGlucHV0XG4gICAgaW5wdXRFbHMuZm9yRWFjaChpbnB1dEVsID0+IHtcbiAgICAgIGxldCB1cGxvYWRlciA9IG5ldyBMaXZlVXBsb2FkZXIoaW5wdXRFbCwgdGhpcywgKCkgPT4ge1xuICAgICAgICBudW1GaWxlSW5wdXRzSW5Qcm9ncmVzcy0tXG4gICAgICAgIGlmKG51bUZpbGVJbnB1dHNJblByb2dyZXNzID09PSAwKXsgb25Db21wbGV0ZSgpIH1cbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLnVwbG9hZGVyc1tpbnB1dEVsXSA9IHVwbG9hZGVyXG4gICAgICBsZXQgZW50cmllcyA9IHVwbG9hZGVyLmVudHJpZXMoKS5tYXAoZW50cnkgPT4gZW50cnkudG9QcmVmbGlnaHRQYXlsb2FkKCkpXG5cbiAgICAgIGxldCBwYXlsb2FkID0ge1xuICAgICAgICByZWY6IGlucHV0RWwuZ2V0QXR0cmlidXRlKFBIWF9VUExPQURfUkVGKSxcbiAgICAgICAgZW50cmllczogZW50cmllcyxcbiAgICAgICAgY2lkOiB0aGlzLnRhcmdldENvbXBvbmVudElEKGlucHV0RWwuZm9ybSwgdGFyZ2V0Q3R4KVxuICAgICAgfVxuXG4gICAgICB0aGlzLmxvZyhcInVwbG9hZFwiLCAoKSA9PiBbXCJzZW5kaW5nIHByZWZsaWdodCByZXF1ZXN0XCIsIHBheWxvYWRdKVxuXG4gICAgICB0aGlzLnB1c2hXaXRoUmVwbHkobnVsbCwgXCJhbGxvd191cGxvYWRcIiwgcGF5bG9hZCwgcmVzcCA9PiB7XG4gICAgICAgIHRoaXMubG9nKFwidXBsb2FkXCIsICgpID0+IFtcImdvdCBwcmVmbGlnaHQgcmVzcG9uc2VcIiwgcmVzcF0pXG4gICAgICAgIGlmKHJlc3AuZXJyb3Ipe1xuICAgICAgICAgIHRoaXMudW5kb1JlZnMocmVmKVxuICAgICAgICAgIGxldCBbZW50cnlfcmVmLCByZWFzb25dID0gcmVzcC5lcnJvclxuICAgICAgICAgIHRoaXMubG9nKFwidXBsb2FkXCIsICgpID0+IFtgZXJyb3IgZm9yIGVudHJ5ICR7ZW50cnlfcmVmfWAsIHJlYXNvbl0pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbGV0IG9uRXJyb3IgPSAoY2FsbGJhY2spID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2hhbm5lbC5vbkVycm9yKCgpID0+IHtcbiAgICAgICAgICAgICAgaWYodGhpcy5qb2luQ291bnQgPT09IGpvaW5Db3VudEF0VXBsb2FkKXsgY2FsbGJhY2soKSB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH1cbiAgICAgICAgICB1cGxvYWRlci5pbml0QWRhcHRlclVwbG9hZChyZXNwLCBvbkVycm9yLCB0aGlzLmxpdmVTb2NrZXQpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfSlcbiAgfVxuXG4gIGRpc3BhdGNoVXBsb2FkcyhuYW1lLCBmaWxlc09yQmxvYnMpe1xuICAgIGxldCBpbnB1dHMgPSBET00uZmluZFVwbG9hZElucHV0cyh0aGlzLmVsKS5maWx0ZXIoZWwgPT4gZWwubmFtZSA9PT0gbmFtZSlcbiAgICBpZihpbnB1dHMubGVuZ3RoID09PSAwKXsgbG9nRXJyb3IoYG5vIGxpdmUgZmlsZSBpbnB1dHMgZm91bmQgbWF0Y2hpbmcgdGhlIG5hbWUgXCIke25hbWV9XCJgKSB9XG4gICAgZWxzZSBpZihpbnB1dHMubGVuZ3RoID4gMSl7IGxvZ0Vycm9yKGBkdXBsaWNhdGUgbGl2ZSBmaWxlIGlucHV0cyBmb3VuZCBtYXRjaGluZyB0aGUgbmFtZSBcIiR7bmFtZX1cImApIH1cbiAgICBlbHNlIHsgRE9NLmRpc3BhdGNoRXZlbnQoaW5wdXRzWzBdLCBQSFhfVFJBQ0tfVVBMT0FEUywge2RldGFpbDoge2ZpbGVzOiBmaWxlc09yQmxvYnN9fSkgfVxuICB9XG5cbiAgcHVzaEZvcm1SZWNvdmVyeShmb3JtLCBuZXdDaWQsIGNhbGxiYWNrKXtcbiAgICB0aGlzLmxpdmVTb2NrZXQud2l0aGluT3duZXJzKGZvcm0sICh2aWV3LCB0YXJnZXRDdHgpID0+IHtcbiAgICAgIGxldCBwaHhDaGFuZ2UgPSB0aGlzLmJpbmRpbmcoXCJjaGFuZ2VcIilcbiAgICAgIGxldCBpbnB1dHMgPSBBcnJheS5mcm9tKGZvcm0uZWxlbWVudHMpLmZpbHRlcihlbCA9PiBET00uaXNGb3JtSW5wdXQoZWwpICYmIGVsLm5hbWUgJiYgIWVsLmhhc0F0dHJpYnV0ZShwaHhDaGFuZ2UpKVxuICAgICAgaWYoaW5wdXRzLmxlbmd0aCA9PT0gMCl7IHJldHVybiB9XG5cbiAgICAgIC8vIHdlIG11c3QgY2xlYXIgdHJhY2tlZCB1cGxvYWRzIGJlZm9yZSByZWNvdmVyeSBhcyB0aGV5IG5vIGxvbmdlciBoYXZlIHZhbGlkIHJlZnNcbiAgICAgIGlucHV0cy5mb3JFYWNoKGlucHV0ID0+IGlucHV0Lmhhc0F0dHJpYnV0ZShQSFhfVVBMT0FEX1JFRikgJiYgTGl2ZVVwbG9hZGVyLmNsZWFyRmlsZXMoaW5wdXQpKVxuICAgICAgbGV0IGlucHV0ID0gaW5wdXRzLmZpbmQoZWwgPT4gZWwudHlwZSAhPT0gXCJoaWRkZW5cIikgfHwgaW5wdXRzWzBdXG5cbiAgICAgIGxldCBwaHhFdmVudCA9IGZvcm0uZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhQSFhfQVVUT19SRUNPVkVSKSkgfHwgZm9ybS5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFwiY2hhbmdlXCIpKVxuICAgICAgSlMuZXhlYyhcImNoYW5nZVwiLCBwaHhFdmVudCwgdmlldywgaW5wdXQsIFtcInB1c2hcIiwge190YXJnZXQ6IGlucHV0Lm5hbWUsIG5ld0NpZDogbmV3Q2lkLCBjYWxsYmFjazogY2FsbGJhY2t9XSlcbiAgICB9KVxuICB9XG5cbiAgcHVzaExpbmtQYXRjaChocmVmLCB0YXJnZXRFbCwgY2FsbGJhY2spe1xuICAgIGxldCBsaW5rUmVmID0gdGhpcy5saXZlU29ja2V0LnNldFBlbmRpbmdMaW5rKGhyZWYpXG4gICAgbGV0IHJlZkdlbiA9IHRhcmdldEVsID8gKCkgPT4gdGhpcy5wdXRSZWYoW3RhcmdldEVsXSwgXCJjbGlja1wiKSA6IG51bGxcbiAgICBsZXQgZmFsbGJhY2sgPSAoKSA9PiB0aGlzLmxpdmVTb2NrZXQucmVkaXJlY3Qod2luZG93LmxvY2F0aW9uLmhyZWYpXG4gICAgbGV0IHVybCA9IGhyZWYuc3RhcnRzV2l0aChcIi9cIikgPyBgJHtsb2NhdGlvbi5wcm90b2NvbH0vLyR7bG9jYXRpb24uaG9zdH0ke2hyZWZ9YCA6IGhyZWZcblxuICAgIGxldCBwdXNoID0gdGhpcy5wdXNoV2l0aFJlcGx5KHJlZkdlbiwgXCJsaXZlX3BhdGNoXCIsIHt1cmx9LCByZXNwID0+IHtcbiAgICAgIHRoaXMubGl2ZVNvY2tldC5yZXF1ZXN0RE9NVXBkYXRlKCgpID0+IHtcbiAgICAgICAgaWYocmVzcC5saW5rX3JlZGlyZWN0KXtcbiAgICAgICAgICB0aGlzLmxpdmVTb2NrZXQucmVwbGFjZU1haW4oaHJlZiwgbnVsbCwgY2FsbGJhY2ssIGxpbmtSZWYpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYodGhpcy5saXZlU29ja2V0LmNvbW1pdFBlbmRpbmdMaW5rKGxpbmtSZWYpKXtcbiAgICAgICAgICAgIHRoaXMuaHJlZiA9IGhyZWZcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5hcHBseVBlbmRpbmdVcGRhdGVzKClcbiAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjayhsaW5rUmVmKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH0pXG5cbiAgICBpZihwdXNoKXtcbiAgICAgIHB1c2gucmVjZWl2ZShcInRpbWVvdXRcIiwgZmFsbGJhY2spXG4gICAgfSBlbHNlIHtcbiAgICAgIGZhbGxiYWNrKClcbiAgICB9XG4gIH1cblxuICBmb3Jtc0ZvclJlY292ZXJ5KGh0bWwpe1xuICAgIGlmKHRoaXMuam9pbkNvdW50ID09PSAwKXsgcmV0dXJuIFtdIH1cblxuICAgIGxldCBwaHhDaGFuZ2UgPSB0aGlzLmJpbmRpbmcoXCJjaGFuZ2VcIilcbiAgICBsZXQgdGVtcGxhdGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidGVtcGxhdGVcIilcbiAgICB0ZW1wbGF0ZS5pbm5lckhUTUwgPSBodG1sXG5cbiAgICByZXR1cm4gKFxuICAgICAgRE9NLmFsbCh0aGlzLmVsLCBgZm9ybVske3BoeENoYW5nZX1dYClcbiAgICAgICAgLmZpbHRlcihmb3JtID0+IGZvcm0uaWQgJiYgdGhpcy5vd25zRWxlbWVudChmb3JtKSlcbiAgICAgICAgLmZpbHRlcihmb3JtID0+IGZvcm0uZWxlbWVudHMubGVuZ3RoID4gMClcbiAgICAgICAgLmZpbHRlcihmb3JtID0+IGZvcm0uZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhQSFhfQVVUT19SRUNPVkVSKSkgIT09IFwiaWdub3JlXCIpXG4gICAgICAgIC5tYXAoZm9ybSA9PiB7XG4gICAgICAgICAgLy8gYXR0cmlidXRlIGdpdmVuIHZpYSBKUyBtb2R1bGUgbmVlZHMgdG8gYmUgZXNjYXBlZCBhcyBpdCBjb250YWlucyB0aGUgc3ltYm9scyBbXVwiLFxuICAgICAgICAgIC8vIHdoaWNoIHJlc3VsdCBpbiBhbiBpbnZhbGlkIGNzcyBzZWxlY3RvciBvdGhlcndpc2UuXG4gICAgICAgICAgY29uc3QgcGh4Q2hhbmdlVmFsdWUgPSBmb3JtLmdldEF0dHJpYnV0ZShwaHhDaGFuZ2UpLnJlcGxhY2VBbGwoLyhbXFxbXFxdXCJdKS9nLCAnXFxcXCQxJylcbiAgICAgICAgICBsZXQgbmV3Rm9ybSA9IHRlbXBsYXRlLmNvbnRlbnQucXVlcnlTZWxlY3RvcihgZm9ybVtpZD1cIiR7Zm9ybS5pZH1cIl1bJHtwaHhDaGFuZ2V9PVwiJHtwaHhDaGFuZ2VWYWx1ZX1cIl1gKVxuICAgICAgICAgIGlmKG5ld0Zvcm0pe1xuICAgICAgICAgICAgcmV0dXJuIFtmb3JtLCBuZXdGb3JtLCB0aGlzLnRhcmdldENvbXBvbmVudElEKG5ld0Zvcm0pXVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gW2Zvcm0sIGZvcm0sIHRoaXMudGFyZ2V0Q29tcG9uZW50SUQoZm9ybSldXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuZmlsdGVyKChbZm9ybSwgbmV3Rm9ybSwgbmV3Q2lkXSkgPT4gbmV3Rm9ybSlcbiAgICApXG4gIH1cblxuICBtYXliZVB1c2hDb21wb25lbnRzRGVzdHJveWVkKGRlc3Ryb3llZENJRHMpe1xuICAgIGxldCB3aWxsRGVzdHJveUNJRHMgPSBkZXN0cm95ZWRDSURzLmZpbHRlcihjaWQgPT4ge1xuICAgICAgcmV0dXJuIERPTS5maW5kQ29tcG9uZW50Tm9kZUxpc3QodGhpcy5lbCwgY2lkKS5sZW5ndGggPT09IDBcbiAgICB9KVxuICAgIGlmKHdpbGxEZXN0cm95Q0lEcy5sZW5ndGggPiAwKXtcbiAgICAgIHRoaXMucHJ1bmluZ0NJRHMucHVzaCguLi53aWxsRGVzdHJveUNJRHMpXG5cbiAgICAgIHRoaXMucHVzaFdpdGhSZXBseShudWxsLCBcImNpZHNfd2lsbF9kZXN0cm95XCIsIHtjaWRzOiB3aWxsRGVzdHJveUNJRHN9LCAoKSA9PiB7XG4gICAgICAgIC8vIFRoZSBjaWRzIGFyZSBlaXRoZXIgYmFjayBvbiB0aGUgcGFnZSBvciB0aGV5IHdpbGwgYmUgZnVsbHkgcmVtb3ZlZCxcbiAgICAgICAgLy8gc28gd2UgY2FuIHJlbW92ZSB0aGVtIGZyb20gdGhlIHBydW5pbmdDSURzLlxuICAgICAgICB0aGlzLnBydW5pbmdDSURzID0gdGhpcy5wcnVuaW5nQ0lEcy5maWx0ZXIoY2lkID0+IHdpbGxEZXN0cm95Q0lEcy5pbmRleE9mKGNpZCkgIT09IC0xKVxuXG4gICAgICAgIC8vIFNlZSBpZiBhbnkgb2YgdGhlIGNpZHMgd2Ugd2FudGVkIHRvIGRlc3Ryb3kgd2VyZSBhZGRlZCBiYWNrLFxuICAgICAgICAvLyBpZiB0aGV5IHdlcmUgYWRkZWQgYmFjaywgd2UgZG9uJ3QgYWN0dWFsbHkgZGVzdHJveSB0aGVtLlxuICAgICAgICBsZXQgY29tcGxldGVseURlc3Ryb3lDSURzID0gd2lsbERlc3Ryb3lDSURzLmZpbHRlcihjaWQgPT4ge1xuICAgICAgICAgIHJldHVybiBET00uZmluZENvbXBvbmVudE5vZGVMaXN0KHRoaXMuZWwsIGNpZCkubGVuZ3RoID09PSAwXG4gICAgICAgIH0pXG5cbiAgICAgICAgaWYoY29tcGxldGVseURlc3Ryb3lDSURzLmxlbmd0aCA+IDApe1xuICAgICAgICAgIHRoaXMucHVzaFdpdGhSZXBseShudWxsLCBcImNpZHNfZGVzdHJveWVkXCIsIHtjaWRzOiBjb21wbGV0ZWx5RGVzdHJveUNJRHN9LCAocmVzcCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJlZC5wcnVuZUNJRHMocmVzcC5jaWRzKVxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgb3duc0VsZW1lbnQoZWwpe1xuICAgIGxldCBwYXJlbnRWaWV3RWwgPSBlbC5jbG9zZXN0KFBIWF9WSUVXX1NFTEVDVE9SKVxuICAgIHJldHVybiBlbC5nZXRBdHRyaWJ1dGUoUEhYX1BBUkVOVF9JRCkgPT09IHRoaXMuaWQgfHxcbiAgICAgIChwYXJlbnRWaWV3RWwgJiYgcGFyZW50Vmlld0VsLmlkID09PSB0aGlzLmlkKSB8fFxuICAgICAgKCFwYXJlbnRWaWV3RWwgJiYgdGhpcy5pc0RlYWQpXG4gIH1cblxuICBzdWJtaXRGb3JtKGZvcm0sIHRhcmdldEN0eCwgcGh4RXZlbnQsIHN1Ym1pdHRlciwgb3B0cyA9IHt9KXtcbiAgICBET00ucHV0UHJpdmF0ZShmb3JtLCBQSFhfSEFTX1NVQk1JVFRFRCwgdHJ1ZSlcbiAgICBsZXQgcGh4RmVlZGJhY2sgPSB0aGlzLmxpdmVTb2NrZXQuYmluZGluZyhQSFhfRkVFREJBQ0tfRk9SKVxuICAgIGxldCBpbnB1dHMgPSBBcnJheS5mcm9tKGZvcm0uZWxlbWVudHMpXG4gICAgaW5wdXRzLmZvckVhY2goaW5wdXQgPT4gRE9NLnB1dFByaXZhdGUoaW5wdXQsIFBIWF9IQVNfU1VCTUlUVEVELCB0cnVlKSlcbiAgICB0aGlzLmxpdmVTb2NrZXQuYmx1ckFjdGl2ZUVsZW1lbnQodGhpcylcbiAgICB0aGlzLnB1c2hGb3JtU3VibWl0KGZvcm0sIHRhcmdldEN0eCwgcGh4RXZlbnQsIHN1Ym1pdHRlciwgb3B0cywgKCkgPT4ge1xuICAgICAgaW5wdXRzLmZvckVhY2goaW5wdXQgPT4gRE9NLnNob3dFcnJvcihpbnB1dCwgcGh4RmVlZGJhY2spKVxuICAgICAgdGhpcy5saXZlU29ja2V0LnJlc3RvcmVQcmV2aW91c2x5QWN0aXZlRm9jdXMoKVxuICAgIH0pXG4gIH1cblxuICBiaW5kaW5nKGtpbmQpeyByZXR1cm4gdGhpcy5saXZlU29ja2V0LmJpbmRpbmcoa2luZCkgfVxufVxuIiwgIi8qKiBJbml0aWFsaXplcyB0aGUgTGl2ZVNvY2tldFxuICpcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZW5kUG9pbnQgLSBUaGUgc3RyaW5nIFdlYlNvY2tldCBlbmRwb2ludCwgaWUsIGBcIndzczovL2V4YW1wbGUuY29tL2xpdmVcImAsXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYFwiL2xpdmVcImAgKGluaGVyaXRlZCBob3N0ICYgcHJvdG9jb2wpXG4gKiBAcGFyYW0ge1Bob2VuaXguU29ja2V0fSBzb2NrZXQgLSB0aGUgcmVxdWlyZWQgUGhvZW5peCBTb2NrZXQgY2xhc3MgaW1wb3J0ZWQgZnJvbSBcInBob2VuaXhcIi4gRm9yIGV4YW1wbGU6XG4gKlxuICogICAgIGltcG9ydCB7U29ja2V0fSBmcm9tIFwicGhvZW5peFwiXG4gKiAgICAgaW1wb3J0IHtMaXZlU29ja2V0fSBmcm9tIFwicGhvZW5peF9saXZlX3ZpZXdcIlxuICogICAgIGxldCBsaXZlU29ja2V0ID0gbmV3IExpdmVTb2NrZXQoXCIvbGl2ZVwiLCBTb2NrZXQsIHsuLi59KVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0c10gLSBPcHRpb25hbCBjb25maWd1cmF0aW9uLiBPdXRzaWRlIG9mIGtleXMgbGlzdGVkIGJlbG93LCBhbGxcbiAqIGNvbmZpZ3VyYXRpb24gaXMgcGFzc2VkIGRpcmVjdGx5IHRvIHRoZSBQaG9lbml4IFNvY2tldCBjb25zdHJ1Y3Rvci5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0cy5kZWZhdWx0c10gLSBUaGUgb3B0aW9uYWwgZGVmYXVsdHMgdG8gdXNlIGZvciB2YXJpb3VzIGJpbmRpbmdzLFxuICogc3VjaCBhcyBgcGh4LWRlYm91bmNlYC4gU3VwcG9ydHMgdGhlIGZvbGxvd2luZyBrZXlzOlxuICpcbiAqICAgLSBkZWJvdW5jZSAtIHRoZSBtaWxsaXNlY29uZCBwaHgtZGVib3VuY2UgdGltZS4gRGVmYXVsdHMgMzAwXG4gKiAgIC0gdGhyb3R0bGUgLSB0aGUgbWlsbGlzZWNvbmQgcGh4LXRocm90dGxlIHRpbWUuIERlZmF1bHRzIDMwMFxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRzLnBhcmFtc10gLSBUaGUgb3B0aW9uYWwgZnVuY3Rpb24gZm9yIHBhc3NpbmcgY29ubmVjdCBwYXJhbXMuXG4gKiBUaGUgZnVuY3Rpb24gcmVjZWl2ZXMgdGhlIGVsZW1lbnQgYXNzb2NpYXRlZCB3aXRoIGEgZ2l2ZW4gTGl2ZVZpZXcuIEZvciBleGFtcGxlOlxuICpcbiAqICAgICAoZWwpID0+IHt2aWV3OiBlbC5nZXRBdHRyaWJ1dGUoXCJkYXRhLW15LXZpZXctbmFtZVwiLCB0b2tlbjogd2luZG93Lm15VG9rZW59XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmJpbmRpbmdQcmVmaXhdIC0gVGhlIG9wdGlvbmFsIHByZWZpeCB0byB1c2UgZm9yIGFsbCBwaHggRE9NIGFubm90YXRpb25zLlxuICogRGVmYXVsdHMgdG8gXCJwaHgtXCIuXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdHMuaG9va3NdIC0gVGhlIG9wdGlvbmFsIG9iamVjdCBmb3IgcmVmZXJlbmNpbmcgTGl2ZVZpZXcgaG9vayBjYWxsYmFja3MuXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdHMudXBsb2FkZXJzXSAtIFRoZSBvcHRpb25hbCBvYmplY3QgZm9yIHJlZmVyZW5jaW5nIExpdmVWaWV3IHVwbG9hZGVyIGNhbGxiYWNrcy5cbiAqIEBwYXJhbSB7aW50ZWdlcn0gW29wdHMubG9hZGVyVGltZW91dF0gLSBUaGUgb3B0aW9uYWwgZGVsYXkgaW4gbWlsbGlzZWNvbmRzIHRvIHdhaXQgYmVmb3JlIGFwcGx5XG4gKiBsb2FkaW5nIHN0YXRlcy5cbiAqIEBwYXJhbSB7aW50ZWdlcn0gW29wdHMubWF4UmVsb2Fkc10gLSBUaGUgbWF4aW11bSByZWxvYWRzIGJlZm9yZSBlbnRlcmluZyBmYWlsc2FmZSBtb2RlLlxuICogQHBhcmFtIHtpbnRlZ2VyfSBbb3B0cy5yZWxvYWRKaXR0ZXJNaW5dIC0gVGhlIG1pbmltdW0gdGltZSBiZXR3ZWVuIG5vcm1hbCByZWxvYWQgYXR0ZW1wdHMuXG4gKiBAcGFyYW0ge2ludGVnZXJ9IFtvcHRzLnJlbG9hZEppdHRlck1heF0gLSBUaGUgbWF4aW11bSB0aW1lIGJldHdlZW4gbm9ybWFsIHJlbG9hZCBhdHRlbXB0cy5cbiAqIEBwYXJhbSB7aW50ZWdlcn0gW29wdHMuZmFpbHNhZmVKaXR0ZXJdIC0gVGhlIHRpbWUgYmV0d2VlbiByZWxvYWQgYXR0ZW1wdHMgaW4gZmFpbHNhZmUgbW9kZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRzLnZpZXdMb2dnZXJdIC0gVGhlIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGxvZyBkZWJ1ZyBpbmZvcm1hdGlvbi4gRm9yIGV4YW1wbGU6XG4gKlxuICogICAgICh2aWV3LCBraW5kLCBtc2csIG9iaikgPT4gY29uc29sZS5sb2coYCR7dmlldy5pZH0gJHtraW5kfTogJHttc2d9IC0gYCwgb2JqKVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0cy5tZXRhZGF0YV0gLSBUaGUgb3B0aW9uYWwgb2JqZWN0IG1hcHBpbmcgZXZlbnQgbmFtZXMgdG8gZnVuY3Rpb25zIGZvclxuICogcG9wdWxhdGluZyBldmVudCBtZXRhZGF0YS4gRm9yIGV4YW1wbGU6XG4gKlxuICogICAgIG1ldGFkYXRhOiB7XG4gKiAgICAgICBjbGljazogKGUsIGVsKSA9PiB7XG4gKiAgICAgICAgIHJldHVybiB7XG4gKiAgICAgICAgICAgY3RybEtleTogZS5jdHJsS2V5LFxuICogICAgICAgICAgIG1ldGFLZXk6IGUubWV0YUtleSxcbiAqICAgICAgICAgICBkZXRhaWw6IGUuZGV0YWlsIHx8IDEsXG4gKiAgICAgICAgIH1cbiAqICAgICAgIH0sXG4gKiAgICAgICBrZXlkb3duOiAoZSwgZWwpID0+IHtcbiAqICAgICAgICAgcmV0dXJuIHtcbiAqICAgICAgICAgICBrZXk6IGUua2V5LFxuICogICAgICAgICAgIGN0cmxLZXk6IGUuY3RybEtleSxcbiAqICAgICAgICAgICBtZXRhS2V5OiBlLm1ldGFLZXksXG4gKiAgICAgICAgICAgc2hpZnRLZXk6IGUuc2hpZnRLZXlcbiAqICAgICAgICAgfVxuICogICAgICAgfVxuICogICAgIH1cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0cy5zZXNzaW9uU3RvcmFnZV0gLSBBbiBvcHRpb25hbCBTdG9yYWdlIGNvbXBhdGlibGUgb2JqZWN0XG4gKiBVc2VmdWwgd2hlbiBMaXZlVmlldyB3b24ndCBoYXZlIGFjY2VzcyB0byBgc2Vzc2lvblN0b3JhZ2VgLiAgRm9yIGV4YW1wbGUsIFRoaXMgY291bGRcbiAqIGhhcHBlbiBpZiBhIHNpdGUgbG9hZHMgYSBjcm9zcy1kb21haW4gTGl2ZVZpZXcgaW4gYW4gaWZyYW1lLiAgRXhhbXBsZSB1c2FnZTpcbiAqXG4gKiAgICAgY2xhc3MgSW5NZW1vcnlTdG9yYWdlIHtcbiAqICAgICAgIGNvbnN0cnVjdG9yKCkgeyB0aGlzLnN0b3JhZ2UgPSB7fSB9XG4gKiAgICAgICBnZXRJdGVtKGtleU5hbWUpIHsgcmV0dXJuIHRoaXMuc3RvcmFnZVtrZXlOYW1lXSB8fCBudWxsIH1cbiAqICAgICAgIHJlbW92ZUl0ZW0oa2V5TmFtZSkgeyBkZWxldGUgdGhpcy5zdG9yYWdlW2tleU5hbWVdIH1cbiAqICAgICAgIHNldEl0ZW0oa2V5TmFtZSwga2V5VmFsdWUpIHsgdGhpcy5zdG9yYWdlW2tleU5hbWVdID0ga2V5VmFsdWUgfVxuICogICAgIH1cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdHMubG9jYWxTdG9yYWdlXSAtIEFuIG9wdGlvbmFsIFN0b3JhZ2UgY29tcGF0aWJsZSBvYmplY3RcbiAqIFVzZWZ1bCBmb3Igd2hlbiBMaXZlVmlldyB3b24ndCBoYXZlIGFjY2VzcyB0byBgbG9jYWxTdG9yYWdlYC5cbiAqIFNlZSBgb3B0cy5zZXNzaW9uU3RvcmFnZWAgZm9yIGV4YW1wbGVzLlxuKi9cblxuaW1wb3J0IHtcbiAgQklORElOR19QUkVGSVgsXG4gIENPTlNFQ1VUSVZFX1JFTE9BRFMsXG4gIERFRkFVTFRTLFxuICBGQUlMU0FGRV9KSVRURVIsXG4gIExPQURFUl9USU1FT1VULFxuICBNQVhfUkVMT0FEUyxcbiAgUEhYX0RFQk9VTkNFLFxuICBQSFhfRFJPUF9UQVJHRVQsXG4gIFBIWF9IQVNfRk9DVVNFRCxcbiAgUEhYX0tFWSxcbiAgUEhYX0xJTktfU1RBVEUsXG4gIFBIWF9MSVZFX0xJTkssXG4gIFBIWF9MVl9ERUJVRyxcbiAgUEhYX0xWX0xBVEVOQ1lfU0lNLFxuICBQSFhfTFZfUFJPRklMRSxcbiAgUEhYX01BSU4sXG4gIFBIWF9QQVJFTlRfSUQsXG4gIFBIWF9WSUVXX1NFTEVDVE9SLFxuICBQSFhfUk9PVF9JRCxcbiAgUEhYX1RIUk9UVExFLFxuICBQSFhfVFJBQ0tfVVBMT0FEUyxcbiAgUEhYX1NFU1NJT04sXG4gIFBIWF9GRUVEQkFDS19GT1IsXG4gIFJFTE9BRF9KSVRURVJfTUlOLFxuICBSRUxPQURfSklUVEVSX01BWCxcbiAgUEhYX1JFRixcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCJcblxuaW1wb3J0IHtcbiAgY2xvbmUsXG4gIGNsb3Nlc3RQaHhCaW5kaW5nLFxuICBjbG9zdXJlLFxuICBkZWJ1ZyxcbiAgaXNPYmplY3QsXG4gIG1heWJlXG59IGZyb20gXCIuL3V0aWxzXCJcblxuaW1wb3J0IEJyb3dzZXIgZnJvbSBcIi4vYnJvd3NlclwiXG5pbXBvcnQgRE9NIGZyb20gXCIuL2RvbVwiXG5pbXBvcnQgSG9va3MgZnJvbSBcIi4vaG9va3NcIlxuaW1wb3J0IExpdmVVcGxvYWRlciBmcm9tIFwiLi9saXZlX3VwbG9hZGVyXCJcbmltcG9ydCBWaWV3IGZyb20gXCIuL3ZpZXdcIlxuaW1wb3J0IEpTIGZyb20gXCIuL2pzXCJcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTGl2ZVNvY2tldCB7XG4gIGNvbnN0cnVjdG9yKHVybCwgcGh4U29ja2V0LCBvcHRzID0ge30pe1xuICAgIHRoaXMudW5sb2FkZWQgPSBmYWxzZVxuICAgIGlmKCFwaHhTb2NrZXQgfHwgcGh4U29ja2V0LmNvbnN0cnVjdG9yLm5hbWUgPT09IFwiT2JqZWN0XCIpe1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBcbiAgICAgIGEgcGhvZW5peCBTb2NrZXQgbXVzdCBiZSBwcm92aWRlZCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIHRoZSBMaXZlU29ja2V0IGNvbnN0cnVjdG9yLiBGb3IgZXhhbXBsZTpcblxuICAgICAgICAgIGltcG9ydCB7U29ja2V0fSBmcm9tIFwicGhvZW5peFwiXG4gICAgICAgICAgaW1wb3J0IHtMaXZlU29ja2V0fSBmcm9tIFwicGhvZW5peF9saXZlX3ZpZXdcIlxuICAgICAgICAgIGxldCBsaXZlU29ja2V0ID0gbmV3IExpdmVTb2NrZXQoXCIvbGl2ZVwiLCBTb2NrZXQsIHsuLi59KVxuICAgICAgYClcbiAgICB9XG4gICAgdGhpcy5zb2NrZXQgPSBuZXcgcGh4U29ja2V0KHVybCwgb3B0cylcbiAgICB0aGlzLmJpbmRpbmdQcmVmaXggPSBvcHRzLmJpbmRpbmdQcmVmaXggfHwgQklORElOR19QUkVGSVhcbiAgICB0aGlzLm9wdHMgPSBvcHRzXG4gICAgdGhpcy5wYXJhbXMgPSBjbG9zdXJlKG9wdHMucGFyYW1zIHx8IHt9KVxuICAgIHRoaXMudmlld0xvZ2dlciA9IG9wdHMudmlld0xvZ2dlclxuICAgIHRoaXMubWV0YWRhdGFDYWxsYmFja3MgPSBvcHRzLm1ldGFkYXRhIHx8IHt9XG4gICAgdGhpcy5kZWZhdWx0cyA9IE9iamVjdC5hc3NpZ24oY2xvbmUoREVGQVVMVFMpLCBvcHRzLmRlZmF1bHRzIHx8IHt9KVxuICAgIHRoaXMuYWN0aXZlRWxlbWVudCA9IG51bGxcbiAgICB0aGlzLnByZXZBY3RpdmUgPSBudWxsXG4gICAgdGhpcy5zaWxlbmNlZCA9IGZhbHNlXG4gICAgdGhpcy5tYWluID0gbnVsbFxuICAgIHRoaXMub3V0Z29pbmdNYWluRWwgPSBudWxsXG4gICAgdGhpcy5jbGlja1N0YXJ0ZWRBdFRhcmdldCA9IG51bGxcbiAgICB0aGlzLmxpbmtSZWYgPSAxXG4gICAgdGhpcy5yb290cyA9IHt9XG4gICAgdGhpcy5ocmVmID0gd2luZG93LmxvY2F0aW9uLmhyZWZcbiAgICB0aGlzLnBlbmRpbmdMaW5rID0gbnVsbFxuICAgIHRoaXMuY3VycmVudExvY2F0aW9uID0gY2xvbmUod2luZG93LmxvY2F0aW9uKVxuICAgIHRoaXMuaG9va3MgPSBvcHRzLmhvb2tzIHx8IHt9XG4gICAgdGhpcy51cGxvYWRlcnMgPSBvcHRzLnVwbG9hZGVycyB8fCB7fVxuICAgIHRoaXMubG9hZGVyVGltZW91dCA9IG9wdHMubG9hZGVyVGltZW91dCB8fCBMT0FERVJfVElNRU9VVFxuICAgIHRoaXMucmVsb2FkV2l0aEppdHRlclRpbWVyID0gbnVsbFxuICAgIHRoaXMubWF4UmVsb2FkcyA9IG9wdHMubWF4UmVsb2FkcyB8fCBNQVhfUkVMT0FEU1xuICAgIHRoaXMucmVsb2FkSml0dGVyTWluID0gb3B0cy5yZWxvYWRKaXR0ZXJNaW4gfHwgUkVMT0FEX0pJVFRFUl9NSU5cbiAgICB0aGlzLnJlbG9hZEppdHRlck1heCA9IG9wdHMucmVsb2FkSml0dGVyTWF4IHx8IFJFTE9BRF9KSVRURVJfTUFYXG4gICAgdGhpcy5mYWlsc2FmZUppdHRlciA9IG9wdHMuZmFpbHNhZmVKaXR0ZXIgfHwgRkFJTFNBRkVfSklUVEVSXG4gICAgdGhpcy5sb2NhbFN0b3JhZ2UgPSBvcHRzLmxvY2FsU3RvcmFnZSB8fCB3aW5kb3cubG9jYWxTdG9yYWdlXG4gICAgdGhpcy5zZXNzaW9uU3RvcmFnZSA9IG9wdHMuc2Vzc2lvblN0b3JhZ2UgfHwgd2luZG93LnNlc3Npb25TdG9yYWdlXG4gICAgdGhpcy5ib3VuZFRvcExldmVsRXZlbnRzID0gZmFsc2VcbiAgICB0aGlzLmRvbUNhbGxiYWNrcyA9IE9iamVjdC5hc3NpZ24oe29uTm9kZUFkZGVkOiBjbG9zdXJlKCksIG9uQmVmb3JlRWxVcGRhdGVkOiBjbG9zdXJlKCl9LCBvcHRzLmRvbSB8fCB7fSlcbiAgICB0aGlzLnRyYW5zaXRpb25zID0gbmV3IFRyYW5zaXRpb25TZXQoKVxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicGFnZWhpZGVcIiwgX2UgPT4ge1xuICAgICAgdGhpcy51bmxvYWRlZCA9IHRydWVcbiAgICB9KVxuICAgIHRoaXMuc29ja2V0Lm9uT3BlbigoKSA9PiB7XG4gICAgICBpZih0aGlzLmlzVW5sb2FkZWQoKSl7XG4gICAgICAgIC8vIHJlbG9hZCBwYWdlIGlmIGJlaW5nIHJlc3RvcmVkIGZyb20gYmFjay9mb3J3YXJkIGNhY2hlIGFuZCBicm93c2VyIGRvZXMgbm90IGVtaXQgXCJwYWdlc2hvd1wiXG4gICAgICAgIHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICAvLyBwdWJsaWNcblxuICBpc1Byb2ZpbGVFbmFibGVkKCl7IHJldHVybiB0aGlzLnNlc3Npb25TdG9yYWdlLmdldEl0ZW0oUEhYX0xWX1BST0ZJTEUpID09PSBcInRydWVcIiB9XG5cbiAgaXNEZWJ1Z0VuYWJsZWQoKXsgcmV0dXJuIHRoaXMuc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbShQSFhfTFZfREVCVUcpID09PSBcInRydWVcIiB9XG5cbiAgaXNEZWJ1Z0Rpc2FibGVkKCl7IHJldHVybiB0aGlzLnNlc3Npb25TdG9yYWdlLmdldEl0ZW0oUEhYX0xWX0RFQlVHKSA9PT0gXCJmYWxzZVwiIH1cblxuICBlbmFibGVEZWJ1ZygpeyB0aGlzLnNlc3Npb25TdG9yYWdlLnNldEl0ZW0oUEhYX0xWX0RFQlVHLCBcInRydWVcIikgfVxuXG4gIGVuYWJsZVByb2ZpbGluZygpeyB0aGlzLnNlc3Npb25TdG9yYWdlLnNldEl0ZW0oUEhYX0xWX1BST0ZJTEUsIFwidHJ1ZVwiKSB9XG5cbiAgZGlzYWJsZURlYnVnKCl7IHRoaXMuc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShQSFhfTFZfREVCVUcsIFwiZmFsc2VcIikgfVxuXG4gIGRpc2FibGVQcm9maWxpbmcoKXsgdGhpcy5zZXNzaW9uU3RvcmFnZS5yZW1vdmVJdGVtKFBIWF9MVl9QUk9GSUxFKSB9XG5cbiAgZW5hYmxlTGF0ZW5jeVNpbSh1cHBlckJvdW5kTXMpe1xuICAgIHRoaXMuZW5hYmxlRGVidWcoKVxuICAgIGNvbnNvbGUubG9nKFwibGF0ZW5jeSBzaW11bGF0b3IgZW5hYmxlZCBmb3IgdGhlIGR1cmF0aW9uIG9mIHRoaXMgYnJvd3NlciBzZXNzaW9uLiBDYWxsIGRpc2FibGVMYXRlbmN5U2ltKCkgdG8gZGlzYWJsZVwiKVxuICAgIHRoaXMuc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShQSFhfTFZfTEFURU5DWV9TSU0sIHVwcGVyQm91bmRNcylcbiAgfVxuXG4gIGRpc2FibGVMYXRlbmN5U2ltKCl7IHRoaXMuc2Vzc2lvblN0b3JhZ2UucmVtb3ZlSXRlbShQSFhfTFZfTEFURU5DWV9TSU0pIH1cblxuICBnZXRMYXRlbmN5U2ltKCl7XG4gICAgbGV0IHN0ciA9IHRoaXMuc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbShQSFhfTFZfTEFURU5DWV9TSU0pXG4gICAgcmV0dXJuIHN0ciA/IHBhcnNlSW50KHN0cikgOiBudWxsXG4gIH1cblxuICBnZXRTb2NrZXQoKXsgcmV0dXJuIHRoaXMuc29ja2V0IH1cblxuICBjb25uZWN0KCl7XG4gICAgLy8gZW5hYmxlIGRlYnVnIGJ5IGRlZmF1bHQgaWYgb24gbG9jYWxob3N0IGFuZCBub3QgZXhwbGljaXRseSBkaXNhYmxlZFxuICAgIGlmKHdpbmRvdy5sb2NhdGlvbi5ob3N0bmFtZSA9PT0gXCJsb2NhbGhvc3RcIiAmJiAhdGhpcy5pc0RlYnVnRGlzYWJsZWQoKSl7IHRoaXMuZW5hYmxlRGVidWcoKSB9XG4gICAgbGV0IGRvQ29ubmVjdCA9ICgpID0+IHtcbiAgICAgIGlmKHRoaXMuam9pblJvb3RWaWV3cygpKXtcbiAgICAgICAgdGhpcy5iaW5kVG9wTGV2ZWxFdmVudHMoKVxuICAgICAgICB0aGlzLnNvY2tldC5jb25uZWN0KClcbiAgICAgIH0gZWxzZSBpZih0aGlzLm1haW4pe1xuICAgICAgICB0aGlzLnNvY2tldC5jb25uZWN0KClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYmluZFRvcExldmVsRXZlbnRzKHtkZWFkOiB0cnVlfSlcbiAgICAgIH1cbiAgICAgIHRoaXMuam9pbkRlYWRWaWV3KClcbiAgICB9XG4gICAgaWYoW1wiY29tcGxldGVcIiwgXCJsb2FkZWRcIiwgXCJpbnRlcmFjdGl2ZVwiXS5pbmRleE9mKGRvY3VtZW50LnJlYWR5U3RhdGUpID49IDApe1xuICAgICAgZG9Db25uZWN0KClcbiAgICB9IGVsc2Uge1xuICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIkRPTUNvbnRlbnRMb2FkZWRcIiwgKCkgPT4gZG9Db25uZWN0KCkpXG4gICAgfVxuICB9XG5cbiAgZGlzY29ubmVjdChjYWxsYmFjayl7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMucmVsb2FkV2l0aEppdHRlclRpbWVyKVxuICAgIHRoaXMuc29ja2V0LmRpc2Nvbm5lY3QoY2FsbGJhY2spXG4gIH1cblxuICByZXBsYWNlVHJhbnNwb3J0KHRyYW5zcG9ydCl7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMucmVsb2FkV2l0aEppdHRlclRpbWVyKVxuICAgIHRoaXMuc29ja2V0LnJlcGxhY2VUcmFuc3BvcnQodHJhbnNwb3J0KVxuICAgIHRoaXMuY29ubmVjdCgpXG4gIH1cblxuICBleGVjSlMoZWwsIGVuY29kZWRKUywgZXZlbnRUeXBlID0gbnVsbCl7XG4gICAgdGhpcy5vd25lcihlbCwgdmlldyA9PiBKUy5leGVjKGV2ZW50VHlwZSwgZW5jb2RlZEpTLCB2aWV3LCBlbCkpXG4gIH1cblxuICAvLyBwcml2YXRlXG5cbiAgZXhlY0pTSG9va1B1c2goZWwsIHBoeEV2ZW50LCBkYXRhLCBjYWxsYmFjayl7XG4gICAgdGhpcy53aXRoaW5Pd25lcnMoZWwsIHZpZXcgPT4ge1xuICAgICAgSlMuZXhlYyhcImhvb2tcIiwgcGh4RXZlbnQsIHZpZXcsIGVsLCBbXCJwdXNoXCIsIHtkYXRhLCBjYWxsYmFja31dKVxuICAgIH0pXG4gIH1cblxuICB1bmxvYWQoKXtcbiAgICBpZih0aGlzLnVubG9hZGVkKXsgcmV0dXJuIH1cbiAgICBpZih0aGlzLm1haW4gJiYgdGhpcy5pc0Nvbm5lY3RlZCgpKXsgdGhpcy5sb2codGhpcy5tYWluLCBcInNvY2tldFwiLCAoKSA9PiBbXCJkaXNjb25uZWN0IGZvciBwYWdlIG5hdlwiXSkgfVxuICAgIHRoaXMudW5sb2FkZWQgPSB0cnVlXG4gICAgdGhpcy5kZXN0cm95QWxsVmlld3MoKVxuICAgIHRoaXMuZGlzY29ubmVjdCgpXG4gIH1cblxuICB0cmlnZ2VyRE9NKGtpbmQsIGFyZ3MpeyB0aGlzLmRvbUNhbGxiYWNrc1traW5kXSguLi5hcmdzKSB9XG5cbiAgdGltZShuYW1lLCBmdW5jKXtcbiAgICBpZighdGhpcy5pc1Byb2ZpbGVFbmFibGVkKCkgfHwgIWNvbnNvbGUudGltZSl7IHJldHVybiBmdW5jKCkgfVxuICAgIGNvbnNvbGUudGltZShuYW1lKVxuICAgIGxldCByZXN1bHQgPSBmdW5jKClcbiAgICBjb25zb2xlLnRpbWVFbmQobmFtZSlcbiAgICByZXR1cm4gcmVzdWx0XG4gIH1cblxuICBsb2codmlldywga2luZCwgbXNnQ2FsbGJhY2spe1xuICAgIGlmKHRoaXMudmlld0xvZ2dlcil7XG4gICAgICBsZXQgW21zZywgb2JqXSA9IG1zZ0NhbGxiYWNrKClcbiAgICAgIHRoaXMudmlld0xvZ2dlcih2aWV3LCBraW5kLCBtc2csIG9iailcbiAgICB9IGVsc2UgaWYodGhpcy5pc0RlYnVnRW5hYmxlZCgpKXtcbiAgICAgIGxldCBbbXNnLCBvYmpdID0gbXNnQ2FsbGJhY2soKVxuICAgICAgZGVidWcodmlldywga2luZCwgbXNnLCBvYmopXG4gICAgfVxuICB9XG5cbiAgcmVxdWVzdERPTVVwZGF0ZShjYWxsYmFjayl7XG4gICAgdGhpcy50cmFuc2l0aW9ucy5hZnRlcihjYWxsYmFjaylcbiAgfVxuXG4gIHRyYW5zaXRpb24odGltZSwgb25TdGFydCwgb25Eb25lID0gZnVuY3Rpb24oKXt9KXtcbiAgICB0aGlzLnRyYW5zaXRpb25zLmFkZFRyYW5zaXRpb24odGltZSwgb25TdGFydCwgb25Eb25lKVxuICB9XG5cbiAgb25DaGFubmVsKGNoYW5uZWwsIGV2ZW50LCBjYil7XG4gICAgY2hhbm5lbC5vbihldmVudCwgZGF0YSA9PiB7XG4gICAgICBsZXQgbGF0ZW5jeSA9IHRoaXMuZ2V0TGF0ZW5jeVNpbSgpXG4gICAgICBpZighbGF0ZW5jeSl7XG4gICAgICAgIGNiKGRhdGEpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IGNiKGRhdGEpLCBsYXRlbmN5KVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICB3cmFwUHVzaCh2aWV3LCBvcHRzLCBwdXNoKXtcbiAgICBsZXQgbGF0ZW5jeSA9IHRoaXMuZ2V0TGF0ZW5jeVNpbSgpXG4gICAgbGV0IG9sZEpvaW5Db3VudCA9IHZpZXcuam9pbkNvdW50XG4gICAgaWYoIWxhdGVuY3kpe1xuICAgICAgaWYodGhpcy5pc0Nvbm5lY3RlZCgpICYmIG9wdHMudGltZW91dCl7XG4gICAgICAgIHJldHVybiBwdXNoKCkucmVjZWl2ZShcInRpbWVvdXRcIiwgKCkgPT4ge1xuICAgICAgICAgIGlmKHZpZXcuam9pbkNvdW50ID09PSBvbGRKb2luQ291bnQgJiYgIXZpZXcuaXNEZXN0cm95ZWQoKSl7XG4gICAgICAgICAgICB0aGlzLnJlbG9hZFdpdGhKaXR0ZXIodmlldywgKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLmxvZyh2aWV3LCBcInRpbWVvdXRcIiwgKCkgPT4gW1wicmVjZWl2ZWQgdGltZW91dCB3aGlsZSBjb21tdW5pY2F0aW5nIHdpdGggc2VydmVyLiBGYWxsaW5nIGJhY2sgdG8gaGFyZCByZWZyZXNoIGZvciByZWNvdmVyeVwiXSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHB1c2goKVxuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBmYWtlUHVzaCA9IHtcbiAgICAgIHJlY2VpdmVzOiBbXSxcbiAgICAgIHJlY2VpdmUoa2luZCwgY2IpeyB0aGlzLnJlY2VpdmVzLnB1c2goW2tpbmQsIGNiXSkgfVxuICAgIH1cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmKHZpZXcuaXNEZXN0cm95ZWQoKSl7IHJldHVybiB9XG4gICAgICBmYWtlUHVzaC5yZWNlaXZlcy5yZWR1Y2UoKGFjYywgW2tpbmQsIGNiXSkgPT4gYWNjLnJlY2VpdmUoa2luZCwgY2IpLCBwdXNoKCkpXG4gICAgfSwgbGF0ZW5jeSlcbiAgICByZXR1cm4gZmFrZVB1c2hcbiAgfVxuXG4gIHJlbG9hZFdpdGhKaXR0ZXIodmlldywgbG9nKXtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5yZWxvYWRXaXRoSml0dGVyVGltZXIpXG4gICAgdGhpcy5kaXNjb25uZWN0KClcbiAgICBsZXQgbWluTXMgPSB0aGlzLnJlbG9hZEppdHRlck1pblxuICAgIGxldCBtYXhNcyA9IHRoaXMucmVsb2FkSml0dGVyTWF4XG4gICAgbGV0IGFmdGVyTXMgPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAobWF4TXMgLSBtaW5NcyArIDEpKSArIG1pbk1zXG4gICAgbGV0IHRyaWVzID0gQnJvd3Nlci51cGRhdGVMb2NhbCh0aGlzLmxvY2FsU3RvcmFnZSwgd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLCBDT05TRUNVVElWRV9SRUxPQURTLCAwLCBjb3VudCA9PiBjb3VudCArIDEpXG4gICAgaWYodHJpZXMgPiB0aGlzLm1heFJlbG9hZHMpe1xuICAgICAgYWZ0ZXJNcyA9IHRoaXMuZmFpbHNhZmVKaXR0ZXJcbiAgICB9XG4gICAgdGhpcy5yZWxvYWRXaXRoSml0dGVyVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIC8vIGlmIHZpZXcgaGFzIHJlY292ZXJlZCwgc3VjaCBhcyB0cmFuc3BvcnQgcmVwbGFjZWQsIHRoZW4gY2FuY2VsXG4gICAgICBpZih2aWV3LmlzRGVzdHJveWVkKCkgfHwgdmlldy5pc0Nvbm5lY3RlZCgpKXsgcmV0dXJuIH1cbiAgICAgIHZpZXcuZGVzdHJveSgpXG4gICAgICBsb2cgPyBsb2coKSA6IHRoaXMubG9nKHZpZXcsIFwiam9pblwiLCAoKSA9PiBbYGVuY291bnRlcmVkICR7dHJpZXN9IGNvbnNlY3V0aXZlIHJlbG9hZHNgXSlcbiAgICAgIGlmKHRyaWVzID4gdGhpcy5tYXhSZWxvYWRzKXtcbiAgICAgICAgdGhpcy5sb2codmlldywgXCJqb2luXCIsICgpID0+IFtgZXhjZWVkZWQgJHt0aGlzLm1heFJlbG9hZHN9IGNvbnNlY3V0aXZlIHJlbG9hZHMuIEVudGVyaW5nIGZhaWxzYWZlIG1vZGVgXSlcbiAgICAgIH1cbiAgICAgIGlmKHRoaXMuaGFzUGVuZGluZ0xpbmsoKSl7XG4gICAgICAgIHdpbmRvdy5sb2NhdGlvbiA9IHRoaXMucGVuZGluZ0xpbmtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKVxuICAgICAgfVxuICAgIH0sIGFmdGVyTXMpXG4gIH1cblxuICBnZXRIb29rQ2FsbGJhY2tzKG5hbWUpe1xuICAgIHJldHVybiBuYW1lICYmIG5hbWUuc3RhcnRzV2l0aChcIlBob2VuaXguXCIpID8gSG9va3NbbmFtZS5zcGxpdChcIi5cIilbMV1dIDogdGhpcy5ob29rc1tuYW1lXVxuICB9XG5cbiAgaXNVbmxvYWRlZCgpeyByZXR1cm4gdGhpcy51bmxvYWRlZCB9XG5cbiAgaXNDb25uZWN0ZWQoKXsgcmV0dXJuIHRoaXMuc29ja2V0LmlzQ29ubmVjdGVkKCkgfVxuXG4gIGdldEJpbmRpbmdQcmVmaXgoKXsgcmV0dXJuIHRoaXMuYmluZGluZ1ByZWZpeCB9XG5cbiAgYmluZGluZyhraW5kKXsgcmV0dXJuIGAke3RoaXMuZ2V0QmluZGluZ1ByZWZpeCgpfSR7a2luZH1gIH1cblxuICBjaGFubmVsKHRvcGljLCBwYXJhbXMpeyByZXR1cm4gdGhpcy5zb2NrZXQuY2hhbm5lbCh0b3BpYywgcGFyYW1zKSB9XG5cbiAgam9pbkRlYWRWaWV3KCl7XG4gICAgbGV0IGJvZHkgPSBkb2N1bWVudC5ib2R5XG4gICAgaWYoYm9keSAmJiAhdGhpcy5pc1BoeFZpZXcoYm9keSkgJiYgIXRoaXMuaXNQaHhWaWV3KGRvY3VtZW50LmZpcnN0RWxlbWVudENoaWxkKSl7XG4gICAgICBsZXQgdmlldyA9IHRoaXMubmV3Um9vdFZpZXcoYm9keSlcbiAgICAgIHZpZXcuc2V0SHJlZih0aGlzLmdldEhyZWYoKSlcbiAgICAgIHZpZXcuam9pbkRlYWQoKVxuICAgICAgaWYoIXRoaXMubWFpbil7IHRoaXMubWFpbiA9IHZpZXcgfVxuICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB2aWV3LmV4ZWNOZXdNb3VudGVkKCkpXG4gICAgfVxuICB9XG5cbiAgam9pblJvb3RWaWV3cygpe1xuICAgIGxldCByb290c0ZvdW5kID0gZmFsc2VcbiAgICBET00uYWxsKGRvY3VtZW50LCBgJHtQSFhfVklFV19TRUxFQ1RPUn06bm90KFske1BIWF9QQVJFTlRfSUR9XSlgLCByb290RWwgPT4ge1xuICAgICAgaWYoIXRoaXMuZ2V0Um9vdEJ5SWQocm9vdEVsLmlkKSl7XG4gICAgICAgIGxldCB2aWV3ID0gdGhpcy5uZXdSb290Vmlldyhyb290RWwpXG4gICAgICAgIHZpZXcuc2V0SHJlZih0aGlzLmdldEhyZWYoKSlcbiAgICAgICAgdmlldy5qb2luKClcbiAgICAgICAgaWYocm9vdEVsLmhhc0F0dHJpYnV0ZShQSFhfTUFJTikpeyB0aGlzLm1haW4gPSB2aWV3IH1cbiAgICAgIH1cbiAgICAgIHJvb3RzRm91bmQgPSB0cnVlXG4gICAgfSlcbiAgICByZXR1cm4gcm9vdHNGb3VuZFxuICB9XG5cbiAgcmVkaXJlY3QodG8sIGZsYXNoKXtcbiAgICB0aGlzLnVubG9hZCgpXG4gICAgQnJvd3Nlci5yZWRpcmVjdCh0bywgZmxhc2gpXG4gIH1cblxuICByZXBsYWNlTWFpbihocmVmLCBmbGFzaCwgY2FsbGJhY2sgPSBudWxsLCBsaW5rUmVmID0gdGhpcy5zZXRQZW5kaW5nTGluayhocmVmKSl7XG4gICAgbGV0IGxpdmVSZWZlcmVyID0gdGhpcy5jdXJyZW50TG9jYXRpb24uaHJlZlxuICAgIHRoaXMub3V0Z29pbmdNYWluRWwgPSB0aGlzLm91dGdvaW5nTWFpbkVsIHx8IHRoaXMubWFpbi5lbFxuICAgIGxldCBuZXdNYWluRWwgPSBET00uY2xvbmVOb2RlKHRoaXMub3V0Z29pbmdNYWluRWwsIFwiXCIpXG4gICAgdGhpcy5tYWluLnNob3dMb2FkZXIodGhpcy5sb2FkZXJUaW1lb3V0KVxuICAgIHRoaXMubWFpbi5kZXN0cm95KClcblxuICAgIHRoaXMubWFpbiA9IHRoaXMubmV3Um9vdFZpZXcobmV3TWFpbkVsLCBmbGFzaCwgbGl2ZVJlZmVyZXIpXG4gICAgdGhpcy5tYWluLnNldFJlZGlyZWN0KGhyZWYpXG4gICAgdGhpcy50cmFuc2l0aW9uUmVtb3ZlcygpXG4gICAgdGhpcy5tYWluLmpvaW4oKGpvaW5Db3VudCwgb25Eb25lKSA9PiB7XG4gICAgICBpZihqb2luQ291bnQgPT09IDEgJiYgdGhpcy5jb21taXRQZW5kaW5nTGluayhsaW5rUmVmKSl7XG4gICAgICAgIHRoaXMucmVxdWVzdERPTVVwZGF0ZSgoKSA9PiB7XG4gICAgICAgICAgRE9NLmZpbmRQaHhTdGlja3koZG9jdW1lbnQpLmZvckVhY2goZWwgPT4gbmV3TWFpbkVsLmFwcGVuZENoaWxkKGVsKSlcbiAgICAgICAgICB0aGlzLm91dGdvaW5nTWFpbkVsLnJlcGxhY2VXaXRoKG5ld01haW5FbClcbiAgICAgICAgICB0aGlzLm91dGdvaW5nTWFpbkVsID0gbnVsbFxuICAgICAgICAgIGNhbGxiYWNrICYmIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiBjYWxsYmFjayhsaW5rUmVmKSlcbiAgICAgICAgICBvbkRvbmUoKVxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICB0cmFuc2l0aW9uUmVtb3ZlcyhlbGVtZW50cyl7XG4gICAgbGV0IHJlbW92ZUF0dHIgPSB0aGlzLmJpbmRpbmcoXCJyZW1vdmVcIilcbiAgICBlbGVtZW50cyA9IGVsZW1lbnRzIHx8IERPTS5hbGwoZG9jdW1lbnQsIGBbJHtyZW1vdmVBdHRyfV1gKVxuICAgIGVsZW1lbnRzLmZvckVhY2goZWwgPT4ge1xuICAgICAgdGhpcy5leGVjSlMoZWwsIGVsLmdldEF0dHJpYnV0ZShyZW1vdmVBdHRyKSwgXCJyZW1vdmVcIilcbiAgICB9KVxuICB9XG5cbiAgaXNQaHhWaWV3KGVsKXsgcmV0dXJuIGVsLmdldEF0dHJpYnV0ZSAmJiBlbC5nZXRBdHRyaWJ1dGUoUEhYX1NFU1NJT04pICE9PSBudWxsIH1cblxuICBuZXdSb290VmlldyhlbCwgZmxhc2gsIGxpdmVSZWZlcmVyKXtcbiAgICBsZXQgdmlldyA9IG5ldyBWaWV3KGVsLCB0aGlzLCBudWxsLCBmbGFzaCwgbGl2ZVJlZmVyZXIpXG4gICAgdGhpcy5yb290c1t2aWV3LmlkXSA9IHZpZXdcbiAgICByZXR1cm4gdmlld1xuICB9XG5cbiAgb3duZXIoY2hpbGRFbCwgY2FsbGJhY2spe1xuICAgIGxldCB2aWV3ID0gbWF5YmUoY2hpbGRFbC5jbG9zZXN0KFBIWF9WSUVXX1NFTEVDVE9SKSwgZWwgPT4gdGhpcy5nZXRWaWV3QnlFbChlbCkpIHx8IHRoaXMubWFpblxuICAgIGlmKHZpZXcpeyBjYWxsYmFjayh2aWV3KSB9XG4gIH1cblxuICB3aXRoaW5Pd25lcnMoY2hpbGRFbCwgY2FsbGJhY2spe1xuICAgIHRoaXMub3duZXIoY2hpbGRFbCwgdmlldyA9PiBjYWxsYmFjayh2aWV3LCBjaGlsZEVsKSlcbiAgfVxuXG4gIGdldFZpZXdCeUVsKGVsKXtcbiAgICBsZXQgcm9vdElkID0gZWwuZ2V0QXR0cmlidXRlKFBIWF9ST09UX0lEKVxuICAgIHJldHVybiBtYXliZSh0aGlzLmdldFJvb3RCeUlkKHJvb3RJZCksIHJvb3QgPT4gcm9vdC5nZXREZXNjZW5kZW50QnlFbChlbCkpXG4gIH1cblxuICBnZXRSb290QnlJZChpZCl7IHJldHVybiB0aGlzLnJvb3RzW2lkXSB9XG5cbiAgZGVzdHJveUFsbFZpZXdzKCl7XG4gICAgZm9yKGxldCBpZCBpbiB0aGlzLnJvb3RzKXtcbiAgICAgIHRoaXMucm9vdHNbaWRdLmRlc3Ryb3koKVxuICAgICAgZGVsZXRlIHRoaXMucm9vdHNbaWRdXG4gICAgfVxuICAgIHRoaXMubWFpbiA9IG51bGxcbiAgfVxuXG4gIGRlc3Ryb3lWaWV3QnlFbChlbCl7XG4gICAgbGV0IHJvb3QgPSB0aGlzLmdldFJvb3RCeUlkKGVsLmdldEF0dHJpYnV0ZShQSFhfUk9PVF9JRCkpXG4gICAgaWYocm9vdCAmJiByb290LmlkID09PSBlbC5pZCl7XG4gICAgICByb290LmRlc3Ryb3koKVxuICAgICAgZGVsZXRlIHRoaXMucm9vdHNbcm9vdC5pZF1cbiAgICB9IGVsc2UgaWYocm9vdCl7XG4gICAgICByb290LmRlc3Ryb3lEZXNjZW5kZW50KGVsLmlkKVxuICAgIH1cbiAgfVxuXG4gIHNldEFjdGl2ZUVsZW1lbnQodGFyZ2V0KXtcbiAgICBpZih0aGlzLmFjdGl2ZUVsZW1lbnQgPT09IHRhcmdldCl7IHJldHVybiB9XG4gICAgdGhpcy5hY3RpdmVFbGVtZW50ID0gdGFyZ2V0XG4gICAgbGV0IGNhbmNlbCA9ICgpID0+IHtcbiAgICAgIGlmKHRhcmdldCA9PT0gdGhpcy5hY3RpdmVFbGVtZW50KXsgdGhpcy5hY3RpdmVFbGVtZW50ID0gbnVsbCB9XG4gICAgICB0YXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNldXBcIiwgdGhpcylcbiAgICAgIHRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgdGhpcylcbiAgICB9XG4gICAgdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIGNhbmNlbClcbiAgICB0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoZW5kXCIsIGNhbmNlbClcbiAgfVxuXG4gIGdldEFjdGl2ZUVsZW1lbnQoKXtcbiAgICBpZihkb2N1bWVudC5hY3RpdmVFbGVtZW50ID09PSBkb2N1bWVudC5ib2R5KXtcbiAgICAgIHJldHVybiB0aGlzLmFjdGl2ZUVsZW1lbnQgfHwgZG9jdW1lbnQuYWN0aXZlRWxlbWVudFxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBkb2N1bWVudC5hY3RpdmVFbGVtZW50IGNhbiBiZSBudWxsIGluIEludGVybmV0IEV4cGxvcmVyIDExXG4gICAgICByZXR1cm4gZG9jdW1lbnQuYWN0aXZlRWxlbWVudCB8fCBkb2N1bWVudC5ib2R5XG4gICAgfVxuICB9XG5cbiAgZHJvcEFjdGl2ZUVsZW1lbnQodmlldyl7XG4gICAgaWYodGhpcy5wcmV2QWN0aXZlICYmIHZpZXcub3duc0VsZW1lbnQodGhpcy5wcmV2QWN0aXZlKSl7XG4gICAgICB0aGlzLnByZXZBY3RpdmUgPSBudWxsXG4gICAgfVxuICB9XG5cbiAgcmVzdG9yZVByZXZpb3VzbHlBY3RpdmVGb2N1cygpe1xuICAgIGlmKHRoaXMucHJldkFjdGl2ZSAmJiB0aGlzLnByZXZBY3RpdmUgIT09IGRvY3VtZW50LmJvZHkpe1xuICAgICAgdGhpcy5wcmV2QWN0aXZlLmZvY3VzKClcbiAgICB9XG4gIH1cblxuICBibHVyQWN0aXZlRWxlbWVudCgpe1xuICAgIHRoaXMucHJldkFjdGl2ZSA9IHRoaXMuZ2V0QWN0aXZlRWxlbWVudCgpXG4gICAgaWYodGhpcy5wcmV2QWN0aXZlICE9PSBkb2N1bWVudC5ib2R5KXsgdGhpcy5wcmV2QWN0aXZlLmJsdXIoKSB9XG4gIH1cblxuICBiaW5kVG9wTGV2ZWxFdmVudHMoe2RlYWR9ID0ge30pe1xuICAgIGlmKHRoaXMuYm91bmRUb3BMZXZlbEV2ZW50cyl7IHJldHVybiB9XG5cbiAgICB0aGlzLmJvdW5kVG9wTGV2ZWxFdmVudHMgPSB0cnVlXG4gICAgLy8gZW50ZXIgZmFpbHNhZmUgcmVsb2FkIGlmIHNlcnZlciBoYXMgZ29uZSBhd2F5IGludGVudGlvbmFsbHksIHN1Y2ggYXMgXCJkaXNjb25uZWN0XCIgYnJvYWRjYXN0XG4gICAgdGhpcy5zb2NrZXQub25DbG9zZShldmVudCA9PiB7XG4gICAgICAvLyBmYWlsc2FmZSByZWxvYWQgaWYgbm9ybWFsIGNsb3N1cmUgYW5kIHdlIHN0aWxsIGhhdmUgYSBtYWluIExWXG4gICAgICBpZihldmVudCAmJiBldmVudC5jb2RlID09PSAxMDAwICYmIHRoaXMubWFpbil7IHJldHVybiB0aGlzLnJlbG9hZFdpdGhKaXR0ZXIodGhpcy5tYWluKSB9XG4gICAgfSlcbiAgICBkb2N1bWVudC5ib2R5LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBmdW5jdGlvbiAoKXsgfSkgLy8gZW5zdXJlIGFsbCBjbGljayBldmVudHMgYnViYmxlIGZvciBtb2JpbGUgU2FmYXJpXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJwYWdlc2hvd1wiLCBlID0+IHtcbiAgICAgIGlmKGUucGVyc2lzdGVkKXsgLy8gcmVsb2FkIHBhZ2UgaWYgYmVpbmcgcmVzdG9yZWQgZnJvbSBiYWNrL2ZvcndhcmQgY2FjaGVcbiAgICAgICAgdGhpcy5nZXRTb2NrZXQoKS5kaXNjb25uZWN0KClcbiAgICAgICAgdGhpcy53aXRoUGFnZUxvYWRpbmcoe3RvOiB3aW5kb3cubG9jYXRpb24uaHJlZiwga2luZDogXCJyZWRpcmVjdFwifSlcbiAgICAgICAgd2luZG93LmxvY2F0aW9uLnJlbG9hZCgpXG4gICAgICB9XG4gICAgfSwgdHJ1ZSlcbiAgICBpZighZGVhZCl7IHRoaXMuYmluZE5hdigpIH1cbiAgICB0aGlzLmJpbmRDbGlja3MoKVxuICAgIGlmKCFkZWFkKXsgdGhpcy5iaW5kRm9ybXMoKSB9XG4gICAgdGhpcy5iaW5kKHtrZXl1cDogXCJrZXl1cFwiLCBrZXlkb3duOiBcImtleWRvd25cIn0sIChlLCB0eXBlLCB2aWV3LCB0YXJnZXRFbCwgcGh4RXZlbnQsIGV2ZW50VGFyZ2V0KSA9PiB7XG4gICAgICBsZXQgbWF0Y2hLZXkgPSB0YXJnZXRFbC5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFBIWF9LRVkpKVxuICAgICAgbGV0IHByZXNzZWRLZXkgPSBlLmtleSAmJiBlLmtleS50b0xvd2VyQ2FzZSgpIC8vIGNocm9tZSBjbGlja2VkIGF1dG9jb21wbGV0ZXMgc2VuZCBhIGtleWRvd24gd2l0aG91dCBrZXlcbiAgICAgIGlmKG1hdGNoS2V5ICYmIG1hdGNoS2V5LnRvTG93ZXJDYXNlKCkgIT09IHByZXNzZWRLZXkpeyByZXR1cm4gfVxuXG4gICAgICBsZXQgZGF0YSA9IHtrZXk6IGUua2V5LCAuLi50aGlzLmV2ZW50TWV0YSh0eXBlLCBlLCB0YXJnZXRFbCl9XG4gICAgICBKUy5leGVjKHR5cGUsIHBoeEV2ZW50LCB2aWV3LCB0YXJnZXRFbCwgW1wicHVzaFwiLCB7ZGF0YX1dKVxuICAgIH0pXG4gICAgdGhpcy5iaW5kKHtibHVyOiBcImZvY3Vzb3V0XCIsIGZvY3VzOiBcImZvY3VzaW5cIn0sIChlLCB0eXBlLCB2aWV3LCB0YXJnZXRFbCwgcGh4RXZlbnQsIGV2ZW50VGFyZ2V0KSA9PiB7XG4gICAgICBpZighZXZlbnRUYXJnZXQpe1xuICAgICAgICBsZXQgZGF0YSA9IHtrZXk6IGUua2V5LCAuLi50aGlzLmV2ZW50TWV0YSh0eXBlLCBlLCB0YXJnZXRFbCl9XG4gICAgICAgIEpTLmV4ZWModHlwZSwgcGh4RXZlbnQsIHZpZXcsIHRhcmdldEVsLCBbXCJwdXNoXCIsIHtkYXRhfV0pXG4gICAgICB9XG4gICAgfSlcbiAgICB0aGlzLmJpbmQoe2JsdXI6IFwiYmx1clwiLCBmb2N1czogXCJmb2N1c1wifSwgKGUsIHR5cGUsIHZpZXcsIHRhcmdldEVsLCB0YXJnZXRDdHgsIHBoeEV2ZW50LCBwaHhUYXJnZXQpID0+IHtcbiAgICAgIC8vIGJsdXIgYW5kIGZvY3VzIGFyZSB0cmlnZ2VyZWQgb24gZG9jdW1lbnQgYW5kIHdpbmRvdy4gRGlzY2FyZCBvbmUgdG8gYXZvaWQgZHVwc1xuICAgICAgaWYocGh4VGFyZ2V0ID09PSBcIndpbmRvd1wiKXtcbiAgICAgICAgbGV0IGRhdGEgPSB0aGlzLmV2ZW50TWV0YSh0eXBlLCBlLCB0YXJnZXRFbClcbiAgICAgICAgSlMuZXhlYyh0eXBlLCBwaHhFdmVudCwgdmlldywgdGFyZ2V0RWwsIFtcInB1c2hcIiwge2RhdGF9XSlcbiAgICAgIH1cbiAgICB9KVxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiZHJhZ292ZXJcIiwgZSA9PiBlLnByZXZlbnREZWZhdWx0KCkpXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJkcm9wXCIsIGUgPT4ge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICBsZXQgZHJvcFRhcmdldElkID0gbWF5YmUoY2xvc2VzdFBoeEJpbmRpbmcoZS50YXJnZXQsIHRoaXMuYmluZGluZyhQSFhfRFJPUF9UQVJHRVQpKSwgdHJ1ZVRhcmdldCA9PiB7XG4gICAgICAgIHJldHVybiB0cnVlVGFyZ2V0LmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoUEhYX0RST1BfVEFSR0VUKSlcbiAgICAgIH0pXG4gICAgICBsZXQgZHJvcFRhcmdldCA9IGRyb3BUYXJnZXRJZCAmJiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChkcm9wVGFyZ2V0SWQpXG4gICAgICBsZXQgZmlsZXMgPSBBcnJheS5mcm9tKGUuZGF0YVRyYW5zZmVyLmZpbGVzIHx8IFtdKVxuICAgICAgaWYoIWRyb3BUYXJnZXQgfHwgZHJvcFRhcmdldC5kaXNhYmxlZCB8fCBmaWxlcy5sZW5ndGggPT09IDAgfHwgIShkcm9wVGFyZ2V0LmZpbGVzIGluc3RhbmNlb2YgRmlsZUxpc3QpKXsgcmV0dXJuIH1cblxuICAgICAgTGl2ZVVwbG9hZGVyLnRyYWNrRmlsZXMoZHJvcFRhcmdldCwgZmlsZXMsIGUuZGF0YVRyYW5zZmVyKVxuICAgICAgZHJvcFRhcmdldC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcImlucHV0XCIsIHtidWJibGVzOiB0cnVlfSkpXG4gICAgfSlcbiAgICB0aGlzLm9uKFBIWF9UUkFDS19VUExPQURTLCBlID0+IHtcbiAgICAgIGxldCB1cGxvYWRUYXJnZXQgPSBlLnRhcmdldFxuICAgICAgaWYoIURPTS5pc1VwbG9hZElucHV0KHVwbG9hZFRhcmdldCkpeyByZXR1cm4gfVxuICAgICAgbGV0IGZpbGVzID0gQXJyYXkuZnJvbShlLmRldGFpbC5maWxlcyB8fCBbXSkuZmlsdGVyKGYgPT4gZiBpbnN0YW5jZW9mIEZpbGUgfHwgZiBpbnN0YW5jZW9mIEJsb2IpXG4gICAgICBMaXZlVXBsb2FkZXIudHJhY2tGaWxlcyh1cGxvYWRUYXJnZXQsIGZpbGVzKVxuICAgICAgdXBsb2FkVGFyZ2V0LmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwiaW5wdXRcIiwge2J1YmJsZXM6IHRydWV9KSlcbiAgICB9KVxuICB9XG5cbiAgZXZlbnRNZXRhKGV2ZW50TmFtZSwgZSwgdGFyZ2V0RWwpe1xuICAgIGxldCBjYWxsYmFjayA9IHRoaXMubWV0YWRhdGFDYWxsYmFja3NbZXZlbnROYW1lXVxuICAgIHJldHVybiBjYWxsYmFjayA/IGNhbGxiYWNrKGUsIHRhcmdldEVsKSA6IHt9XG4gIH1cblxuICBzZXRQZW5kaW5nTGluayhocmVmKXtcbiAgICB0aGlzLmxpbmtSZWYrK1xuICAgIHRoaXMucGVuZGluZ0xpbmsgPSBocmVmXG4gICAgcmV0dXJuIHRoaXMubGlua1JlZlxuICB9XG5cbiAgY29tbWl0UGVuZGluZ0xpbmsobGlua1JlZil7XG4gICAgaWYodGhpcy5saW5rUmVmICE9PSBsaW5rUmVmKXtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmhyZWYgPSB0aGlzLnBlbmRpbmdMaW5rXG4gICAgICB0aGlzLnBlbmRpbmdMaW5rID0gbnVsbFxuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH1cblxuICBnZXRIcmVmKCl7IHJldHVybiB0aGlzLmhyZWYgfVxuXG4gIGhhc1BlbmRpbmdMaW5rKCl7IHJldHVybiAhIXRoaXMucGVuZGluZ0xpbmsgfVxuXG4gIGJpbmQoZXZlbnRzLCBjYWxsYmFjayl7XG4gICAgZm9yKGxldCBldmVudCBpbiBldmVudHMpe1xuICAgICAgbGV0IGJyb3dzZXJFdmVudE5hbWUgPSBldmVudHNbZXZlbnRdXG5cbiAgICAgIHRoaXMub24oYnJvd3NlckV2ZW50TmFtZSwgZSA9PiB7XG4gICAgICAgIGxldCBiaW5kaW5nID0gdGhpcy5iaW5kaW5nKGV2ZW50KVxuICAgICAgICBsZXQgd2luZG93QmluZGluZyA9IHRoaXMuYmluZGluZyhgd2luZG93LSR7ZXZlbnR9YClcbiAgICAgICAgbGV0IHRhcmdldFBoeEV2ZW50ID0gZS50YXJnZXQuZ2V0QXR0cmlidXRlICYmIGUudGFyZ2V0LmdldEF0dHJpYnV0ZShiaW5kaW5nKVxuICAgICAgICBpZih0YXJnZXRQaHhFdmVudCl7XG4gICAgICAgICAgdGhpcy5kZWJvdW5jZShlLnRhcmdldCwgZSwgYnJvd3NlckV2ZW50TmFtZSwgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy53aXRoaW5Pd25lcnMoZS50YXJnZXQsIHZpZXcgPT4ge1xuICAgICAgICAgICAgICBjYWxsYmFjayhlLCBldmVudCwgdmlldywgZS50YXJnZXQsIHRhcmdldFBoeEV2ZW50LCBudWxsKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIERPTS5hbGwoZG9jdW1lbnQsIGBbJHt3aW5kb3dCaW5kaW5nfV1gLCBlbCA9PiB7XG4gICAgICAgICAgICBsZXQgcGh4RXZlbnQgPSBlbC5nZXRBdHRyaWJ1dGUod2luZG93QmluZGluZylcbiAgICAgICAgICAgIHRoaXMuZGVib3VuY2UoZWwsIGUsIGJyb3dzZXJFdmVudE5hbWUsICgpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy53aXRoaW5Pd25lcnMoZWwsIHZpZXcgPT4ge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGUsIGV2ZW50LCB2aWV3LCBlbCwgcGh4RXZlbnQsIFwid2luZG93XCIpXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgYmluZENsaWNrcygpe1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgZSA9PiB0aGlzLmNsaWNrU3RhcnRlZEF0VGFyZ2V0ID0gZS50YXJnZXQpXG4gICAgdGhpcy5iaW5kQ2xpY2soXCJjbGlja1wiLCBcImNsaWNrXCIsIGZhbHNlKVxuICAgIHRoaXMuYmluZENsaWNrKFwibW91c2Vkb3duXCIsIFwiY2FwdHVyZS1jbGlja1wiLCB0cnVlKVxuICB9XG5cbiAgYmluZENsaWNrKGV2ZW50TmFtZSwgYmluZGluZ05hbWUsIGNhcHR1cmUpe1xuICAgIGxldCBjbGljayA9IHRoaXMuYmluZGluZyhiaW5kaW5nTmFtZSlcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGUgPT4ge1xuICAgICAgbGV0IHRhcmdldCA9IG51bGxcbiAgICAgIGlmKGNhcHR1cmUpe1xuICAgICAgICB0YXJnZXQgPSBlLnRhcmdldC5tYXRjaGVzKGBbJHtjbGlja31dYCkgPyBlLnRhcmdldCA6IGUudGFyZ2V0LnF1ZXJ5U2VsZWN0b3IoYFske2NsaWNrfV1gKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGV0IGNsaWNrU3RhcnRlZEF0VGFyZ2V0ID0gdGhpcy5jbGlja1N0YXJ0ZWRBdFRhcmdldCB8fCBlLnRhcmdldFxuICAgICAgICB0YXJnZXQgPSBjbG9zZXN0UGh4QmluZGluZyhjbGlja1N0YXJ0ZWRBdFRhcmdldCwgY2xpY2spXG4gICAgICAgIHRoaXMuZGlzcGF0Y2hDbGlja0F3YXkoZSwgY2xpY2tTdGFydGVkQXRUYXJnZXQpXG4gICAgICAgIHRoaXMuY2xpY2tTdGFydGVkQXRUYXJnZXQgPSBudWxsXG4gICAgICB9XG4gICAgICBsZXQgcGh4RXZlbnQgPSB0YXJnZXQgJiYgdGFyZ2V0LmdldEF0dHJpYnV0ZShjbGljaylcbiAgICAgIGlmKCFwaHhFdmVudCl7XG4gICAgICAgIGlmKCFjYXB0dXJlICYmIERPTS5pc05ld1BhZ2VDbGljayhlLCB3aW5kb3cubG9jYXRpb24pKXsgdGhpcy51bmxvYWQoKSB9XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBpZih0YXJnZXQuZ2V0QXR0cmlidXRlKFwiaHJlZlwiKSA9PT0gXCIjXCIpeyBlLnByZXZlbnREZWZhdWx0KCkgfVxuXG4gICAgICAvLyBub29wIGlmIHdlIGFyZSBpbiB0aGUgbWlkZGxlIG9mIGF3YWl0aW5nIGFuIGFjayBmb3IgdGhpcyBlbCBhbHJlYWR5XG4gICAgICBpZih0YXJnZXQuaGFzQXR0cmlidXRlKFBIWF9SRUYpKXsgcmV0dXJuIH1cblxuICAgICAgdGhpcy5kZWJvdW5jZSh0YXJnZXQsIGUsIFwiY2xpY2tcIiwgKCkgPT4ge1xuICAgICAgICB0aGlzLndpdGhpbk93bmVycyh0YXJnZXQsIHZpZXcgPT4ge1xuICAgICAgICAgIEpTLmV4ZWMoXCJjbGlja1wiLCBwaHhFdmVudCwgdmlldywgdGFyZ2V0LCBbXCJwdXNoXCIsIHtkYXRhOiB0aGlzLmV2ZW50TWV0YShcImNsaWNrXCIsIGUsIHRhcmdldCl9XSlcbiAgICAgICAgfSlcbiAgICAgIH0pXG4gICAgfSwgY2FwdHVyZSlcbiAgfVxuXG4gIGRpc3BhdGNoQ2xpY2tBd2F5KGUsIGNsaWNrU3RhcnRlZEF0KXtcbiAgICBsZXQgcGh4Q2xpY2tBd2F5ID0gdGhpcy5iaW5kaW5nKFwiY2xpY2stYXdheVwiKVxuICAgIERPTS5hbGwoZG9jdW1lbnQsIGBbJHtwaHhDbGlja0F3YXl9XWAsIGVsID0+IHtcbiAgICAgIGlmKCEoZWwuaXNTYW1lTm9kZShjbGlja1N0YXJ0ZWRBdCkgfHwgZWwuY29udGFpbnMoY2xpY2tTdGFydGVkQXQpKSl7XG4gICAgICAgIHRoaXMud2l0aGluT3duZXJzKGUudGFyZ2V0LCB2aWV3ID0+IHtcbiAgICAgICAgICBsZXQgcGh4RXZlbnQgPSBlbC5nZXRBdHRyaWJ1dGUocGh4Q2xpY2tBd2F5KVxuICAgICAgICAgIGlmKEpTLmlzVmlzaWJsZShlbCkpe1xuICAgICAgICAgICAgSlMuZXhlYyhcImNsaWNrXCIsIHBoeEV2ZW50LCB2aWV3LCBlbCwgW1wicHVzaFwiLCB7ZGF0YTogdGhpcy5ldmVudE1ldGEoXCJjbGlja1wiLCBlLCBlLnRhcmdldCl9XSlcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIGJpbmROYXYoKXtcbiAgICBpZighQnJvd3Nlci5jYW5QdXNoU3RhdGUoKSl7IHJldHVybiB9XG4gICAgaWYoaGlzdG9yeS5zY3JvbGxSZXN0b3JhdGlvbil7IGhpc3Rvcnkuc2Nyb2xsUmVzdG9yYXRpb24gPSBcIm1hbnVhbFwiIH1cbiAgICBsZXQgc2Nyb2xsVGltZXIgPSBudWxsXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgX2UgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHNjcm9sbFRpbWVyKVxuICAgICAgc2Nyb2xsVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgQnJvd3Nlci51cGRhdGVDdXJyZW50U3RhdGUoc3RhdGUgPT4gT2JqZWN0LmFzc2lnbihzdGF0ZSwge3Njcm9sbDogd2luZG93LnNjcm9sbFl9KSlcbiAgICAgIH0sIDEwMClcbiAgICB9KVxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicG9wc3RhdGVcIiwgZXZlbnQgPT4ge1xuICAgICAgaWYoIXRoaXMucmVnaXN0ZXJOZXdMb2NhdGlvbih3aW5kb3cubG9jYXRpb24pKXsgcmV0dXJuIH1cbiAgICAgIGxldCB7dHlwZSwgaWQsIHJvb3QsIHNjcm9sbH0gPSBldmVudC5zdGF0ZSB8fCB7fVxuICAgICAgbGV0IGhyZWYgPSB3aW5kb3cubG9jYXRpb24uaHJlZlxuXG4gICAgICBET00uZGlzcGF0Y2hFdmVudCh3aW5kb3csIFwicGh4Om5hdmlnYXRlXCIsIHtkZXRhaWw6IHtocmVmLCBwYXRjaDogdHlwZSA9PT0gXCJwYXRjaFwiLCBwb3A6IHRydWV9fSlcbiAgICAgIHRoaXMucmVxdWVzdERPTVVwZGF0ZSgoKSA9PiB7XG4gICAgICAgIGlmKHRoaXMubWFpbi5pc0Nvbm5lY3RlZCgpICYmICh0eXBlID09PSBcInBhdGNoXCIgJiYgaWQgPT09IHRoaXMubWFpbi5pZCkpe1xuICAgICAgICAgIHRoaXMubWFpbi5wdXNoTGlua1BhdGNoKGhyZWYsIG51bGwsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMubWF5YmVTY3JvbGwoc2Nyb2xsKVxuICAgICAgICAgIH0pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5yZXBsYWNlTWFpbihocmVmLCBudWxsLCAoKSA9PiB7XG4gICAgICAgICAgICBpZihyb290KXsgdGhpcy5yZXBsYWNlUm9vdEhpc3RvcnkoKSB9XG4gICAgICAgICAgICB0aGlzLm1heWJlU2Nyb2xsKHNjcm9sbClcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH0sIGZhbHNlKVxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgZSA9PiB7XG4gICAgICBsZXQgdGFyZ2V0ID0gY2xvc2VzdFBoeEJpbmRpbmcoZS50YXJnZXQsIFBIWF9MSVZFX0xJTkspXG4gICAgICBsZXQgdHlwZSA9IHRhcmdldCAmJiB0YXJnZXQuZ2V0QXR0cmlidXRlKFBIWF9MSVZFX0xJTkspXG4gICAgICBpZighdHlwZSB8fCAhdGhpcy5pc0Nvbm5lY3RlZCgpIHx8ICF0aGlzLm1haW4gfHwgRE9NLndhbnRzTmV3VGFiKGUpKXsgcmV0dXJuIH1cblxuICAgICAgbGV0IGhyZWYgPSB0YXJnZXQuaHJlZlxuICAgICAgbGV0IGxpbmtTdGF0ZSA9IHRhcmdldC5nZXRBdHRyaWJ1dGUoUEhYX0xJTktfU1RBVEUpXG4gICAgICBlLnByZXZlbnREZWZhdWx0KClcbiAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCkgLy8gZG8gbm90IGJ1YmJsZSBjbGljayB0byByZWd1bGFyIHBoeC1jbGljayBiaW5kaW5nc1xuICAgICAgaWYodGhpcy5wZW5kaW5nTGluayA9PT0gaHJlZil7IHJldHVybiB9XG5cbiAgICAgIHRoaXMucmVxdWVzdERPTVVwZGF0ZSgoKSA9PiB7XG4gICAgICAgIGlmKHR5cGUgPT09IFwicGF0Y2hcIil7XG4gICAgICAgICAgdGhpcy5wdXNoSGlzdG9yeVBhdGNoKGhyZWYsIGxpbmtTdGF0ZSwgdGFyZ2V0KVxuICAgICAgICB9IGVsc2UgaWYodHlwZSA9PT0gXCJyZWRpcmVjdFwiKXtcbiAgICAgICAgICB0aGlzLmhpc3RvcnlSZWRpcmVjdChocmVmLCBsaW5rU3RhdGUpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBleHBlY3RlZCAke1BIWF9MSVZFX0xJTkt9IHRvIGJlIFwicGF0Y2hcIiBvciBcInJlZGlyZWN0XCIsIGdvdDogJHt0eXBlfWApXG4gICAgICAgIH1cbiAgICAgICAgbGV0IHBoeENsaWNrID0gdGFyZ2V0LmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoXCJjbGlja1wiKSlcbiAgICAgICAgaWYocGh4Q2xpY2spe1xuICAgICAgICAgIHRoaXMucmVxdWVzdERPTVVwZGF0ZSgoKSA9PiB0aGlzLmV4ZWNKUyh0YXJnZXQsIHBoeENsaWNrLCBcImNsaWNrXCIpKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH0sIGZhbHNlKVxuICB9XG5cbiAgbWF5YmVTY3JvbGwoc2Nyb2xsKSB7XG4gICAgaWYodHlwZW9mKHNjcm9sbCkgPT09IFwibnVtYmVyXCIpe1xuICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgd2luZG93LnNjcm9sbFRvKDAsIHNjcm9sbClcbiAgICAgIH0pIC8vIHRoZSBib2R5IG5lZWRzIHRvIHJlbmRlciBiZWZvcmUgd2Ugc2Nyb2xsLlxuICAgIH1cbiAgfVxuXG4gIGRpc3BhdGNoRXZlbnQoZXZlbnQsIHBheWxvYWQgPSB7fSl7XG4gICAgRE9NLmRpc3BhdGNoRXZlbnQod2luZG93LCBgcGh4OiR7ZXZlbnR9YCwge2RldGFpbDogcGF5bG9hZH0pXG4gIH1cblxuICBkaXNwYXRjaEV2ZW50cyhldmVudHMpe1xuICAgIGV2ZW50cy5mb3JFYWNoKChbZXZlbnQsIHBheWxvYWRdKSA9PiB0aGlzLmRpc3BhdGNoRXZlbnQoZXZlbnQsIHBheWxvYWQpKVxuICB9XG5cbiAgd2l0aFBhZ2VMb2FkaW5nKGluZm8sIGNhbGxiYWNrKXtcbiAgICBET00uZGlzcGF0Y2hFdmVudCh3aW5kb3csIFwicGh4OnBhZ2UtbG9hZGluZy1zdGFydFwiLCB7ZGV0YWlsOiBpbmZvfSlcbiAgICBsZXQgZG9uZSA9ICgpID0+IERPTS5kaXNwYXRjaEV2ZW50KHdpbmRvdywgXCJwaHg6cGFnZS1sb2FkaW5nLXN0b3BcIiwge2RldGFpbDogaW5mb30pXG4gICAgcmV0dXJuIGNhbGxiYWNrID8gY2FsbGJhY2soZG9uZSkgOiBkb25lXG4gIH1cblxuICBwdXNoSGlzdG9yeVBhdGNoKGhyZWYsIGxpbmtTdGF0ZSwgdGFyZ2V0RWwpe1xuICAgIGlmKCF0aGlzLmlzQ29ubmVjdGVkKCkpeyByZXR1cm4gQnJvd3Nlci5yZWRpcmVjdChocmVmKSB9XG5cbiAgICB0aGlzLndpdGhQYWdlTG9hZGluZyh7dG86IGhyZWYsIGtpbmQ6IFwicGF0Y2hcIn0sIGRvbmUgPT4ge1xuICAgICAgdGhpcy5tYWluLnB1c2hMaW5rUGF0Y2goaHJlZiwgdGFyZ2V0RWwsIGxpbmtSZWYgPT4ge1xuICAgICAgICB0aGlzLmhpc3RvcnlQYXRjaChocmVmLCBsaW5rU3RhdGUsIGxpbmtSZWYpXG4gICAgICAgIGRvbmUoKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgaGlzdG9yeVBhdGNoKGhyZWYsIGxpbmtTdGF0ZSwgbGlua1JlZiA9IHRoaXMuc2V0UGVuZGluZ0xpbmsoaHJlZikpe1xuICAgIGlmKCF0aGlzLmNvbW1pdFBlbmRpbmdMaW5rKGxpbmtSZWYpKXsgcmV0dXJuIH1cblxuICAgIEJyb3dzZXIucHVzaFN0YXRlKGxpbmtTdGF0ZSwge3R5cGU6IFwicGF0Y2hcIiwgaWQ6IHRoaXMubWFpbi5pZH0sIGhyZWYpXG4gICAgRE9NLmRpc3BhdGNoRXZlbnQod2luZG93LCBcInBoeDpuYXZpZ2F0ZVwiLCB7ZGV0YWlsOiB7cGF0Y2g6IHRydWUsIGhyZWYsIHBvcDogZmFsc2V9fSlcbiAgICB0aGlzLnJlZ2lzdGVyTmV3TG9jYXRpb24od2luZG93LmxvY2F0aW9uKVxuICB9XG5cbiAgaGlzdG9yeVJlZGlyZWN0KGhyZWYsIGxpbmtTdGF0ZSwgZmxhc2gpe1xuICAgIC8vIGNvbnZlcnQgdG8gZnVsbCBocmVmIGlmIG9ubHkgcGF0aCBwcmVmaXhcbiAgICBpZighdGhpcy5pc0Nvbm5lY3RlZCgpKXsgcmV0dXJuIEJyb3dzZXIucmVkaXJlY3QoaHJlZiwgZmxhc2gpIH1cbiAgICBpZigvXlxcLyR8XlxcL1teXFwvXSsuKiQvLnRlc3QoaHJlZikpe1xuICAgICAgbGV0IHtwcm90b2NvbCwgaG9zdH0gPSB3aW5kb3cubG9jYXRpb25cbiAgICAgIGhyZWYgPSBgJHtwcm90b2NvbH0vLyR7aG9zdH0ke2hyZWZ9YFxuICAgIH1cbiAgICBsZXQgc2Nyb2xsID0gd2luZG93LnNjcm9sbFlcbiAgICB0aGlzLndpdGhQYWdlTG9hZGluZyh7dG86IGhyZWYsIGtpbmQ6IFwicmVkaXJlY3RcIn0sIGRvbmUgPT4ge1xuICAgICAgdGhpcy5yZXBsYWNlTWFpbihocmVmLCBmbGFzaCwgKGxpbmtSZWYpID0+IHtcbiAgICAgICAgaWYobGlua1JlZiA9PT0gdGhpcy5saW5rUmVmKXtcbiAgICAgICAgICBCcm93c2VyLnB1c2hTdGF0ZShsaW5rU3RhdGUsIHt0eXBlOiBcInJlZGlyZWN0XCIsIGlkOiB0aGlzLm1haW4uaWQsIHNjcm9sbDogc2Nyb2xsfSwgaHJlZilcbiAgICAgICAgICBET00uZGlzcGF0Y2hFdmVudCh3aW5kb3csIFwicGh4Om5hdmlnYXRlXCIsIHtkZXRhaWw6IHtocmVmLCBwYXRjaDogZmFsc2UsIHBvcDogZmFsc2V9fSlcbiAgICAgICAgICB0aGlzLnJlZ2lzdGVyTmV3TG9jYXRpb24od2luZG93LmxvY2F0aW9uKVxuICAgICAgICB9XG4gICAgICAgIGRvbmUoKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgcmVwbGFjZVJvb3RIaXN0b3J5KCl7XG4gICAgQnJvd3Nlci5wdXNoU3RhdGUoXCJyZXBsYWNlXCIsIHtyb290OiB0cnVlLCB0eXBlOiBcInBhdGNoXCIsIGlkOiB0aGlzLm1haW4uaWR9KVxuICB9XG5cbiAgcmVnaXN0ZXJOZXdMb2NhdGlvbihuZXdMb2NhdGlvbil7XG4gICAgbGV0IHtwYXRobmFtZSwgc2VhcmNofSA9IHRoaXMuY3VycmVudExvY2F0aW9uXG4gICAgaWYocGF0aG5hbWUgKyBzZWFyY2ggPT09IG5ld0xvY2F0aW9uLnBhdGhuYW1lICsgbmV3TG9jYXRpb24uc2VhcmNoKXtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmN1cnJlbnRMb2NhdGlvbiA9IGNsb25lKG5ld0xvY2F0aW9uKVxuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH1cblxuICBiaW5kRm9ybXMoKXtcbiAgICBsZXQgaXRlcmF0aW9ucyA9IDBcbiAgICBsZXQgZXh0ZXJuYWxGb3JtU3VibWl0dGVkID0gZmFsc2VcblxuICAgIC8vIGRpc2FibGUgZm9ybXMgb24gc3VibWl0IHRoYXQgdHJhY2sgcGh4LWNoYW5nZSBidXQgcGVyZm9ybSBleHRlcm5hbCBzdWJtaXRcbiAgICB0aGlzLm9uKFwic3VibWl0XCIsIGUgPT4ge1xuICAgICAgbGV0IHBoeFN1Ym1pdCA9IGUudGFyZ2V0LmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoXCJzdWJtaXRcIikpXG4gICAgICBsZXQgcGh4Q2hhbmdlID0gZS50YXJnZXQuZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhcImNoYW5nZVwiKSlcbiAgICAgIGlmKCFleHRlcm5hbEZvcm1TdWJtaXR0ZWQgJiYgcGh4Q2hhbmdlICYmICFwaHhTdWJtaXQpe1xuICAgICAgICBleHRlcm5hbEZvcm1TdWJtaXR0ZWQgPSB0cnVlXG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKVxuICAgICAgICB0aGlzLndpdGhpbk93bmVycyhlLnRhcmdldCwgdmlldyA9PiB7XG4gICAgICAgICAgdmlldy5kaXNhYmxlRm9ybShlLnRhcmdldClcbiAgICAgICAgICAvLyBzYWZhcmkgbmVlZHMgbmV4dCB0aWNrXG4gICAgICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgICBpZihET00uaXNVbmxvYWRhYmxlRm9ybVN1Ym1pdChlKSl7IHRoaXMudW5sb2FkKCkgfVxuICAgICAgICAgICAgZS50YXJnZXQuc3VibWl0KClcbiAgICAgICAgICB9KVxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH0sIHRydWUpXG5cbiAgICB0aGlzLm9uKFwic3VibWl0XCIsIGUgPT4ge1xuICAgICAgbGV0IHBoeEV2ZW50ID0gZS50YXJnZXQuZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhcInN1Ym1pdFwiKSlcbiAgICAgIGlmKCFwaHhFdmVudCl7XG4gICAgICAgIGlmKERPTS5pc1VubG9hZGFibGVGb3JtU3VibWl0KGUpKXsgdGhpcy51bmxvYWQoKSB9XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICBlLnRhcmdldC5kaXNhYmxlZCA9IHRydWVcbiAgICAgIHRoaXMud2l0aGluT3duZXJzKGUudGFyZ2V0LCB2aWV3ID0+IHtcbiAgICAgICAgSlMuZXhlYyhcInN1Ym1pdFwiLCBwaHhFdmVudCwgdmlldywgZS50YXJnZXQsIFtcInB1c2hcIiwge3N1Ym1pdHRlcjogZS5zdWJtaXR0ZXJ9XSlcbiAgICAgIH0pXG4gICAgfSwgZmFsc2UpXG5cbiAgICBmb3IobGV0IHR5cGUgb2YgW1wiY2hhbmdlXCIsIFwiaW5wdXRcIl0pe1xuICAgICAgdGhpcy5vbih0eXBlLCBlID0+IHtcbiAgICAgICAgbGV0IHBoeENoYW5nZSA9IHRoaXMuYmluZGluZyhcImNoYW5nZVwiKVxuICAgICAgICBsZXQgaW5wdXQgPSBlLnRhcmdldFxuICAgICAgICBsZXQgaW5wdXRFdmVudCA9IGlucHV0LmdldEF0dHJpYnV0ZShwaHhDaGFuZ2UpXG4gICAgICAgIGxldCBmb3JtRXZlbnQgPSBpbnB1dC5mb3JtICYmIGlucHV0LmZvcm0uZ2V0QXR0cmlidXRlKHBoeENoYW5nZSlcbiAgICAgICAgbGV0IHBoeEV2ZW50ID0gaW5wdXRFdmVudCB8fCBmb3JtRXZlbnRcbiAgICAgICAgaWYoIXBoeEV2ZW50KXsgcmV0dXJuIH1cbiAgICAgICAgaWYoaW5wdXQudHlwZSA9PT0gXCJudW1iZXJcIiAmJiBpbnB1dC52YWxpZGl0eSAmJiBpbnB1dC52YWxpZGl0eS5iYWRJbnB1dCl7IHJldHVybiB9XG5cbiAgICAgICAgbGV0IGRpc3BhdGNoZXIgPSBpbnB1dEV2ZW50ID8gaW5wdXQgOiBpbnB1dC5mb3JtXG4gICAgICAgIGxldCBjdXJyZW50SXRlcmF0aW9ucyA9IGl0ZXJhdGlvbnNcbiAgICAgICAgaXRlcmF0aW9ucysrXG4gICAgICAgIGxldCB7YXQ6IGF0LCB0eXBlOiBsYXN0VHlwZX0gPSBET00ucHJpdmF0ZShpbnB1dCwgXCJwcmV2LWl0ZXJhdGlvblwiKSB8fCB7fVxuICAgICAgICAvLyBCcm93c2VycyBzaG91bGQgYWx3YXlzIGZpcmUgYXQgbGVhc3Qgb25lIFwiaW5wdXRcIiBldmVudCBiZWZvcmUgZXZlcnkgXCJjaGFuZ2VcIlxuICAgICAgICAvLyBJZ25vcmUgXCJjaGFuZ2VcIiBldmVudHMsIHVubGVzcyB0aGVyZSB3YXMgbm8gcHJpb3IgXCJpbnB1dFwiIGV2ZW50LlxuICAgICAgICAvLyBUaGlzIGNvdWxkIGhhcHBlbiBpZiB1c2VyIGNvZGUgdHJpZ2dlcnMgYSBcImNoYW5nZVwiIGV2ZW50LCBvciBpZiB0aGUgYnJvd3NlciBpcyBub24tY29uZm9ybWluZy5cbiAgICAgICAgaWYoYXQgPT09IGN1cnJlbnRJdGVyYXRpb25zIC0gMSAmJiB0eXBlID09PSBcImNoYW5nZVwiICYmIGxhc3RUeXBlID09PSBcImlucHV0XCIpeyByZXR1cm4gfVxuXG4gICAgICAgIERPTS5wdXRQcml2YXRlKGlucHV0LCBcInByZXYtaXRlcmF0aW9uXCIsIHthdDogY3VycmVudEl0ZXJhdGlvbnMsIHR5cGU6IHR5cGV9KVxuXG4gICAgICAgIHRoaXMuZGVib3VuY2UoaW5wdXQsIGUsIHR5cGUsICgpID0+IHtcbiAgICAgICAgICB0aGlzLndpdGhpbk93bmVycyhkaXNwYXRjaGVyLCB2aWV3ID0+IHtcbiAgICAgICAgICAgIERPTS5wdXRQcml2YXRlKGlucHV0LCBQSFhfSEFTX0ZPQ1VTRUQsIHRydWUpXG4gICAgICAgICAgICBpZighRE9NLmlzVGV4dHVhbElucHV0KGlucHV0KSl7XG4gICAgICAgICAgICAgIHRoaXMuc2V0QWN0aXZlRWxlbWVudChpbnB1dClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEpTLmV4ZWMoXCJjaGFuZ2VcIiwgcGh4RXZlbnQsIHZpZXcsIGlucHV0LCBbXCJwdXNoXCIsIHtfdGFyZ2V0OiBlLnRhcmdldC5uYW1lLCBkaXNwYXRjaGVyOiBkaXNwYXRjaGVyfV0pXG4gICAgICAgICAgfSlcbiAgICAgICAgfSlcbiAgICAgIH0sIGZhbHNlKVxuICAgIH1cbiAgICB0aGlzLm9uKFwicmVzZXRcIiwgKGUpID0+IHtcbiAgICAgIGxldCBmb3JtID0gZS50YXJnZXRcbiAgICAgIERPTS5yZXNldEZvcm0oZm9ybSwgdGhpcy5iaW5kaW5nKFBIWF9GRUVEQkFDS19GT1IpKVxuICAgICAgbGV0IGlucHV0ID0gQXJyYXkuZnJvbShmb3JtLmVsZW1lbnRzKS5maW5kKGVsID0+IGVsLnR5cGUgPT09IFwicmVzZXRcIilcbiAgICAgIC8vIHdhaXQgdW50aWwgbmV4dCB0aWNrIHRvIGdldCB1cGRhdGVkIGlucHV0IHZhbHVlXG4gICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgaW5wdXQuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJpbnB1dFwiLCB7YnViYmxlczogdHJ1ZSwgY2FuY2VsYWJsZTogZmFsc2V9KSlcbiAgICAgIH0pXG4gICAgfSlcbiAgfVxuXG4gIGRlYm91bmNlKGVsLCBldmVudCwgZXZlbnRUeXBlLCBjYWxsYmFjayl7XG4gICAgaWYoZXZlbnRUeXBlID09PSBcImJsdXJcIiB8fCBldmVudFR5cGUgPT09IFwiZm9jdXNvdXRcIil7IHJldHVybiBjYWxsYmFjaygpIH1cblxuICAgIGxldCBwaHhEZWJvdW5jZSA9IHRoaXMuYmluZGluZyhQSFhfREVCT1VOQ0UpXG4gICAgbGV0IHBoeFRocm90dGxlID0gdGhpcy5iaW5kaW5nKFBIWF9USFJPVFRMRSlcbiAgICBsZXQgZGVmYXVsdERlYm91bmNlID0gdGhpcy5kZWZhdWx0cy5kZWJvdW5jZS50b1N0cmluZygpXG4gICAgbGV0IGRlZmF1bHRUaHJvdHRsZSA9IHRoaXMuZGVmYXVsdHMudGhyb3R0bGUudG9TdHJpbmcoKVxuXG4gICAgdGhpcy53aXRoaW5Pd25lcnMoZWwsIHZpZXcgPT4ge1xuICAgICAgbGV0IGFzeW5jRmlsdGVyID0gKCkgPT4gIXZpZXcuaXNEZXN0cm95ZWQoKSAmJiBkb2N1bWVudC5ib2R5LmNvbnRhaW5zKGVsKVxuICAgICAgRE9NLmRlYm91bmNlKGVsLCBldmVudCwgcGh4RGVib3VuY2UsIGRlZmF1bHREZWJvdW5jZSwgcGh4VGhyb3R0bGUsIGRlZmF1bHRUaHJvdHRsZSwgYXN5bmNGaWx0ZXIsICgpID0+IHtcbiAgICAgICAgY2FsbGJhY2soKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgc2lsZW5jZUV2ZW50cyhjYWxsYmFjayl7XG4gICAgdGhpcy5zaWxlbmNlZCA9IHRydWVcbiAgICBjYWxsYmFjaygpXG4gICAgdGhpcy5zaWxlbmNlZCA9IGZhbHNlXG4gIH1cblxuICBvbihldmVudCwgY2FsbGJhY2spe1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKGV2ZW50LCBlID0+IHtcbiAgICAgIGlmKCF0aGlzLnNpbGVuY2VkKXsgY2FsbGJhY2soZSkgfVxuICAgIH0pXG4gIH1cbn1cblxuY2xhc3MgVHJhbnNpdGlvblNldCB7XG4gIGNvbnN0cnVjdG9yKCl7XG4gICAgdGhpcy50cmFuc2l0aW9ucyA9IG5ldyBTZXQoKVxuICAgIHRoaXMucGVuZGluZ09wcyA9IFtdXG4gIH1cblxuICByZXNldCgpe1xuICAgIHRoaXMudHJhbnNpdGlvbnMuZm9yRWFjaCh0aW1lciA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXIpXG4gICAgICB0aGlzLnRyYW5zaXRpb25zLmRlbGV0ZSh0aW1lcilcbiAgICB9KVxuICAgIHRoaXMuZmx1c2hQZW5kaW5nT3BzKClcbiAgfVxuXG4gIGFmdGVyKGNhbGxiYWNrKXtcbiAgICBpZih0aGlzLnNpemUoKSA9PT0gMCl7XG4gICAgICBjYWxsYmFjaygpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHVzaFBlbmRpbmdPcChjYWxsYmFjaylcbiAgICB9XG4gIH1cblxuICBhZGRUcmFuc2l0aW9uKHRpbWUsIG9uU3RhcnQsIG9uRG9uZSl7XG4gICAgb25TdGFydCgpXG4gICAgbGV0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnRyYW5zaXRpb25zLmRlbGV0ZSh0aW1lcilcbiAgICAgIG9uRG9uZSgpXG4gICAgICB0aGlzLmZsdXNoUGVuZGluZ09wcygpXG4gICAgfSwgdGltZSlcbiAgICB0aGlzLnRyYW5zaXRpb25zLmFkZCh0aW1lcilcbiAgfVxuXG4gIHB1c2hQZW5kaW5nT3Aob3ApeyB0aGlzLnBlbmRpbmdPcHMucHVzaChvcCkgfVxuXG4gIHNpemUoKXsgcmV0dXJuIHRoaXMudHJhbnNpdGlvbnMuc2l6ZSB9XG5cbiAgZmx1c2hQZW5kaW5nT3BzKCl7XG4gICAgaWYodGhpcy5zaXplKCkgPiAwKXsgcmV0dXJuIH1cbiAgICBsZXQgb3AgPSB0aGlzLnBlbmRpbmdPcHMuc2hpZnQoKVxuICAgIGlmKG9wKXtcbiAgICAgIG9wKClcbiAgICAgIHRoaXMuZmx1c2hQZW5kaW5nT3BzKClcbiAgICB9XG4gIH1cbn1cbiIsICIvLyBJZiB5b3Ugd2FudCB0byB1c2UgUGhvZW5peCBjaGFubmVscywgcnVuIGBtaXggaGVscCBwaHguZ2VuLmNoYW5uZWxgXG4vLyB0byBnZXQgc3RhcnRlZCBhbmQgdGhlbiB1bmNvbW1lbnQgdGhlIGxpbmUgYmVsb3cuXG4vLyBpbXBvcnQgXCIuL3VzZXJfc29ja2V0LmpzXCJcblxuLy8gWW91IGNhbiBpbmNsdWRlIGRlcGVuZGVuY2llcyBpbiB0d28gd2F5cy5cbi8vXG4vLyBUaGUgc2ltcGxlc3Qgb3B0aW9uIGlzIHRvIHB1dCB0aGVtIGluIGFzc2V0cy92ZW5kb3IgYW5kXG4vLyBpbXBvcnQgdGhlbSB1c2luZyByZWxhdGl2ZSBwYXRoczpcbi8vXG4vLyAgICAgaW1wb3J0IFwiLi4vdmVuZG9yL3NvbWUtcGFja2FnZS5qc1wiXG4vL1xuLy8gQWx0ZXJuYXRpdmVseSwgeW91IGNhbiBgbnBtIGluc3RhbGwgc29tZS1wYWNrYWdlIC0tcHJlZml4IGFzc2V0c2AgYW5kIGltcG9ydFxuLy8gdGhlbSB1c2luZyBhIHBhdGggc3RhcnRpbmcgd2l0aCB0aGUgcGFja2FnZSBuYW1lOlxuLy9cbi8vICAgICBpbXBvcnQgXCJzb21lLXBhY2thZ2VcIlxuLy9cblxuLy8gSW5jbHVkZSBwaG9lbml4X2h0bWwgdG8gaGFuZGxlIG1ldGhvZD1QVVQvREVMRVRFIGluIGZvcm1zIGFuZCBidXR0b25zLlxuaW1wb3J0IFwicGhvZW5peF9odG1sXCJcbi8vIEVzdGFibGlzaCBQaG9lbml4IFNvY2tldCBhbmQgTGl2ZVZpZXcgY29uZmlndXJhdGlvbi5cbmltcG9ydCB7U29ja2V0fSBmcm9tIFwicGhvZW5peFwiXG5pbXBvcnQge0xpdmVTb2NrZXR9IGZyb20gXCJwaG9lbml4X2xpdmVfdmlld1wiXG5pbXBvcnQgdG9wYmFyIGZyb20gXCIuLi92ZW5kb3IvdG9wYmFyXCJcblxubGV0IGNzcmZUb2tlbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJtZXRhW25hbWU9J2NzcmYtdG9rZW4nXVwiKS5nZXRBdHRyaWJ1dGUoXCJjb250ZW50XCIpXG5sZXQgbGl2ZVNvY2tldCA9IG5ldyBMaXZlU29ja2V0KFwiL2xpdmVcIiwgU29ja2V0LCB7cGFyYW1zOiB7X2NzcmZfdG9rZW46IGNzcmZUb2tlbn19KVxuXG4vLyBTaG93IHByb2dyZXNzIGJhciBvbiBsaXZlIG5hdmlnYXRpb24gYW5kIGZvcm0gc3VibWl0c1xudG9wYmFyLmNvbmZpZyh7YmFyQ29sb3JzOiB7MDogXCIjMjlkXCJ9LCBzaGFkb3dDb2xvcjogXCJyZ2JhKDAsIDAsIDAsIC4zKVwifSlcbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicGh4OnBhZ2UtbG9hZGluZy1zdGFydFwiLCBfaW5mbyA9PiB0b3BiYXIuc2hvdygzMDApKVxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJwaHg6cGFnZS1sb2FkaW5nLXN0b3BcIiwgX2luZm8gPT4gdG9wYmFyLmhpZGUoKSlcblxuLy8gY29ubmVjdCBpZiB0aGVyZSBhcmUgYW55IExpdmVWaWV3cyBvbiB0aGUgcGFnZVxubGl2ZVNvY2tldC5jb25uZWN0KClcblxuLy8gZXhwb3NlIGxpdmVTb2NrZXQgb24gd2luZG93IGZvciB3ZWIgY29uc29sZSBkZWJ1ZyBsb2dzIGFuZCBsYXRlbmN5IHNpbXVsYXRpb246XG4vLyA+PiBsaXZlU29ja2V0LmVuYWJsZURlYnVnKClcbi8vID4+IGxpdmVTb2NrZXQuZW5hYmxlTGF0ZW5jeVNpbSgxMDAwKSAgLy8gZW5hYmxlZCBmb3IgZHVyYXRpb24gb2YgYnJvd3NlciBzZXNzaW9uXG4vLyA+PiBsaXZlU29ja2V0LmRpc2FibGVMYXRlbmN5U2ltKClcbndpbmRvdy5saXZlU29ja2V0ID0gbGl2ZVNvY2tldFxuXG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7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QUE7TUFBQSxPQUNLO0FBQ0wsYUFBSyxjQUFjLFFBQUE7TUFBQTtJQUFBO0lBSXZCLGNBQWMsTUFBTSxTQUFTLFFBQU87QUFDbEMsY0FBQTtBQUNBLFVBQUksUUFBUSxXQUFXLE1BQU07QUFDM0IsYUFBSyxZQUFZLE9BQU8sS0FBQTtBQUN4QixlQUFBO0FBQ0EsYUFBSyxnQkFBQTtNQUFBLEdBQ0osSUFBQTtBQUNILFdBQUssWUFBWSxJQUFJLEtBQUE7SUFBQTtJQUd2QixjQUFjLElBQUc7QUFBRSxXQUFLLFdBQVcsS0FBSyxFQUFBO0lBQUE7SUFFeEMsT0FBTTtBQUFFLGFBQU8sS0FBSyxZQUFZO0lBQUE7SUFFaEMsa0JBQWlCO0FBQ2YsVUFBRyxLQUFLLEtBQUEsSUFBUyxHQUFFO0FBQUU7TUFBQTtBQUNyQixVQUFJLEtBQUssS0FBSyxXQUFXLE1BQUE7QUFDekIsVUFBRyxJQUFHO0FBQ0osV0FBQTtBQUNBLGFBQUssZ0JBQUE7TUFBQTtJQUFBO0VBQUE7OztBQ2g2Qlgsc0JBQW1CO0FBRW5CLE1BQUksWUFBWSxTQUFTLGNBQWMseUJBQXlCLEVBQUUsYUFBYSxTQUFTO0FBQ3hGLE1BQUksYUFBYSxJQUFJLFdBQVcsU0FBUyxRQUFRLEVBQUMsUUFBUSxFQUFDLGFBQWEsVUFBUyxFQUFDLENBQUM7QUFHbkYsZ0JBQUFDLFFBQU8sT0FBTyxFQUFDLFdBQVcsRUFBQyxHQUFHLE9BQU0sR0FBRyxhQUFhLG9CQUFtQixDQUFDO0FBQ3hFLFNBQU8saUJBQWlCLDBCQUEwQixXQUFTLGNBQUFBLFFBQU8sS0FBSyxHQUFHLENBQUM7QUFDM0UsU0FBTyxpQkFBaUIseUJBQXlCLFdBQVMsY0FBQUEsUUFBTyxLQUFLLENBQUM7QUFHdkUsYUFBVyxRQUFRO0FBTW5CLFNBQU8sYUFBYTsiLAogICJuYW1lcyI6IFsid2luZG93IiwgImRvY3VtZW50IiwgInRvcGJhciIsICJDdXN0b21FdmVudCIsICJjbG9zdXJlMiIsICJsaXZlU29ja2V0IiwgImNsb3N1cmUiLCAidG9wYmFyIl0KfQo= diff --git a/test_app/priv/static/assets/home.css b/test_app/priv/static/assets/home.css deleted file mode 100644 index 4746663..0000000 --- a/test_app/priv/static/assets/home.css +++ /dev/null @@ -1,1113 +0,0 @@ -/* Default styling for the home page, this file can be deleted safely */ - -/* -! tailwindcss v3.2.4 | MIT License | https://tailwindcss.com -*/ - -/* -1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) -2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) -*/ - -*, -::before, -::after { - box-sizing: border-box; - /* 1 */ - border-width: 0; - /* 2 */ - border-style: solid; - /* 2 */ - border-color: #e5e7eb; - /* 2 */ -} - -::before, -::after { - --tw-content: ''; -} - -/* -1. Use a consistent sensible line-height in all browsers. -2. Prevent adjustments of font size after orientation changes in iOS. -3. Use a more readable tab size. -4. Use the user's configured `sans` font-family by default. -5. Use the user's configured `sans` font-feature-settings by default. -*/ - -html { - line-height: 1.5; - /* 1 */ - -webkit-text-size-adjust: 100%; - /* 2 */ - -moz-tab-size: 4; - /* 3 */ - -o-tab-size: 4; - tab-size: 4; - /* 3 */ - font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - /* 4 */ - font-feature-settings: normal; - /* 5 */ -} - -/* -1. Remove the margin in all browsers. -2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. -*/ - -body { - margin: 0; - /* 1 */ - line-height: inherit; - /* 2 */ -} - -/* -1. Add the correct height in Firefox. -2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) -3. Ensure horizontal rules are visible by default. -*/ - -hr { - height: 0; - /* 1 */ - color: inherit; - /* 2 */ - border-top-width: 1px; - /* 3 */ -} - -/* -Add the correct text decoration in Chrome, Edge, and Safari. -*/ - -abbr:where([title]) { - -webkit-text-decoration: underline dotted; - text-decoration: underline dotted; -} - -/* -Remove the default font size and weight for headings. -*/ - -h1, -h2, -h3, -h4, -h5, -h6 { - font-size: inherit; - font-weight: inherit; -} - -/* -Reset links to optimize for opt-in styling instead of opt-out. -*/ - -a { - color: inherit; - text-decoration: inherit; -} - -/* -Add the correct font weight in Edge and Safari. -*/ - -b, -strong { - font-weight: bolder; -} - -/* -1. Use the user's configured `mono` font family by default. -2. Correct the odd `em` font sizing in all browsers. -*/ - -code, -kbd, -samp, -pre { - font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; - /* 1 */ - font-size: 1em; - /* 2 */ -} - -/* -Add the correct font size in all browsers. -*/ - -small { - font-size: 80%; -} - -/* -Prevent `sub` and `sup` elements from affecting the line height in all browsers. -*/ - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sub { - bottom: -0.25em; -} - -sup { - top: -0.5em; -} - -/* -1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) -2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) -3. Remove gaps between table borders by default. -*/ - -table { - text-indent: 0; - /* 1 */ - border-color: inherit; - /* 2 */ - border-collapse: collapse; - /* 3 */ -} - -/* -1. Change the font styles in all browsers. -2. Remove the margin in Firefox and Safari. -3. Remove default padding in all browsers. -*/ - -button, -input, -optgroup, -select, -textarea { - font-family: inherit; - /* 1 */ - font-size: 100%; - /* 1 */ - font-weight: inherit; - /* 1 */ - line-height: inherit; - /* 1 */ - color: inherit; - /* 1 */ - margin: 0; - /* 2 */ - padding: 0; - /* 3 */ -} - -/* -Remove the inheritance of text transform in Edge and Firefox. -*/ - -button, -select { - text-transform: none; -} - -/* -1. Correct the inability to style clickable types in iOS and Safari. -2. Remove default button styles. -*/ - -button, -[type='button'], -[type='reset'], -[type='submit'] { - -webkit-appearance: button; - /* 1 */ - background-color: transparent; - /* 2 */ - background-image: none; - /* 2 */ -} - -/* -Use the modern Firefox focus style for all focusable elements. -*/ - -:-moz-focusring { - outline: auto; -} - -/* -Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) -*/ - -:-moz-ui-invalid { - box-shadow: none; -} - -/* -Add the correct vertical alignment in Chrome and Firefox. -*/ - -progress { - vertical-align: baseline; -} - -/* -Correct the cursor style of increment and decrement buttons in Safari. -*/ - -::-webkit-inner-spin-button, -::-webkit-outer-spin-button { - height: auto; -} - -/* -1. Correct the odd appearance in Chrome and Safari. -2. Correct the outline style in Safari. -*/ - -[type='search'] { - -webkit-appearance: textfield; - /* 1 */ - outline-offset: -2px; - /* 2 */ -} - -/* -Remove the inner padding in Chrome and Safari on macOS. -*/ - -::-webkit-search-decoration { - -webkit-appearance: none; -} - -/* -1. Correct the inability to style clickable types in iOS and Safari. -2. Change font properties to `inherit` in Safari. -*/ - -::-webkit-file-upload-button { - -webkit-appearance: button; - /* 1 */ - font: inherit; - /* 2 */ -} - -/* -Add the correct display in Chrome and Safari. -*/ - -summary { - display: list-item; -} - -/* -Removes the default spacing and border for appropriate elements. -*/ - -blockquote, -dl, -dd, -h1, -h2, -h3, -h4, -h5, -h6, -hr, -figure, -p, -pre { - margin: 0; -} - -fieldset { - margin: 0; - padding: 0; -} - -legend { - padding: 0; -} - -ol, -ul, -menu { - list-style: none; - margin: 0; - padding: 0; -} - -/* -Prevent resizing textareas horizontally by default. -*/ - -textarea { - resize: vertical; -} - -/* -1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) -2. Set the default placeholder color to the user's configured gray 400 color. -*/ - -input::-moz-placeholder, textarea::-moz-placeholder { - opacity: 1; - /* 1 */ - color: #9ca3af; - /* 2 */ -} - -input::placeholder, -textarea::placeholder { - opacity: 1; - /* 1 */ - color: #9ca3af; - /* 2 */ -} - -/* -Set the default cursor for buttons. -*/ - -button, -[role="button"] { - cursor: pointer; -} - -/* -Make sure disabled buttons don't get the pointer cursor. -*/ - -:disabled { - cursor: default; -} - -/* -1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) -2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) - This can trigger a poorly considered lint error in some tools but is included by design. -*/ - -img, -svg, -video, -canvas, -audio, -iframe, -embed, -object { - display: block; - /* 1 */ - vertical-align: middle; - /* 2 */ -} - -/* -Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) -*/ - -img, -video { - max-width: 100%; - height: auto; -} - -/* Make elements with the HTML hidden attribute stay hidden by default */ - -[hidden] { - display: none; -} - -[type='text'],[type='email'],[type='url'],[type='password'],[type='number'],[type='date'],[type='datetime-local'],[type='month'],[type='search'],[type='tel'],[type='time'],[type='week'],[multiple],textarea,select { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background-color: #fff; - border-color: #6b7280; - border-width: 1px; - border-radius: 0px; - padding-top: 0.5rem; - padding-right: 0.75rem; - padding-bottom: 0.5rem; - padding-left: 0.75rem; - font-size: 1rem; - line-height: 1.5rem; - --tw-shadow: 0 0 #0000; -} - -[type='text']:focus, [type='email']:focus, [type='url']:focus, [type='password']:focus, [type='number']:focus, [type='date']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='week']:focus, [multiple]:focus, textarea:focus, select:focus { - outline: 2px solid transparent; - outline-offset: 2px; - --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-color: #2563eb; - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - border-color: #2563eb; -} - -input::-moz-placeholder, textarea::-moz-placeholder { - color: #6b7280; - opacity: 1; -} - -input::placeholder,textarea::placeholder { - color: #6b7280; - opacity: 1; -} - -::-webkit-datetime-edit-fields-wrapper { - padding: 0; -} - -::-webkit-date-and-time-value { - min-height: 1.5em; -} - -::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field { - padding-top: 0; - padding-bottom: 0; -} - -select { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e"); - background-position: right 0.5rem center; - background-repeat: no-repeat; - background-size: 1.5em 1.5em; - padding-right: 2.5rem; - -webkit-print-color-adjust: exact; - print-color-adjust: exact; -} - -[multiple] { - background-image: initial; - background-position: initial; - background-repeat: unset; - background-size: initial; - padding-right: 0.75rem; - -webkit-print-color-adjust: unset; - print-color-adjust: unset; -} - -[type='checkbox'],[type='radio'] { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - padding: 0; - -webkit-print-color-adjust: exact; - print-color-adjust: exact; - display: inline-block; - vertical-align: middle; - background-origin: border-box; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; - flex-shrink: 0; - height: 1rem; - width: 1rem; - color: #2563eb; - background-color: #fff; - border-color: #6b7280; - border-width: 1px; - --tw-shadow: 0 0 #0000; -} - -[type='checkbox'] { - border-radius: 0px; -} - -[type='radio'] { - border-radius: 100%; -} - -[type='checkbox']:focus,[type='radio']:focus { - outline: 2px solid transparent; - outline-offset: 2px; - --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); - --tw-ring-offset-width: 2px; - --tw-ring-offset-color: #fff; - --tw-ring-color: #2563eb; - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); -} - -[type='checkbox']:checked,[type='radio']:checked { - border-color: transparent; - background-color: currentColor; - background-size: 100% 100%; - background-position: center; - background-repeat: no-repeat; -} - -[type='checkbox']:checked { - background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e"); -} - -[type='radio']:checked { - background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e"); -} - -[type='checkbox']:checked:hover,[type='checkbox']:checked:focus,[type='radio']:checked:hover,[type='radio']:checked:focus { - border-color: transparent; - background-color: currentColor; -} - -[type='checkbox']:indeterminate { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e"); - border-color: transparent; - background-color: currentColor; - background-size: 100% 100%; - background-position: center; - background-repeat: no-repeat; -} - -[type='checkbox']:indeterminate:hover,[type='checkbox']:indeterminate:focus { - border-color: transparent; - background-color: currentColor; -} - -[type='file'] { - background: unset; - border-color: inherit; - border-width: 0; - border-radius: 0; - padding: 0; - font-size: unset; - line-height: inherit; -} - -[type='file']:focus { - outline: 1px solid ButtonText; - outline: 1px auto -webkit-focus-ring-color; -} - -*, ::before, ::after { - --tw-border-spacing-x: 0; - --tw-border-spacing-y: 0; - --tw-translate-x: 0; - --tw-translate-y: 0; - --tw-rotate: 0; - --tw-skew-x: 0; - --tw-skew-y: 0; - --tw-scale-x: 1; - --tw-scale-y: 1; - --tw-pan-x: ; - --tw-pan-y: ; - --tw-pinch-zoom: ; - --tw-scroll-snap-strictness: proximity; - --tw-ordinal: ; - --tw-slashed-zero: ; - --tw-numeric-figure: ; - --tw-numeric-spacing: ; - --tw-numeric-fraction: ; - --tw-ring-inset: ; - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-color: rgb(59 130 246 / 0.5); - --tw-ring-offset-shadow: 0 0 #0000; - --tw-ring-shadow: 0 0 #0000; - --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; - --tw-blur: ; - --tw-brightness: ; - --tw-contrast: ; - --tw-grayscale: ; - --tw-hue-rotate: ; - --tw-invert: ; - --tw-saturate: ; - --tw-sepia: ; - --tw-drop-shadow: ; - --tw-backdrop-blur: ; - --tw-backdrop-brightness: ; - --tw-backdrop-contrast: ; - --tw-backdrop-grayscale: ; - --tw-backdrop-hue-rotate: ; - --tw-backdrop-invert: ; - --tw-backdrop-opacity: ; - --tw-backdrop-saturate: ; - --tw-backdrop-sepia: ; -} - -::backdrop { - --tw-border-spacing-x: 0; - --tw-border-spacing-y: 0; - --tw-translate-x: 0; - --tw-translate-y: 0; - --tw-rotate: 0; - --tw-skew-x: 0; - --tw-skew-y: 0; - --tw-scale-x: 1; - --tw-scale-y: 1; - --tw-pan-x: ; - --tw-pan-y: ; - --tw-pinch-zoom: ; - --tw-scroll-snap-strictness: proximity; - --tw-ordinal: ; - --tw-slashed-zero: ; - --tw-numeric-figure: ; - --tw-numeric-spacing: ; - --tw-numeric-fraction: ; - --tw-ring-inset: ; - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-color: rgb(59 130 246 / 0.5); - --tw-ring-offset-shadow: 0 0 #0000; - --tw-ring-shadow: 0 0 #0000; - --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; - --tw-blur: ; - --tw-brightness: ; - --tw-contrast: ; - --tw-grayscale: ; - --tw-hue-rotate: ; - --tw-invert: ; - --tw-saturate: ; - --tw-sepia: ; - --tw-drop-shadow: ; - --tw-backdrop-blur: ; - --tw-backdrop-brightness: ; - --tw-backdrop-contrast: ; - --tw-backdrop-grayscale: ; - --tw-backdrop-hue-rotate: ; - --tw-backdrop-invert: ; - --tw-backdrop-opacity: ; - --tw-backdrop-saturate: ; - --tw-backdrop-sepia: ; -} - -.static { - position: static; -} - -.fixed { - position: fixed; -} - -.absolute { - position: absolute; -} - -.relative { - position: relative; -} - -.inset-0 { - top: 0px; - right: 0px; - bottom: 0px; - left: 0px; -} - -.inset-y-0 { - top: 0px; - bottom: 0px; -} - -.right-0 { - right: 0px; -} - -.left-\[40rem\] { - left: 40rem; -} - -.z-0 { - z-index: 0; -} - -.mx-auto { - margin-left: auto; - margin-right: auto; -} - -.-mx-2 { - margin-left: -0.5rem; - margin-right: -0.5rem; -} - -.-my-0\.5 { - margin-top: -0.125rem; - margin-bottom: -0.125rem; -} - -.-my-0 { - margin-top: -0px; - margin-bottom: -0px; -} - -.mt-10 { - margin-top: 2.5rem; -} - -.ml-3 { - margin-left: 0.75rem; -} - -.mt-4 { - margin-top: 1rem; -} - -.flex { - display: flex; -} - -.inline-flex { - display: inline-flex; -} - -.grid { - display: grid; -} - -.contents { - display: contents; -} - -.hidden { - display: none; -} - -.h-6 { - height: 1.5rem; -} - -.h-full { - height: 100%; -} - -.h-12 { - height: 3rem; -} - -.h-4 { - height: 1rem; -} - -.w-full { - width: 100%; -} - -.w-6 { - width: 1.5rem; -} - -.w-4 { - width: 1rem; -} - -.max-w-2xl { - max-width: 42rem; -} - -.max-w-xl { - max-width: 36rem; -} - -.grid-cols-1 { - grid-template-columns: repeat(1, minmax(0, 1fr)); -} - -.items-center { - align-items: center; -} - -.justify-between { - justify-content: space-between; -} - -.gap-4 { - gap: 1rem; -} - -.gap-3 { - gap: 0.75rem; -} - -.gap-x-6 { - -moz-column-gap: 1.5rem; - column-gap: 1.5rem; -} - -.gap-y-4 { - row-gap: 1rem; -} - -.rounded-full { - border-radius: 9999px; -} - -.rounded-lg { - border-radius: 0.5rem; -} - -.rounded-2xl { - border-radius: 1rem; -} - -.border-b { - border-bottom-width: 1px; -} - -.border-zinc-100 { - --tw-border-opacity: 1; - border-color: rgb(244 244 245 / var(--tw-border-opacity)); -} - -.bg-brand\/5 { - background-color: rgb(253 79 0 / 0.05); -} - -.bg-zinc-100 { - --tw-bg-opacity: 1; - background-color: rgb(244 244 245 / var(--tw-bg-opacity)); -} - -.bg-white { - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); -} - -.bg-zinc-50 { - --tw-bg-opacity: 1; - background-color: rgb(250 250 250 / var(--tw-bg-opacity)); -} - -.fill-zinc-400 { - fill: #a1a1aa; -} - -.px-4 { - padding-left: 1rem; - padding-right: 1rem; -} - -.py-3 { - padding-top: 0.75rem; - padding-bottom: 0.75rem; -} - -.px-2 { - padding-left: 0.5rem; - padding-right: 0.5rem; -} - -.py-1 { - padding-top: 0.25rem; - padding-bottom: 0.25rem; -} - -.py-20 { - padding-top: 5rem; - padding-bottom: 5rem; -} - -.py-10 { - padding-top: 2.5rem; - padding-bottom: 2.5rem; -} - -.px-6 { - padding-left: 1.5rem; - padding-right: 1.5rem; -} - -.py-4 { - padding-top: 1rem; - padding-bottom: 1rem; -} - -.py-0\.5 { - padding-top: 0.125rem; - padding-bottom: 0.125rem; -} - -.py-0 { - padding-top: 0px; - padding-bottom: 0px; -} - -.text-\[0\.8125rem\] { - font-size: 0.8125rem; -} - -.text-sm { - font-size: 0.875rem; - line-height: 1.25rem; -} - -.text-\[2rem\] { - font-size: 2rem; -} - -.text-base { - font-size: 1rem; - line-height: 1.5rem; -} - -.font-medium { - font-weight: 500; -} - -.font-semibold { - font-weight: 600; -} - -.leading-6 { - line-height: 1.5rem; -} - -.leading-10 { - line-height: 2.5rem; -} - -.leading-7 { - line-height: 1.75rem; -} - -.tracking-tighter { - letter-spacing: -0.05em; -} - -.text-brand { - --tw-text-opacity: 1; - color: rgb(253 79 0 / var(--tw-text-opacity)); -} - -.text-zinc-900 { - --tw-text-opacity: 1; - color: rgb(24 24 27 / var(--tw-text-opacity)); -} - -.text-zinc-600 { - --tw-text-opacity: 1; - color: rgb(82 82 91 / var(--tw-text-opacity)); -} - -.text-zinc-700 { - --tw-text-opacity: 1; - color: rgb(63 63 70 / var(--tw-text-opacity)); -} - -.antialiased { - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.transition { - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 150ms; -} - -/* This file is for your main application CSS */ - -.hover\:bg-zinc-200\/80:hover { - background-color: rgb(228 228 231 / 0.8); -} - -.hover\:bg-zinc-50:hover { - --tw-bg-opacity: 1; - background-color: rgb(250 250 250 / var(--tw-bg-opacity)); -} - -.hover\:text-zinc-700:hover { - --tw-text-opacity: 1; - color: rgb(63 63 70 / var(--tw-text-opacity)); -} - -.hover\:text-zinc-900:hover { - --tw-text-opacity: 1; - color: rgb(24 24 27 / var(--tw-text-opacity)); -} - -.active\:text-zinc-900\/70:active { - color: rgb(24 24 27 / 0.7); -} - -.group:hover .group-hover\:bg-zinc-100 { - --tw-bg-opacity: 1; - background-color: rgb(244 244 245 / var(--tw-bg-opacity)); -} - -.group:hover .group-hover\:fill-zinc-600 { - fill: #52525b; -} - -@media (min-width: 640px) { - .sm\:w-auto { - width: auto; - } - - .sm\:grid-cols-3 { - grid-template-columns: repeat(3, minmax(0, 1fr)); - } - - .sm\:grid-cols-2 { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - - .sm\:flex-col { - flex-direction: column; - } - - .sm\:px-6 { - padding-left: 1.5rem; - padding-right: 1.5rem; - } - - .sm\:py-28 { - padding-top: 7rem; - padding-bottom: 7rem; - } - - .sm\:py-6 { - padding-top: 1.5rem; - padding-bottom: 1.5rem; - } - - .group:hover .sm\:group-hover\:scale-105 { - --tw-scale-x: 1.05; - --tw-scale-y: 1.05; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); - } -} - -@media (min-width: 1024px) { - .lg\:mx-0 { - margin-left: 0px; - margin-right: 0px; - } - - .lg\:block { - display: block; - } - - .lg\:px-8 { - padding-left: 2rem; - padding-right: 2rem; - } -} - -@media (min-width: 1280px) { - .xl\:left-\[50rem\] { - left: 50rem; - } - - .xl\:py-32 { - padding-top: 8rem; - padding-bottom: 8rem; - } - - .xl\:px-28 { - padding-left: 7rem; - padding-right: 7rem; - } -}