diff --git a/Dockerfile b/Dockerfile
index 1527563..0b64512 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -42,7 +42,7 @@ COPY lib lib
RUN mix compile
# copy runtime configuration file
-COPY config/releases.exs config/
+COPY config/runtime.exs config/
COPY rel rel
# assemble release
diff --git a/config/config.exs b/config/config.exs
index 48d9350..fe97dde 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -28,7 +28,9 @@ config :pr, PRWeb.Endpoint,
pubsub_server: PR.PubSub,
live_view: [
signing_salt: "SECRET_SALT"
- ]
+ ],
+ # This is overriden in prod config
+ force_ssl: false
# Configures Elixir's Logger
config :logger, :console,
diff --git a/config/dev.exs b/config/dev.exs
index 42b4759..0e74605 100644
--- a/config/dev.exs
+++ b/config/dev.exs
@@ -1,7 +1,9 @@
import Config
config :pr,
- playlist_name: "PlayRequest"
+ playlist_name: "PlayRequest",
+ session_same_site: "Lax",
+ session_secure: false
# Configure your database
config :pr, PR.Repo,
@@ -28,7 +30,7 @@ config :oauth2, debug: true
# watchers to your application. For example, we use it
# with webpack to recompile .js and .css sources.
config :pr, PRWeb.Endpoint,
- http: [port: System.get_env("PORT")],
+ http: [port: System.get_env("PORT") || 4000, ip: {0, 0, 0, 0}],
debug_errors: true,
code_reloader: true,
check_origin: false,
@@ -78,8 +80,8 @@ config :pr, PRWeb.Endpoint,
]
# Do not include metadata nor timestamps in development logs
-# config :logger, :console, format: "[$level] $message\n"
-config :logger, level: :info
+config :logger, :console, format: "[$level] $message\n", level: :debug
+# config :logger, level: :info
# Initialize plugs at runtime for faster development compilation
config :phoenix, :plug_init_mode, :runtime
@@ -90,43 +92,4 @@ config :phoenix, :stacktrace_depth, 20
config :phoenix_live_view, :debug_heex_annotations, true
-config :pr, :sonos,
- scopes: "playback-control-all",
- redirect_uri: "#{System.get_env("REDIRECT_URL_BASE")}/sonos/authorized",
- key: System.get_env("SONOS_KEY"),
- secret: System.get_env("SONOS_SECRET")
-
-config :pr, :spotify,
- scopes:
- ~w(user-modify-playback-state user-read-currently-playing user-read-playback-state playlist-modify-private playlist-read-private),
- redirect_uri: "#{System.get_env("REDIRECT_URL_BASE")}/spotify/authorized",
- user_id: System.get_env("SPOTIFY_USER_ID"),
- key: System.get_env("SPOTIFY_CLIENT_ID"),
- secret: System.get_env("SPOTIFY_SECRET")
-
-config :ueberauth, Ueberauth.Strategy.Google.OAuth,
- client_id: System.get_env("GOOGLE_CLIENT_ID"),
- client_secret: System.get_env("GOOGLE_CLIENT_SECRET")
-
-config :pr,
- allowed_user_domains: System.get_env("ALLOWED_USER_DOMAINS"),
- installation_name: System.get_env("INSTALLATION_NAME", "PlayRequest"),
- super_likes_allowed: System.get_env("SUPER_LIKES_ALLOWED", "2"),
- burns_allowed: System.get_env("BURNS_ALLOWED", "2")
-
-config :pr, :feature_flags,
- show_volume: System.get_env("FF_VOLUME", ""),
- show_toggle_playback: System.get_env("FF_TOGGLE_PLAYBACK", ""),
- show_skip: System.get_env("FF_SKIP", ""),
- scale_play_button: System.get_env("FF_SCALE_PLAY_BUTTON", ""),
- show_super_like: System.get_env("FF_SUPER_LIKE", ""),
- show_burn: System.get_env("FF_BURN", "")
-
-config :sentry,
- dsn: System.get_env("SENTRY_DSN"),
- environment_name: :dev,
- enable_source_code_context: true,
- root_source_code_path: File.cwd!(),
- tags: %{
- env: "dev"
- }
+# Runtime configuration for development environment has been moved to config/runtime.exs
diff --git a/config/prod.exs b/config/prod.exs
index a71487a..dfe3f71 100644
--- a/config/prod.exs
+++ b/config/prod.exs
@@ -1,20 +1,26 @@
import Config
-config :logger,
- backends: [LoggerJSON],
- level: :info
+config :pr,
+ session_same_site: "None",
+ session_secure: true
+
+# For production, don't forget to configure the url host
+# to something meaningful, Phoenix uses this information
+# when generating URLs.
-config :pr, PR.Repo, ssl: false, socket_options: [:inet6]
+# Runtime configuration (such as database credentials) should be
+# placed in config/runtime.exs which is loaded at runtime.
+# 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 :pr, PRWeb.Endpoint,
- force_ssl: [rewrite_on: [:x_forwarded_proto]],
- server: true,
- root: ".",
- version: Application.spec(:pr, :vsn)
+ cache_static_manifest: "priv/static/cache_manifest.json",
+ force_ssl: [rewrite_on: [:x_forwarded_proto]]
-config :pr,
- sleep: 60_000
+# Do not print debug messages in production
+config :logger, level: :info
-config :sentry,
- enable_source_code_context: true,
- root_source_code_path: File.cwd!()
+# Runtime configuration moved to config/runtime.exs
diff --git a/config/releases.exs b/config/releases.exs
deleted file mode 100644
index f449834..0000000
--- a/config/releases.exs
+++ /dev/null
@@ -1,71 +0,0 @@
-import Config
-
-config :pr, PR.Repo,
- url: System.get_env("DATABASE_URL"),
- pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10")
-
-config :pr, PRWeb.Endpoint,
- http: [port: System.get_env("PORT")],
- url: [host: System.get_env("HOSTNAME"), port: 443, scheme: "https"],
- cache_static_manifest: "priv/static/cache_manifest.json"
-
-config :logger, :console,
- format: "$time $metadata[$level] $message\n",
- metadata: [:request_id, :playback_state, :error_mode]
-
-config :pr, :sonos,
- scopes: "playback-control-all",
- redirect_uri: "#{System.get_env("REDIRECT_URL_BASE")}/sonos/authorized",
- key: System.get_env("SONOS_KEY"),
- secret: System.get_env("SONOS_SECRET")
-
-config :pr, :spotify,
- scopes:
- ~w(user-modify-playback-state user-read-currently-playing user-read-playback-state playlist-modify-private playlist-read-private),
- redirect_uri: "#{System.get_env("REDIRECT_URL_BASE")}/spotify/authorized",
- user_id: System.get_env("SPOTIFY_USER_ID"),
- key: System.get_env("SPOTIFY_CLIENT_ID"),
- secret: System.get_env("SPOTIFY_SECRET")
-
-config :ueberauth, Ueberauth.Strategy.Google.OAuth,
- client_id: System.get_env("GOOGLE_CLIENT_ID"),
- client_secret: System.get_env("GOOGLE_CLIENT_SECRET")
-
-config :pr,
- allowed_user_domains: System.get_env("ALLOWED_USER_DOMAINS", ""),
- installation_name: System.get_env("INSTALLATION_NAME", "PlayRequest"),
- super_likes_allowed: System.get_env("SUPER_LIKES_ALLOWED", "2"),
- burns_allowed: System.get_env("BURNS_ALLOWED", "2")
-
-config :pr, :feature_flags,
- show_volume: System.get_env("FF_VOLUME", ""),
- show_toggle_playback: System.get_env("FF_TOGGLE_PLAYBACK", ""),
- show_skip: System.get_env("FF_SKIP", ""),
- scale_play_button: System.get_env("FF_SCALE_PLAY_BUTTON", ""),
- show_super_like: System.get_env("FF_SUPER_LIKE", ""),
- show_burn: System.get_env("FF_BURN", "")
-
-app_name =
- System.get_env("FLY_APP_NAME") ||
- raise "FLY_APP_NAME not available"
-
-config :libcluster,
- debug: true,
- topologies: [
- fly6pn: [
- strategy: Cluster.Strategy.DNSPoll,
- config: [
- polling_interval: 5_000,
- query: "#{app_name}.internal",
- node_basename: app_name
- ]
- ]
- ]
-
-config :sentry,
- dsn: System.get_env("SENTRY_DSN"),
- tags: %{
- env: System.get_env("RELEASE_STAGE") || "dev"
- },
- environment_name: System.get_env("RELEASE_STAGE") || :prod,
- release: System.get_env("APP_REVISION", "dev")
diff --git a/config/runtime.exs b/config/runtime.exs
new file mode 100644
index 0000000..3fc307e
--- /dev/null
+++ b/config/runtime.exs
@@ -0,0 +1,120 @@
+import Config
+
+# config/runtime.exs is executed for all environments, including
+# during releases. It is executed after compilation and before the
+# system starts, so it is typically used to load production configuration
+# and secrets from environment variables or elsewhere. Do not define
+# any compile-time configuration in here, as it won't be applied.
+
+# ## Using releases
+#
+# If you use `mix release`, you need to explicitly enable the server
+# by passing the PHX_SERVER=true when you start it:
+#
+# PHX_SERVER=true bin/pr start
+#
+# Alternatively, you can use `mix phx.gen.release` to generate a `bin/server`
+# script that automatically sets the env var above.
+if System.get_env("PHX_SERVER") do
+ config :pr, PRWeb.Endpoint, server: true
+end
+
+# Common runtime configuration for all environments
+config :pr, :sonos,
+ scopes: "playback-control-all",
+ redirect_uri: "#{System.get_env("REDIRECT_URL_BASE")}/sonos/authorized",
+ key: System.get_env("SONOS_KEY"),
+ secret: System.get_env("SONOS_SECRET")
+
+config :pr, :spotify,
+ scopes:
+ ~w(user-modify-playback-state user-read-currently-playing user-read-playback-state playlist-modify-private playlist-read-private),
+ redirect_uri: "#{System.get_env("REDIRECT_URL_BASE")}/spotify/authorized",
+ key: System.get_env("SPOTIFY_CLIENT_ID"),
+ secret: System.get_env("SPOTIFY_SECRET")
+
+config :ueberauth, Ueberauth.Strategy.Google.OAuth,
+ client_id: System.get_env("GOOGLE_CLIENT_ID"),
+ client_secret: System.get_env("GOOGLE_CLIENT_SECRET")
+
+config :pr,
+ allowed_user_domains: System.get_env("ALLOWED_USER_DOMAINS", ""),
+ installation_name: System.get_env("INSTALLATION_NAME", "PlayRequest"),
+ super_likes_allowed: System.get_env("SUPER_LIKES_ALLOWED", "2"),
+ burns_allowed: System.get_env("BURNS_ALLOWED", "2")
+
+config :pr, :feature_flags,
+ show_volume: System.get_env("FF_VOLUME", ""),
+ show_toggle_playback: System.get_env("FF_TOGGLE_PLAYBACK", ""),
+ show_skip: System.get_env("FF_SKIP", ""),
+ scale_play_button: System.get_env("FF_SCALE_PLAY_BUTTON", ""),
+ show_super_like: System.get_env("FF_SUPER_LIKE", ""),
+ show_burn: System.get_env("FF_BURN", "")
+
+config :sentry,
+ dsn: System.get_env("SENTRY_DSN"),
+ enable_source_code_context: true,
+ root_source_code_path: File.cwd!()
+
+# Production-specific configuration
+if config_env() == :prod do
+ config :logger,
+ backends: [LoggerJSON],
+ level: :info
+
+ config :pr, PR.Repo,
+ url: System.get_env("DATABASE_URL") || raise("DATABASE_URL not available"),
+ pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
+ ssl: false,
+ socket_options: [:inet6]
+
+ config :pr, PRWeb.Endpoint,
+ http: [port: String.to_integer(System.get_env("PORT") || "4000")],
+ url: [host: System.get_env("HOSTNAME"), port: 443, scheme: "https"],
+ cache_static_manifest: "priv/static/cache_manifest.json",
+ server: true
+
+ # Production requires these environment variables
+ unless System.get_env("SONOS_KEY"), do: raise("SONOS_KEY not available")
+ unless System.get_env("SONOS_SECRET"), do: raise("SONOS_SECRET not available")
+ unless System.get_env("SPOTIFY_CLIENT_ID"), do: raise("SPOTIFY_CLIENT_ID not available")
+ unless System.get_env("SPOTIFY_SECRET"), do: raise("SPOTIFY_SECRET not available")
+ unless System.get_env("GOOGLE_CLIENT_ID"), do: raise("GOOGLE_CLIENT_ID not available")
+ unless System.get_env("GOOGLE_CLIENT_SECRET"), do: raise("GOOGLE_CLIENT_SECRET not available")
+
+ config :pr,
+ sleep: 60_000
+
+ app_name =
+ System.get_env("FLY_APP_NAME") ||
+ raise "FLY_APP_NAME not available"
+
+ config :libcluster,
+ debug: true,
+ topologies: [
+ fly6pn: [
+ strategy: Cluster.Strategy.DNSPoll,
+ config: [
+ polling_interval: 5_000,
+ query: "#{app_name}.internal",
+ node_basename: app_name
+ ]
+ ]
+ ]
+
+ config :sentry,
+ tags: %{
+ env: System.get_env("RELEASE_STAGE") || "dev"
+ },
+ environment_name: System.get_env("RELEASE_STAGE") || :prod,
+ release: System.get_env("APP_REVISION", "dev")
+end
+
+# Development-specific configuration
+if config_env() == :dev do
+ config :sentry,
+ environment_name: :dev,
+ tags: %{
+ env: "dev"
+ }
+end
diff --git a/justfile b/justfile
index cbe76f7..7d733dc 100644
--- a/justfile
+++ b/justfile
@@ -62,4 +62,4 @@ remote_production:
fly ssh console -C "/home/elixir/app/bin/{{binname}} remote" --app {{appname}}
tunnel:
- ssh -p 443 -R0:localhost:4000 ${PINGY_TOKEN}@a.pinggy.online
+ cloudflared tunnel run --token ${CLOUDFLARE_TOKEN}
diff --git a/lib/pr/apis/sonos_api.ex b/lib/pr/apis/sonos_api.ex
index 475d281..2e955c5 100644
--- a/lib/pr/apis/sonos_api.ex
+++ b/lib/pr/apis/sonos_api.ex
@@ -186,10 +186,17 @@ defmodule PR.SonosAPI do
%Household{household_id: household_id, id: id} ->
%{playerIds: player_ids}
|> post("/households/#{household_id}/groups/createGroup")
- |> Map.get(:group)
- |> fields_for_group(id)
- |> Map.put(:is_active, true)
- |> SonosHouseholds.insert_or_update_group()
+ |> case do
+ %{group: group} ->
+ group
+ |> fields_for_group(id)
+ |> Map.put(:is_active, true)
+ |> SonosHouseholds.insert_or_update_group()
+
+ {:error, error} ->
+ Logger.error(error)
+ {:error, :cant_create_group}
+ end
_ ->
{:error, :no_household_activated}
diff --git a/lib/pr/music/music.ex b/lib/pr/music/music.ex
index c8a91ed..af99a26 100644
--- a/lib/pr/music/music.ex
+++ b/lib/pr/music/music.ex
@@ -119,10 +119,13 @@ defmodule PR.Music do
def check_current_playstate(%PlaybackState{state: state}, _mode),
do: {:error, :playstate, state}
+ def check_current_playstate(%{}, _mode),
+ do: {:error, :playstate, nil}
+
def check_unplayed() do
# Check if there's something in the queue
# If might still be marked as playing if its a skip
- # but that's probably ok as this check is only really
+ # but that's probably ok as this check is only really
# of interest for knowing what to do when skip is pressed
cond do
Queue.num_unplayed() == 0 ->
diff --git a/lib/pr_web.ex b/lib/pr_web.ex
index 10f3ce6..10e77c7 100644
--- a/lib/pr_web.ex
+++ b/lib/pr_web.ex
@@ -51,7 +51,7 @@ defmodule PRWeb do
def plug do
quote do
import Plug.Conn
- use Phoenix.Controller, namespace: PRWeb
+ import Phoenix.Controller, only: [redirect: 2]
unquote(verified_routes())
end
end
diff --git a/lib/pr_web/components/layouts/auth.html.heex b/lib/pr_web/components/layouts/auth.html.heex
new file mode 100644
index 0000000..72e14d4
--- /dev/null
+++ b/lib/pr_web/components/layouts/auth.html.heex
@@ -0,0 +1,10 @@
+
+
+
+ <.flash class="alert alert-info" kind={:info} title="Success!" flash={@flash} />
+ <.flash class="alert alert-danger" kind={:error} title="Error!" flash={@flash} />
+
+ <%= @inner_content %>
+
diff --git a/lib/pr_web/controllers/auth_controller.ex b/lib/pr_web/controllers/auth_controller.ex
index 99892fc..d402792 100644
--- a/lib/pr_web/controllers/auth_controller.ex
+++ b/lib/pr_web/controllers/auth_controller.ex
@@ -1,6 +1,7 @@
defmodule PRWeb.AuthController do
use PRWeb, :controller
plug(Ueberauth)
+ plug(:put_layout, html: {PRWeb.Layouts, :auth})
alias PR.Auth
diff --git a/lib/pr_web/endpoint.ex b/lib/pr_web/endpoint.ex
index 9955a85..42e6e22 100644
--- a/lib/pr_web/endpoint.ex
+++ b/lib/pr_web/endpoint.ex
@@ -6,7 +6,9 @@ defmodule PRWeb.Endpoint do
store: :cookie,
key: "_pr_web_key",
signing_salt: "ZG+jiBR2",
- same_site: "None"
+ # Different same site polic for local where there is no HTTPS
+ same_site: Application.compile_env(:pr, :session_same_site, "Lax"),
+ secure: Application.compile_env(:pr, :session_secure, false)
]
socket("/live", Phoenix.LiveView.Socket,
diff --git a/lib/pr_web/live/auth_hooks.ex b/lib/pr_web/live/auth_hooks.ex
new file mode 100644
index 0000000..1cdc2ae
--- /dev/null
+++ b/lib/pr_web/live/auth_hooks.ex
@@ -0,0 +1,45 @@
+defmodule PRWeb.AuthHooks do
+ @moduledoc """
+ LiveView authentication hooks for handling user sessions.
+ """
+ use PRWeb, :verified_routes
+
+ import Phoenix.Component
+ import Phoenix.LiveView
+
+ alias PR.Auth
+
+ def on_mount(:require_authenticated_user, _params, %{"user_id" => user_id} = session, socket) do
+ require Logger
+ Logger.debug("AuthHook: Found user_id in session: #{inspect(user_id)}")
+ Logger.debug("AuthHook: Full session: #{inspect(session)}")
+
+ case Auth.get_user(user_id) do
+ nil ->
+ Logger.debug("AuthHook: User not found in database for user_id: #{inspect(user_id)}")
+
+ socket =
+ socket
+ |> put_flash(:error, "You must log in to access this page.")
+ |> redirect(to: ~p"/auth")
+
+ {:halt, socket}
+
+ user ->
+ Logger.debug("AuthHook: User authenticated: #{inspect(user.id)}")
+ {:cont, assign(socket, current_user: user)}
+ end
+ end
+
+ def on_mount(:require_authenticated_user, _params, session, socket) do
+ require Logger
+ Logger.debug("AuthHook: No user_id in session. Session: #{inspect(session)}")
+
+ socket =
+ socket
+ |> put_flash(:error, "You must log in to access this page.")
+ |> redirect(to: ~p"/auth")
+
+ {:halt, socket}
+ end
+end
diff --git a/lib/pr_web/live/playback_live/playback_live.ex b/lib/pr_web/live/playback_live/playback_live.ex
index ae7d08c..db0dcbe 100644
--- a/lib/pr_web/live/playback_live/playback_live.ex
+++ b/lib/pr_web/live/playback_live/playback_live.ex
@@ -20,7 +20,8 @@ defmodule PRWeb.PlaybackLive do
embed_templates "*"
@impl true
- def mount(_params, %{"user_id" => user_id}, socket) do
+ def mount(_params, _session, socket) do
+ user_id = socket.assigns.current_user.id
if connected?(socket), do: PlayState.subscribe()
if connected?(socket), do: Music.subscribe()
play_state = PlayState.get(:play_state)
@@ -46,7 +47,7 @@ defmodule PRWeb.PlaybackLive do
)
|> assign(feature_flags())
- {:ok, assign_new(socket, :current_user, fn -> Auth.get_user!(user_id) end)}
+ {:ok, socket}
end
defp show_encouraging_message(user) do
diff --git a/lib/pr_web/plugs/auth_plug.ex b/lib/pr_web/plugs/auth_plug.ex
index f02ce7f..5c6cad8 100644
--- a/lib/pr_web/plugs/auth_plug.ex
+++ b/lib/pr_web/plugs/auth_plug.ex
@@ -4,27 +4,37 @@ defmodule PRWeb.Plug.AuthPlug do
use PRWeb, :plug
alias PR.Auth.User
alias PR.Auth
+ require Logger
def init(opts), do: opts
def call(conn, _) do
- conn
- |> get_session(:user_id)
+ user_id = get_session(conn, :user_id)
+ Logger.debug("AuthPlug: user_id from session: #{inspect(user_id)}")
+ Logger.debug("AuthPlug: path: #{conn.request_path}")
+
+ user_id
|> get_user(conn)
end
defp get_user(nil, conn) do
+ Logger.debug("AuthPlug: No user_id in session, redirecting to /auth")
nope(conn)
end
defp get_user(user_id, conn) do
+ Logger.debug("AuthPlug: Looking up user_id: #{inspect(user_id)}")
+
case Auth.get_user(user_id) do
%User{} = user ->
+ Logger.debug("AuthPlug: User found: #{inspect(user.id)}")
+
conn
|> put_session(:user_id, user_id)
|> assign(:current_user, user)
_ ->
+ Logger.debug("AuthPlug: User not found in database for user_id: #{inspect(user_id)}")
nope(conn)
end
end
diff --git a/lib/pr_web/router.ex b/lib/pr_web/router.ex
index a593f2b..3562b59 100644
--- a/lib/pr_web/router.ex
+++ b/lib/pr_web/router.ex
@@ -29,10 +29,22 @@ defmodule PRWeb.Router do
end
scope "/", PRWeb do
- pipe_through([:browser, :auth, :now_playing])
- live("/", PlaybackLive)
- get("/history", HistoryController, :index)
- post("/history/track-unplayed/:id", HistoryController, :mark_unplayed)
+ # Not using auth pipeline here cos AuthHooks is doing the same thing
+ # for live views. apparently
+ pipe_through([:browser, :now_playing])
+
+ live_session :authenticated,
+ on_mount: [{PRWeb.AuthHooks, :require_authenticated_user}] do
+ live("/", PlaybackLive)
+ end
+ end
+
+ scope "/history", PRWeb do
+ # Authenticated routes for history, using controlers so AuthPlug
+ pipe_through([:browser, :auth])
+
+ get("/", HistoryController, :index)
+ post("/track-unplayed/:id", HistoryController, :mark_unplayed)
end
scope "/auth", PRWeb do
@@ -43,24 +55,27 @@ defmodule PRWeb.Router do
get("/:provider/callback", AuthController, :callback)
end
- scope "/", PRWeb.Service do
+ scope "/setup", PRWeb.Service do
+ # Authenticated controller routes for doing setup stuff
pipe_through([:browser, :auth])
- scope "/setup" do
- get("/", ServiceSetupController, :index)
- post("/save-households", ServiceSetupController, :save_households)
- post("/save-groups", ServiceSetupController, :save_groups)
- delete("/clear-groups", ServiceSetupController, :clear_groups)
- put("/household/:id", ServiceSetupController, :toggle_household)
- put("/group/:id", ServiceSetupController, :toggle_group)
- post("/subscribe", ServiceSetupController, :subscribe_sonos_webhooks)
- post("/sync-playlist", ServiceSetupController, :sync_playlist)
- post("/trigger-playlist", ServiceSetupController, :trigger_playlist)
- post("/create-playlist", ServiceSetupController, :create_spotify_playlist)
- post("/bump", ServiceSetupController, :bump)
- post("/get-state", ServiceSetupController, :get_state)
- end
+ get("/", ServiceSetupController, :index)
+ post("/save-households", ServiceSetupController, :save_households)
+ post("/save-groups", ServiceSetupController, :save_groups)
+ delete("/clear-groups", ServiceSetupController, :clear_groups)
+ put("/household/:id", ServiceSetupController, :toggle_household)
+ put("/group/:id", ServiceSetupController, :toggle_group)
+ post("/subscribe", ServiceSetupController, :subscribe_sonos_webhooks)
+ post("/sync-playlist", ServiceSetupController, :sync_playlist)
+ post("/trigger-playlist", ServiceSetupController, :trigger_playlist)
+ post("/create-playlist", ServiceSetupController, :create_spotify_playlist)
+ post("/bump", ServiceSetupController, :bump)
+ post("/get-state", ServiceSetupController, :get_state)
+ end
+ scope "/", PRWeb.Service do
+ # Plublic controller routes for authenticating services
+ pipe_through([:browser])
get("/sonos/authorized", ServiceAuthController, :authorized_sonos, as: :sonos_auth)
get("/spotify/authorized", ServiceAuthController, :authorized_spotify, as: :spotify_auth)
end
diff --git a/mix.exs b/mix.exs
index 26c1443..df57e24 100644
--- a/mix.exs
+++ b/mix.exs
@@ -10,7 +10,8 @@ defmodule PR.MixProject do
start_permanent: Mix.env() == :prod,
aliases: aliases(),
deps: deps(),
- releases: releases()
+ releases: releases(),
+ listeners: [Phoenix.CodeReloader]
]
end
@@ -38,8 +39,8 @@ defmodule PR.MixProject do
{:certifi, "~> 2.2"},
{:telemetry_poller, "~> 0.4"},
{:telemetry_metrics, "~> 0.4"},
- {:phoenix, "~> 1.7.0"},
- {:phoenix_live_view, "~> 0.20.0"},
+ {:phoenix, "~> 1.8.0"},
+ {:phoenix_live_view, "~> 1.0"},
{:phoenix_ecto, "~> 4.1"},
{:phoenix_html, "~> 3.0"},
{:phoenix_live_reload, "~> 1.2", only: :dev},
diff --git a/mix.lock b/mix.lock
index b6c9dda..1ee106b 100644
--- a/mix.lock
+++ b/mix.lock
@@ -1,7 +1,7 @@
%{
"bertex": {:hex, :bertex, "1.3.0", "0ad0df9159b5110d9d2b6654f72fbf42a54884ef43b6b651e6224c0af30ba3cb", [:mix], [], "hexpm", "0a5d5e478bb5764b7b7bae37cae1ca491200e58b089df121a2fe1c223d8ee57a"},
"calendar": {:hex, :calendar, "0.17.6", "ec291cb2e4ba499c2e8c0ef5f4ace974e2f9d02ae9e807e711a9b0c7850b9aee", [:mix], [{:tzdata, "~> 0.5.20 or ~> 0.1.201603 or ~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"},
- "castore": {:hex, :castore, "1.0.3", "7130ba6d24c8424014194676d608cb989f62ef8039efd50ff4b3f33286d06db8", [:mix], [], "hexpm", "680ab01ef5d15b161ed6a95449fac5c6b8f60055677a8e79acf01b27baa4390b"},
+ "castore": {:hex, :castore, "1.0.16", "8a4f9a7c8b81cda88231a08fe69e3254f16833053b23fa63274b05cbc61d2a1e", [:mix], [], "hexpm", "33689203a0eaaf02fcd0e86eadfbcf1bd636100455350592e7e2628564022aaf"},
"certifi": {:hex, :certifi, "2.15.0", "0e6e882fcdaaa0a5a9f2b3db55b1394dba07e8d6d9bcad08318fb604c6839712", [:rebar3], [], "hexpm", "b147ed22ce71d72eafdad94f055165c1c182f61a2ff49df28bcc71d1d5b94a60"},
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
"connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
@@ -46,17 +46,17 @@
"oauth2": {:hex, :oauth2, "2.0.0", "338382079fe16c514420fa218b0903f8ad2d4bfc0ad0c9f988867dfa246731b0", [:mix], [{:hackney, "~> 1.13", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "881b8364ac7385f9fddc7949379cbe3f7081da37233a1aa7aab844670a91e7e7"},
"opq": {:hex, :opq, "4.0.1", "fa6e0c11e8eb4a6b0779c01b4c8e8af455bc40b2a06c52f54d3a4ba5bc1751cd", [:mix], [{:gen_stage, "~> 1.1", [hex: :gen_stage, repo: "hexpm", optional: false]}], "hexpm", "a6314afd345ba24f7c2df431d7eb7420926a5410fe6cd083432909adee00eaba"},
"parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"},
- "phoenix": {:hex, :phoenix, "1.7.7", "4cc501d4d823015007ba3cdd9c41ecaaf2ffb619d6fb283199fa8ddba89191e0", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, 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]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "8966e15c395e5e37591b6ed0bd2ae7f48e961f0f60ac4c733f9566b519453085"},
+ "phoenix": {:hex, :phoenix, "1.8.1", "865473a60a979551a4879db79fbfb4503e41cd809e77c85af79716578b6a456d", [:mix], [{:bandit, "~> 1.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, 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]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "84d77d2b2e77c3c7e7527099bd01ef5c8560cd149c036d6b3a40745f11cd2fb2"},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.3.0", "2c69a452c2e0ee8c93345ae1cdc1696ef4877ff9cbb15c305def41960c3c4ebf", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "0ac491924217550c8f42c81c1f390b5d81517d12ceaf9abf3e701156760a848e"},
- "phoenix_html": {:hex, :phoenix_html, "3.3.2", "d6ce982c6d8247d2fc0defe625255c721fb8d5f1942c5ac051f6177bffa5973f", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "44adaf8e667c1c20fb9d284b6b0fa8dc7946ce29e81ce621860aa7e96de9a11d"},
+ "phoenix_html": {:hex, :phoenix_html, "3.3.4", "42a09fc443bbc1da37e372a5c8e6755d046f22b9b11343bf885067357da21cb3", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "0249d3abec3714aff3415e7ee3d9786cb325be3151e6c4b3021502c585bf53fb"},
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.3.3", "3a53772a6118d5679bf50fc1670505a290e32a1d195df9e069d8c53ab040c054", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "766796676e5f558dbae5d1bdb066849673e956005e3730dfd5affd7a6da4abac"},
- "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"},
+ "phoenix_live_view": {:hex, :phoenix_live_view, "1.1.17", "1d782b5901cf13b137c6d8c56542ff6cb618359b2adca7e185b21df728fa0c6c", [:mix], [{:igniter, ">= 0.6.16 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:lazy_html, "~> 0.1.0", [hex: :lazy_html, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0 or ~> 1.8.0-rc", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [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]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fa82307dd9305657a8236d6b48e60ef2e8d9f742ee7ed832de4b8bcb7e0e5ed2"},
+ "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.2.0", "ff3a5616e1bed6804de7773b92cbccfc0b0f473faf1f63d7daf1206c7aeaaa6f", [:mix], [], "hexpm", "adc313a5bf7136039f63cfd9668fde73bba0765e0614cba80c06ac9460ff3e96"},
+ "phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"},
"phoenix_view": {:hex, :phoenix_view, "2.0.2", "6bd4d2fd595ef80d33b439ede6a19326b78f0f1d8d62b9a318e3d9c1af351098", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "a929e7230ea5c7ee0e149ffcf44ce7cf7f4b6d2bfe1752dd7c084cdff152d36f"},
"plug": {:hex, :plug, "1.18.1", "5067f26f7745b7e31bc3368bc1a2b818b9779faa959b49c934c17730efc911cf", [: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", "57a57db70df2b422b564437d2d33cf8d33cd16339c1edb190cd11b1a3a546cc2"},
"plug_cowboy": {:hex, :plug_cowboy, "2.7.4", "729c752d17cf364e2b8da5bdb34fb5804f56251e88bb602aff48ae0bd8673d11", [: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", "9b85632bd7012615bae0a5d70084deb1b25d2bcbb32cab82d1e9a1e023168aa3"},
- "plug_crypto": {:hex, :plug_crypto, "1.2.5", "918772575e48e81e455818229bf719d4ab4181fcbf7f85b68a35620f78d89ced", [:mix], [], "hexpm", "26549a1d6345e2172eb1c233866756ae44a9609bd33ee6f99147ab3fd87fd842"},
+ "plug_crypto": {:hex, :plug_crypto, "2.1.1", "19bda8184399cb24afa10be734f84a16ea0a2bc65054e23a62bb10f06bc89491", [:mix], [], "hexpm", "6470bce6ffe41c8bd497612ffde1a7e4af67f36a15eea5f921af71cf3e11247c"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"},
"postgrex": {:hex, :postgrex, "0.17.3", "c92cda8de2033a7585dae8c61b1d420a1a1322421df84da9a82a6764580c503d", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "946cf46935a4fdca7a81448be76ba3503cff082df42c6ec1ff16a4bdfbfb098d"},
@@ -77,5 +77,5 @@
"ueberauth_google": {:hex, :ueberauth_google, "0.10.1", "db7bd2d99d2ff38e7449042a08d9560741b0dcaf1c31191729b97188b025465e", [:mix], [{:oauth2, "~> 1.0 or ~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.7.0", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "b799f547d279bb836e1f7039fc9fbb3a9d008a695e2a25bd06bffe591a168ba1"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.1", "a48703a25c170eedadca83b11e88985af08d35f37c6f664d6dcfb106a97782fc", [:rebar3], [], "hexpm", "b3a917854ce3ae233619744ad1e0102e05673136776fb2fa76234f3e03b23642"},
"websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"},
- "websock_adapter": {:hex, :websock_adapter, "0.5.4", "7af8408e7ed9d56578539594d1ee7d8461e2dd5c3f57b0f2a5352d610ddde757", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "d2c238c79c52cbe223fcdae22ca0bb5007a735b9e933870e241fce66afb4f4ab"},
+ "websock_adapter": {:hex, :websock_adapter, "0.5.9", "43dc3ba6d89ef5dec5b1d0a39698436a1e856d000d84bf31a3149862b01a287f", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "5534d5c9adad3c18a0f58a9371220d75a803bf0b9a3d87e6fe072faaeed76a08"},
}
diff --git a/priv/static/assets/app.js b/priv/static/assets/app.js
index 54fa906..fc6f3d3 100644
--- a/priv/static/assets/app.js
+++ b/priv/static/assets/app.js
@@ -1,5 +1,7 @@
(() => {
var __defProp = Object.defineProperty;
+ var __defProps = Object.defineProperties;
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
@@ -15,18 +17,7 @@
}
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 __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
// ../deps/phoenix_html/priv/static/phoenix_html.js
"use strict";
@@ -111,14 +102,18 @@
"phx-keydown-loading",
"phx-keyup-loading",
"phx-blur-loading",
- "phx-focus-loading"
+ "phx-focus-loading",
+ "phx-hook-loading"
];
var PHX_COMPONENT = "data-phx-component";
+ var PHX_VIEW_REF = "data-phx-view";
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_LOADING = "data-phx-ref-loading";
var PHX_REF_SRC = "data-phx-ref-src";
+ var PHX_REF_LOCK = "data-phx-ref-lock";
+ var PHX_PENDING_REFS = "phx-pending-refs";
var PHX_TRACK_UPLOADS = "track-uploads";
var PHX_UPLOAD_REF = "data-phx-upload-ref";
var PHX_PREFLIGHTED_REFS = "data-phx-preflighted-refs";
@@ -127,11 +122,10 @@
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_MAGIC_ID = "data-phx-id";
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";
@@ -141,9 +135,22 @@
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 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";
@@ -160,16 +167,25 @@
var PHX_UPDATE = "update";
var PHX_STREAM = "stream";
var PHX_STREAM_REF = "data-phx-stream";
+ var PHX_PORTAL = "data-phx-portal";
+ var PHX_TELEPORTED_REF = "data-phx-teleported";
+ var PHX_TELEPORTED_SRC = "data-phx-teleported-src";
+ var PHX_RUNTIME_HOOK = "data-phx-runtime-hook";
+ var PHX_LV_PID = "data-phx-pid";
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_LV_HISTORY_POSITION = "phx:nav-history-position";
var PHX_PROGRESS = "progress";
var PHX_MOUNTED = "mounted";
+ var PHX_RELOAD_STATUS = "__phoenix_reload_status__";
var LOADER_TIMEOUT = 1;
+ var MAX_CHILD_JOIN_ATTEMPTS = 3;
var BEFORE_UNLOAD_LOADER_TIMEOUT = 200;
+ var DISCONNECTED_TIMEOUT = 500;
var BINDING_PREFIX = "phx-";
var PUSH_TIMEOUT = 3e4;
var DEBOUNCE_TRIGGER = "debounce-trigger";
@@ -179,28 +195,36 @@
debounce: 300,
throttle: 300
};
- var DYNAMICS = "d";
+ var PHX_PENDING_ATTRS = [PHX_REF_LOADING, PHX_REF_SRC, PHX_REF_LOCK];
var STATIC = "s";
+ var ROOT = "r";
var COMPONENTS = "c";
+ var KEYED = "k";
+ var KEYED_COUNT = "kc";
var EVENTS = "e";
var REPLY = "r";
var TITLE = "t";
var TEMPLATES = "p";
var STREAM = "stream";
var EntryUploader = class {
- constructor(entry, chunkSize, liveSocket2) {
+ constructor(entry, config, liveSocket2) {
+ const { chunk_size, chunk_timeout } = config;
this.liveSocket = liveSocket2;
this.entry = entry;
this.offset = 0;
- this.chunkSize = chunkSize;
+ this.chunkSize = chunk_size;
+ this.chunkTimeout = chunk_timeout;
this.chunkTimer = null;
this.errored = false;
- this.uploadChannel = liveSocket2.channel(`lvu:${entry.ref}`, { token: entry.metadata() });
+ this.uploadChannel = liveSocket2.channel(`lvu:${entry.ref}`, {
+ token: entry.metadata()
+ });
}
error(reason) {
if (this.errored) {
return;
}
+ this.uploadChannel.leave();
this.errored = true;
clearTimeout(this.chunkTimer);
this.entry.error(reason);
@@ -213,8 +237,8 @@
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);
+ const reader = new window.FileReader();
+ const 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;
@@ -229,7 +253,7 @@
if (!this.uploadChannel.isJoined()) {
return;
}
- this.uploadChannel.push("chunk", chunk).receive("ok", () => {
+ this.uploadChannel.push("chunk", chunk, this.chunkTimeout).receive("ok", () => {
this.entry.progress(this.offset / this.entry.file.size * 100);
if (!this.isDone()) {
this.chunkTimer = setTimeout(() => this.readNextChunk(), this.liveSocket.getLatencySim() || 0);
@@ -239,12 +263,12 @@
};
var logError = (msg, obj) => console.error && console.error(msg, obj);
var isCid = (cid) => {
- let type = typeof cid;
+ const type = typeof cid;
return type === "number" || type === "string" && /^(0|[1-9]\d*)$/.test(cid);
};
function detectDuplicateIds() {
- let ids = new Set();
- let elems = document.querySelectorAll("*[id]");
+ const ids = /* @__PURE__ */ new Set();
+ const 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.`);
@@ -253,6 +277,16 @@
}
}
}
+ function detectInvalidStreamInserts(inserts) {
+ const errors = /* @__PURE__ */ new Set();
+ Object.keys(inserts).forEach((id) => {
+ const streamEl = document.getElementById(id);
+ if (streamEl && streamEl.parentElement && streamEl.parentElement.getAttribute("phx-update") !== "stream") {
+ errors.add(`The stream container with id "${streamEl.parentElement.id}" is missing the phx-update="stream" attribute. Ensure it is set for streams to work properly.`);
+ }
+ });
+ errors.forEach((error) => console.error(error));
+ }
var debug = (view, kind, msg, obj) => {
if (view.liveSocket.isDebugEnabled()) {
console.log(`${view.id} ${kind}: ${msg} - `, obj);
@@ -278,7 +312,7 @@
};
var isEqualObj = (obj1, obj2) => JSON.stringify(obj1) === JSON.stringify(obj2);
var isEmpty = (obj) => {
- for (let x in obj) {
+ for (const x in obj) {
return false;
}
return true;
@@ -286,7 +320,7 @@
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);
+ const entryUploader = new EntryUploader(entry, resp.config, liveSocket2);
entryUploader.upload();
});
};
@@ -298,9 +332,9 @@
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);
+ const current = this.getLocal(localStorage, namespace, subkey);
+ const key = this.localKey(namespace, subkey);
+ const newVal = current === null ? initial : func(current);
localStorage.setItem(key, JSON.stringify(newVal));
return newVal;
},
@@ -317,40 +351,48 @@
if (this.canPushState()) {
if (to !== window.location.href) {
if (meta.type == "redirect" && meta.scroll) {
- let currentState = history.state || {};
+ const 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);
- }
+ window.requestAnimationFrame(() => {
+ const 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}`;
+ setCookie(name, value, maxAgeSeconds) {
+ const expires = typeof maxAgeSeconds === "number" ? ` max-age=${maxAgeSeconds};` : "";
+ document.cookie = `${name}=${value};${expires} path=/`;
},
getCookie(name) {
return document.cookie.replace(new RegExp(`(?:(?:^|.*;s*)${name}s*=s*([^;]*).*$)|^.*$`), "$1");
},
- redirect(toURL, flash) {
+ deleteCookie(name) {
+ document.cookie = `${name}=; max-age=-1; path=/`;
+ },
+ redirect(toURL, flash, navigate = (url) => {
+ window.location.href = url;
+ }) {
if (flash) {
- Browser.setCookie("__phoenix_flash__", flash + "; max-age=60000; path=/");
+ this.setCookie("__phoenix_flash__", flash, 60);
}
- window.location = toURL;
+ navigate(toURL);
},
localKey(namespace, subkey) {
return `${namespace}-${subkey}`;
},
getHashTargetEl(maybeHash) {
- let hash = maybeHash.toString().substring(1);
+ const hash = maybeHash.toString().substring(1);
if (hash === "") {
return;
}
@@ -372,11 +414,14 @@
if (!node) {
return [];
}
- let array = Array.from(node.querySelectorAll(query));
- return callback ? array.forEach(callback) : array;
+ const array = Array.from(node.querySelectorAll(query));
+ if (callback) {
+ array.forEach(callback);
+ }
+ return array;
},
childNodeLength(html) {
- let template = document.createElement("template");
+ const template = document.createElement("template");
template.innerHTML = html;
return template.content.childElementCount;
},
@@ -387,22 +432,25 @@
return inputEl.hasAttribute("data-phx-auto-upload");
},
findUploadInputs(node) {
- return this.all(node, `input[type="file"][${PHX_UPLOAD_REF}]`);
+ const formId = node.id;
+ const inputsOutsideForm = this.all(document, `input[type="file"][${PHX_UPLOAD_REF}][form="${formId}"]`);
+ return this.all(node, `input[type="file"][${PHX_UPLOAD_REF}]`).concat(inputsOutsideForm);
},
- findComponentNodeList(node, cid) {
- return this.filterWithinSameLiveView(this.all(node, `[${PHX_COMPONENT}="${cid}"]`), node);
+ findComponentNodeList(viewId, cid, doc2 = document) {
+ return this.all(doc2, `[${PHX_VIEW_REF}="${viewId}"][${PHX_COMPONENT}="${cid}"]`);
},
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;
+ const wantsNewTab = e.ctrlKey || e.shiftKey || e.metaKey || e.button && e.button === 1;
+ const isDownload = e.target instanceof HTMLAnchorElement && e.target.hasAttribute("download");
+ const isTargetBlank = e.target.hasAttribute("target") && e.target.getAttribute("target").toLowerCase() === "_blank";
+ const isTargetNamedTab = e.target.hasAttribute("target") && !e.target.getAttribute("target").startsWith("_");
+ return wantsNewTab || isTargetBlank || isDownload || isTargetNamedTab;
},
isUnloadableFormSubmit(e) {
- let isDialogSubmit = e.target && e.target.getAttribute("method") === "dialog" || e.submitter && e.submitter.getAttribute("formmethod") === "dialog";
+ const isDialogSubmit = e.target && e.target.getAttribute("method") === "dialog" || e.submitter && e.submitter.getAttribute("formmethod") === "dialog";
if (isDialogSubmit) {
return false;
} else {
@@ -410,7 +458,7 @@
}
},
isNewPageClick(e, currentLocation) {
- let href = e.target instanceof HTMLAnchorElement ? e.target.getAttribute("href") : null;
+ const href = e.target instanceof HTMLAnchorElement ? e.target.getAttribute("href") : null;
let url;
if (e.defaultPrevented || href === null || this.wantsNewTab(e)) {
return false;
@@ -444,7 +492,7 @@
this.putPrivate(el, "destroyed", true);
},
findPhxChildrenInFragment(html, parentId) {
- let template = document.createElement("template");
+ const template = document.createElement("template");
template.innerHTML = html;
return this.findPhxChildren(template.content, parentId);
},
@@ -460,31 +508,17 @@
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;
- }
- }
+ findExistingParentCIDs(viewId, cids) {
+ const parentCids = /* @__PURE__ */ new Set();
+ const childrenCids = /* @__PURE__ */ new Set();
+ cids.forEach((cid) => {
+ this.all(document, `[${PHX_VIEW_REF}="${viewId}"][${PHX_COMPONENT}="${cid}"]`).forEach((parent) => {
+ parentCids.add(cid);
+ this.all(parent, `[${PHX_VIEW_REF}="${viewId}"][${PHX_COMPONENT}]`).map((el) => parseInt(el.getAttribute(PHX_COMPONENT))).forEach((childCID) => childrenCids.add(childCID));
+ });
+ });
+ childrenCids.forEach((childCid) => parentCids.delete(childCid));
+ return parentCids;
},
private(el, key) {
return el[PHX_PRIVATE] && el[PHX_PRIVATE][key];
@@ -499,23 +533,39 @@
el[PHX_PRIVATE][key] = value;
},
updatePrivate(el, key, defaultVal, updateFunc) {
- let existing = this.private(el, key);
+ const existing = this.private(el, key);
if (existing === void 0) {
this.putPrivate(el, key, updateFunc(defaultVal));
} else {
this.putPrivate(el, key, updateFunc(existing));
}
},
+ syncPendingAttrs(fromEl, toEl) {
+ if (!fromEl.hasAttribute(PHX_REF_SRC)) {
+ return;
+ }
+ PHX_EVENT_CLASSES.forEach((className) => {
+ fromEl.classList.contains(className) && toEl.classList.add(className);
+ });
+ PHX_PENDING_ATTRS.filter((attr) => fromEl.hasAttribute(attr)).forEach((attr) => {
+ toEl.setAttribute(attr, fromEl.getAttribute(attr));
+ });
+ },
copyPrivates(target, source) {
if (source[PHX_PRIVATE]) {
target[PHX_PRIVATE] = source[PHX_PRIVATE];
}
},
putTitle(str) {
- let titleEl = document.querySelector("title");
+ const titleEl = document.querySelector("title");
if (titleEl) {
- let { prefix, suffix } = titleEl.dataset;
- document.title = `${prefix || ""}${str}${suffix || ""}`;
+ const { prefix, suffix, default: defaultTitle } = titleEl.dataset;
+ const isEmpty2 = typeof str !== "string" || str.trim() === "";
+ if (isEmpty2 && typeof defaultTitle !== "string") {
+ return;
+ }
+ const inner = isEmpty2 ? defaultTitle : str;
+ document.title = `${prefix || ""}${inner || ""}${suffix || ""}`;
} else {
document.title = str;
}
@@ -529,26 +579,31 @@
if (throttle === "") {
throttle = defaultThrottle;
}
- let value = debounce || throttle;
+ const value = debounce || throttle;
switch (value) {
case null:
return callback();
case "blur":
+ this.incCycle(el, "debounce-blur-cycle", () => {
+ if (asyncFilter()) {
+ callback();
+ }
+ });
if (this.once(el, "debounce-blur")) {
- el.addEventListener("blur", () => callback());
+ el.addEventListener("blur", () => this.triggerCycle(el, "debounce-blur-cycle"));
}
return;
default:
- let timeout = parseInt(value);
- let trigger = () => throttle ? this.deletePrivate(el, THROTTLED) : callback();
- let currentCycle = this.incCycle(el, DEBOUNCE_TRIGGER, trigger);
+ const timeout = parseInt(value);
+ const trigger = () => throttle ? this.deletePrivate(el, THROTTLED) : callback();
+ const 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);
+ const prevKey = this.private(el, DEBOUNCE_PREV_KEY);
this.putPrivate(el, DEBOUNCE_PREV_KEY, event.key);
newKeyDown = prevKey !== event.key;
}
@@ -556,12 +611,12 @@
return false;
} else {
callback();
- this.putPrivate(el, THROTTLED, true);
- setTimeout(() => {
+ const t = setTimeout(() => {
if (asyncFilter()) {
this.triggerCycle(el, DEBOUNCE_TRIGGER);
}
}, timeout);
+ this.putPrivate(el, THROTTLED, t);
}
} else {
setTimeout(() => {
@@ -570,23 +625,26 @@
}
}, timeout);
}
- let form = el.form;
+ const 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}"]`);
+ const 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));
+ el.addEventListener("blur", () => {
+ clearTimeout(this.private(el, THROTTLED));
+ this.triggerCycle(el, DEBOUNCE_TRIGGER);
+ });
}
}
},
triggerCycle(el, key, currentCycle) {
- let [cycle, trigger] = this.private(el, key);
+ const [cycle, trigger] = this.private(el, key);
if (!currentCycle) {
currentCycle = cycle;
}
@@ -609,79 +667,114 @@
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");
+ maintainPrivateHooks(fromEl, toEl, phxViewportTop, phxViewportBottom) {
+ if (fromEl.hasAttribute && fromEl.hasAttribute("data-phx-hook") && !toEl.hasAttribute("data-phx-hook")) {
+ toEl.setAttribute("data-phx-hook", fromEl.getAttribute("data-phx-hook"));
+ }
+ if (toEl.hasAttribute && (toEl.hasAttribute(phxViewportTop) || toEl.hasAttribute(phxViewportBottom))) {
+ toEl.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));
+ putCustomElHook(el, hook) {
+ if (el.isConnected) {
+ el.setAttribute("data-phx-hook", "");
+ } else {
+ console.error(`
+ hook attached to non-connected DOM element
+ ensure you are calling createHook within your connectedCallback. ${el.outerHTML}
+ `);
}
+ this.putPrivate(el, "custom-el-hook", hook);
},
- resetForm(form, phxFeedbackFor) {
+ getCustomElHook(el) {
+ return this.private(el, "custom-el-hook");
+ },
+ isUsedInput(el) {
+ return el.nodeType === Node.ELEMENT_NODE && (this.private(el, PHX_HAS_FOCUSED) || this.private(el, PHX_HAS_SUBMITTED));
+ },
+ resetForm(form) {
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;
},
+ isChildOfAny(el, parents) {
+ return !!parents.find((parent) => parent.contains(el));
+ },
firstPhxChild(el) {
return this.isPhxChild(el) ? el : this.all(el, `[${PHX_PARENT_ID}]`)[0];
},
+ isPortalTemplate(el) {
+ return el.tagName === "TEMPLATE" && el.hasAttribute(PHX_PORTAL);
+ },
+ closestViewEl(el) {
+ const portalOrViewEl = el.closest(`[${PHX_TELEPORTED_REF}],${PHX_VIEW_SELECTOR}`);
+ if (!portalOrViewEl) {
+ return null;
+ }
+ if (portalOrViewEl.hasAttribute(PHX_TELEPORTED_REF)) {
+ return this.byId(portalOrViewEl.getAttribute(PHX_TELEPORTED_REF));
+ } else if (portalOrViewEl.hasAttribute(PHX_SESSION)) {
+ return portalOrViewEl;
+ }
+ return null;
+ },
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);
+ let defaultBubble = true;
+ const isUploadTarget = target.nodeName === "INPUT" && target.type === "file";
+ if (isUploadTarget && name === "click") {
+ defaultBubble = false;
+ }
+ const bubbles = opts.bubbles === void 0 ? defaultBubble : !!opts.bubbles;
+ const eventOpts = {
+ bubbles,
+ cancelable: true,
+ detail: opts.detail || {}
+ };
+ const 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);
+ const 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;
+ var _a;
+ const exclude = new Set(opts.exclude || []);
+ const isIgnored = opts.isIgnored;
+ const 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));
+ const name = sourceAttrs[i].name;
+ if (!exclude.has(name)) {
+ const sourceValue = source.getAttribute(name);
+ if (target.getAttribute(name) !== sourceValue && (!isIgnored || isIgnored && name.startsWith("data-"))) {
+ target.setAttribute(name, sourceValue);
+ }
+ } else {
+ if (name === "value") {
+ const sourceValue = (_a = source.value) != null ? _a : source.getAttribute(name);
+ if (target.value === sourceValue) {
+ target.setAttribute("value", source.getAttribute(name));
+ }
+ }
}
}
- let targetAttrs = target.attributes;
+ const targetAttrs = target.attributes;
for (let i = targetAttrs.length - 1; i >= 0; i--) {
- let name = targetAttrs[i].name;
+ const name = targetAttrs[i].name;
if (isIgnored) {
- if (name.startsWith("data-") && !source.hasAttribute(name)) {
+ if (name.startsWith("data-") && !source.hasAttribute(name) && !PHX_PENDING_ATTRS.includes(name)) {
target.removeAttribute(name);
}
} else {
@@ -705,13 +798,13 @@
return el.setSelectionRange && (el.type === "text" || el.type === "textarea");
},
restoreFocus(focused, selectionStart, selectionEnd) {
+ if (focused instanceof HTMLSelectElement) {
+ focused.focus();
+ }
if (!DOM.isTextualInput(focused)) {
return;
}
- let wasFocused = focused.matches(":focus");
- if (focused.readOnly) {
- focused.blur();
- }
+ const wasFocused = focused.matches(":focus");
if (!wasFocused) {
focused.focus();
}
@@ -720,6 +813,9 @@
}
},
isFormInput(el) {
+ if (el.localName && customElements.get(el.localName)) {
+ return customElements.get(el.localName)[`formAssociated`];
+ }
return /^(?:input|select|textarea)$/i.test(el.tagName) && el.type !== "button";
},
syncAttrsToProps(el) {
@@ -731,36 +827,15 @@
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;
- }
+ return el.getAttribute && el.getAttribute(phxTriggerExternal) !== null && document.body.contains(el);
},
cleanChildNodes(container, phxUpdate) {
- if (DOM.isPhxUpdate(container, phxUpdate, ["append", "prepend"])) {
- let toRemove = [];
+ if (DOM.isPhxUpdate(container, phxUpdate, ["append", "prepend", PHX_STREAM])) {
+ const toRemove = [];
container.childNodes.forEach((childNode) => {
if (!childNode.id) {
- let isEmptyTextNode = childNode.nodeType === Node.TEXT_NODE && childNode.nodeValue.trim() === "";
- if (!isEmptyTextNode) {
+ const isEmptyTextNode = childNode.nodeType === Node.TEXT_NODE && childNode.nodeValue.trim() === "";
+ if (!isEmptyTextNode && childNode.nodeType !== Node.COMMENT_NODE) {
logError(`only HTML element tags with an id are allowed inside containers with phx-update.
removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
@@ -774,13 +849,19 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
}
},
replaceRootContainer(container, tagName, attrs) {
- let retainedAttrs = new Set(["id", PHX_SESSION, PHX_STATIC, PHX_MAIN, PHX_ROOT_ID]);
+ const 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);
+ const 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;
@@ -789,9 +870,9 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
}
},
getSticky(el, name, defaultVal) {
- let op = (DOM.private(el, "sticky") || []).find(([existingName]) => name === existingName);
+ const op = (DOM.private(el, "sticky") || []).find(([existingName]) => name === existingName);
if (op) {
- let [_name, _op, stashedResult] = op;
+ const [_name, _op, stashedResult] = op;
return stashedResult;
} else {
return typeof defaultVal === "function" ? defaultVal() : defaultVal;
@@ -803,9 +884,9 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
});
},
putSticky(el, name, op) {
- let stashedResult = op(el);
+ const stashedResult = op(el);
this.updatePrivate(el, "sticky", [], (ops) => {
- let existingIndex = ops.findIndex(([existingName]) => name === existingName);
+ const existingIndex = ops.findIndex(([existingName]) => name === existingName);
if (existingIndex >= 0) {
ops[existingIndex] = [name, op, stashedResult];
} else {
@@ -815,27 +896,36 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
});
},
applyStickyOperations(el) {
- let ops = DOM.private(el, "sticky");
+ const ops = DOM.private(el, "sticky");
if (!ops) {
return;
}
ops.forEach(([name, op, _stashed]) => this.putSticky(el, name, op));
+ },
+ isLocked(el) {
+ return el.hasAttribute && el.hasAttribute(PHX_REF_LOCK);
}
};
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;
+ const isNew = file._phxRef === void 0;
+ const activeRefs = fileEl.getAttribute(PHX_ACTIVE_ENTRY_REFS).split(",");
+ const 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;
+ const preflightedRefs = fileEl.getAttribute(PHX_PREFLIGHTED_REFS).split(",");
+ const isPreflighted = preflightedRefs.indexOf(LiveUploader.genFileRef(file)) >= 0;
return isPreflighted && this.isActive(fileEl, file);
}
- constructor(fileEl, file, view) {
+ static isPreflightInProgress(file) {
+ return file._preflightInProgress === true;
+ }
+ static markPreflightInProgress(file) {
+ file._preflightInProgress = true;
+ }
+ constructor(fileEl, file, view, autoUpload) {
this.ref = LiveUploader.genFileRef(file);
this.fileEl = fileEl;
this.file = file;
@@ -849,6 +939,7 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
};
this._onElUpdated = this.onElUpdated.bind(this);
this.fileEl.addEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated);
+ this.autoUpload = autoUpload;
}
metadata() {
return this.meta;
@@ -870,7 +961,11 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
}
}
}
+ isCancelled() {
+ return this._isCancelled;
+ }
cancel() {
+ this.file._preflightInProgress = false;
this._isCancelled = true;
this._isDone = true;
this._onDone();
@@ -881,10 +976,13 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
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)) {
+ if (!this.isAutoUpload()) {
LiveUploader.clearFiles(this.fileEl);
}
}
+ isAutoUpload() {
+ return this.autoUpload;
+ }
onDone(callback) {
this._onDone = () => {
this.fileEl.removeEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated);
@@ -892,8 +990,9 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
};
}
onElUpdated() {
- let activeRefs = this.fileEl.getAttribute(PHX_ACTIVE_ENTRY_REFS).split(",");
+ const activeRefs = this.fileEl.getAttribute(PHX_ACTIVE_ENTRY_REFS).split(",");
if (activeRefs.indexOf(this.ref) === -1) {
+ LiveUploader.untrackFile(this.fileEl, this.file);
this.cancel();
}
}
@@ -904,12 +1003,13 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
relative_path: this.file.webkitRelativePath,
size: this.file.size,
type: this.file.type,
- ref: this.ref
+ ref: this.ref,
+ meta: typeof this.file.meta === "function" ? this.file.meta() : void 0
};
}
uploader(uploaders) {
if (this.meta.uploader) {
- let callback = uploaders[this.meta.uploader] || logError(`no uploader configured for ${this.meta.uploader}`);
+ const 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 };
@@ -918,14 +1018,17 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
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 });
+ logError(`no preflight upload response returned with ref ${this.ref}`, {
+ input: this.fileEl,
+ response: resp
+ });
}
}
};
var liveUploaderFileRef = 0;
- var LiveUploader = class {
+ var LiveUploader = class _LiveUploader {
static genFileRef(file) {
- let ref = file._phxRef;
+ const ref = file._phxRef;
if (ref !== void 0) {
return ref;
} else {
@@ -934,7 +1037,7 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
}
}
static getEntryDataURL(inputEl, ref, callback) {
- let file = this.activeFiles(inputEl).find((file2) => this.genFileRef(file2) === ref);
+ const file = this.activeFiles(inputEl).find((file2) => this.genFileRef(file2) === ref);
callback(URL.createObjectURL(file));
}
static hasUploadsInProgress(formEl) {
@@ -947,11 +1050,11 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
return active > 0;
}
static serializeUploads(inputEl) {
- let files = this.activeFiles(inputEl);
- let fileData = {};
+ const files = this.activeFiles(inputEl);
+ const fileData = {};
files.forEach((file) => {
- let entry = { path: inputEl.name };
- let uploadRef = inputEl.getAttribute(PHX_UPLOAD_REF);
+ const entry = { path: inputEl.name };
+ const uploadRef = inputEl.getAttribute(PHX_UPLOAD_REF);
fileData[uploadRef] = fileData[uploadRef] || [];
entry.ref = this.genFileRef(file);
entry.last_modified = file.lastModified;
@@ -959,6 +1062,9 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
entry.relative_path = file.webkitRelativePath;
entry.type = file.type;
entry.size = file.size;
+ if (typeof file.meta === "function") {
+ entry.meta = file.meta();
+ }
fileData[uploadRef].push(entry);
});
return fileData;
@@ -973,8 +1079,8 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
}
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));
+ const newFiles = files.filter((file) => !this.activeFiles(inputEl).find((f) => Object.is(f, file)));
+ dom_default.updatePrivate(inputEl, "files", [], (existing) => existing.concat(newFiles));
inputEl.value = null;
} else {
if (dataTransfer && dataTransfer.files.length > 0) {
@@ -984,69 +1090,80 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
}
}
static activeFileInputs(formEl) {
- let fileInputs = dom_default.findUploadInputs(formEl);
+ const 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);
+ const 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));
+ return this.activeFiles(input).filter((f) => !UploadEntry.isPreflighted(input, f) && !UploadEntry.isPreflightInProgress(f));
+ }
+ static markPreflightInProgress(entries) {
+ entries.forEach((entry) => UploadEntry.markPreflightInProgress(entry.file));
}
constructor(inputEl, view, onComplete) {
+ this.autoUpload = dom_default.isAutoUpload(inputEl);
this.view = view;
this.onComplete = onComplete;
- this._entries = Array.from(LiveUploader.filesAwaitingPreflight(inputEl) || []).map((file) => new UploadEntry(inputEl, file, view));
+ this._entries = Array.from(_LiveUploader.filesAwaitingPreflight(inputEl) || []).map((file) => new UploadEntry(inputEl, file, view, this.autoUpload));
+ _LiveUploader.markPreflightInProgress(this._entries);
this.numEntriesInProgress = this._entries.length;
}
+ isAutoUpload() {
+ return this.autoUpload;
+ }
entries() {
return this._entries;
}
initAdapterUpload(resp, onError, liveSocket2) {
this._entries = this._entries.map((entry) => {
- entry.zipPostFlight(resp);
- entry.onDone(() => {
+ if (entry.isCancelled()) {
this.numEntriesInProgress--;
if (this.numEntriesInProgress === 0) {
this.onComplete();
}
- });
+ } else {
+ entry.zipPostFlight(resp);
+ entry.onDone(() => {
+ this.numEntriesInProgress--;
+ if (this.numEntriesInProgress === 0) {
+ this.onComplete();
+ }
+ });
+ }
return entry;
});
- let groupedEntries = this._entries.reduce((acc, entry) => {
+ const groupedEntries = this._entries.reduce((acc, entry) => {
if (!entry.meta) {
return acc;
}
- let { name, callback } = entry.uploader(liveSocket2.uploaders);
+ const { 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];
+ for (const name in groupedEntries) {
+ const { 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");
+ 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 && el.getAttribute("aria-hidden") !== "true" || !interactiveOnly && el.getAttribute("tabindex") !== null && el.getAttribute("aria-hidden") !== "true";
},
attemptFocus(el, interactiveOnly) {
if (this.isFocusable(el, interactiveOnly)) {
@@ -1060,7 +1177,7 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
focusFirstInteractive(el) {
let child = el.firstElementChild;
while (child) {
- if (this.attemptFocus(child, true) || this.focusFirstInteractive(child, true)) {
+ if (this.attemptFocus(child, true) || this.focusFirstInteractive(child)) {
return true;
}
child = child.nextElementSibling;
@@ -1098,11 +1215,11 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
this.preflightedWas = this.preflightedRefs();
},
updated() {
- let newPreflights = this.preflightedRefs();
+ const newPreflights = this.preflightedRefs();
if (this.preflightedWas !== newPreflights) {
this.preflightedWas = newPreflights;
if (newPreflights === "") {
- this.__view.cancelSubmit(this.el.form);
+ this.__view().cancelSubmit(this.el.form);
}
}
if (this.activeRefs() === "") {
@@ -1128,96 +1245,160 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
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);
+ this.focusStart.addEventListener("focus", (e) => {
+ if (!e.relatedTarget || !this.el.contains(e.relatedTarget)) {
+ const nextFocus = e.target.nextElementSibling;
+ aria_default.attemptFocus(nextFocus) || aria_default.focusFirst(nextFocus);
+ } else {
+ aria_default.focusLast(this.el);
+ }
+ });
+ this.focusEnd.addEventListener("focus", (e) => {
+ if (!e.relatedTarget || !this.el.contains(e.relatedTarget)) {
+ const nextFocus = e.target.previousElementSibling;
+ aria_default.attemptFocus(nextFocus) || aria_default.focusLast(nextFocus);
+ } else {
+ aria_default.focusFirst(this.el);
+ }
+ });
+ if (!this.el.contains(document.activeElement)) {
+ 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 findScrollContainer = (el) => {
+ if (["HTML", "BODY"].indexOf(el.nodeName.toUpperCase()) >= 0)
+ return null;
+ if (["scroll", "auto"].indexOf(getComputedStyle(el).overflowY) >= 0)
+ return el;
+ return findScrollContainer(el.parentElement);
+ };
+ var scrollTop = (scrollContainer) => {
+ if (scrollContainer) {
+ return scrollContainer.scrollTop;
+ } else {
+ return document.documentElement.scrollTop || document.body.scrollTop;
+ }
+ };
+ var bottom = (scrollContainer) => {
+ if (scrollContainer) {
+ return scrollContainer.getBoundingClientRect().bottom;
+ } else {
+ return window.innerHeight || document.documentElement.clientHeight;
+ }
+ };
+ var top = (scrollContainer) => {
+ if (scrollContainer) {
+ return scrollContainer.getBoundingClientRect().top;
+ } else {
+ return 0;
+ }
+ };
+ var isAtViewportTop = (el, scrollContainer) => {
+ const rect = el.getBoundingClientRect();
+ return Math.ceil(rect.top) >= top(scrollContainer) && Math.ceil(rect.left) >= 0 && Math.floor(rect.top) <= bottom(scrollContainer);
};
- var isAtViewportBottom = (el) => {
- let rect = el.getBoundingClientRect();
- return rect.right >= 0 && rect.left >= 0 && rect.bottom <= winHeight();
+ var isAtViewportBottom = (el, scrollContainer) => {
+ const rect = el.getBoundingClientRect();
+ return Math.ceil(rect.bottom) >= top(scrollContainer) && Math.ceil(rect.left) >= 0 && Math.floor(rect.bottom) <= bottom(scrollContainer);
};
- var isWithinViewport = (el) => {
- let rect = el.getBoundingClientRect();
- return rect.top >= 0 && rect.left >= 0 && rect.top <= winHeight();
+ var isWithinViewport = (el, scrollContainer) => {
+ const rect = el.getBoundingClientRect();
+ return Math.ceil(rect.top) >= top(scrollContainer) && Math.ceil(rect.left) >= 0 && Math.floor(rect.top) <= bottom(scrollContainer);
};
Hooks.InfiniteScroll = {
mounted() {
- let scrollBefore = scrollTop();
+ this.scrollContainer = findScrollContainer(this.el);
+ let scrollBefore = scrollTop(this.scrollContainer);
let topOverran = false;
- let throttleInterval = 500;
+ const throttleInterval = 500;
let pendingOp = null;
- let onTopOverrun = this.throttle(throttleInterval, (topEvent, firstChild) => {
+ const onTopOverrun = this.throttle(throttleInterval, (topEvent, firstChild) => {
pendingOp = () => true;
- this.liveSocket.execJSHookPush(this.el, topEvent, { id: firstChild.id, _overran: true }, () => {
- pendingOp = null;
+ this.liveSocket.js().push(this.el, topEvent, {
+ value: { id: firstChild.id, _overran: true },
+ callback: () => {
+ pendingOp = null;
+ }
});
});
- let onFirstChildAtTop = this.throttle(throttleInterval, (topEvent, firstChild) => {
+ const 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" });
+ this.liveSocket.js().push(this.el, topEvent, {
+ value: { id: firstChild.id },
+ callback: () => {
+ pendingOp = null;
+ window.requestAnimationFrame(() => {
+ if (!isWithinViewport(firstChild, this.scrollContainer)) {
+ firstChild.scrollIntoView({ block: "start" });
+ }
+ });
}
});
});
- let onLastChildAtBottom = this.throttle(throttleInterval, (bottomEvent, lastChild) => {
+ const 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.liveSocket.js().push(this.el, bottomEvent, {
+ value: { id: lastChild.id },
+ callback: () => {
+ pendingOp = null;
+ window.requestAnimationFrame(() => {
+ if (!isWithinViewport(lastChild, this.scrollContainer)) {
+ lastChild.scrollIntoView({ block: "end" });
+ }
+ });
}
});
});
- this.onScroll = (e) => {
- let scrollNow = scrollTop();
+ this.onScroll = (_e) => {
+ const scrollNow = scrollTop(this.scrollContainer);
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;
+ const rect = this.el.getBoundingClientRect();
+ const topEvent = this.el.getAttribute(this.liveSocket.binding("viewport-top"));
+ const bottomEvent = this.el.getAttribute(this.liveSocket.binding("viewport-bottom"));
+ const lastChild = this.el.lastElementChild;
+ const firstChild = this.el.firstElementChild;
+ const isScrollingUp = scrollNow < scrollBefore;
+ const 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)) {
+ if (topEvent && isScrollingUp && isAtViewportTop(firstChild, this.scrollContainer)) {
onFirstChildAtTop(topEvent, firstChild);
- } else if (bottomEvent && isScrollingDown && isAtViewportBottom(lastChild)) {
+ } else if (bottomEvent && isScrollingDown && isAtViewportBottom(lastChild, this.scrollContainer)) {
onLastChildAtBottom(bottomEvent, lastChild);
}
scrollBefore = scrollNow;
};
- window.addEventListener("scroll", this.onScroll);
+ if (this.scrollContainer) {
+ this.scrollContainer.addEventListener("scroll", this.onScroll);
+ } else {
+ window.addEventListener("scroll", this.onScroll);
+ }
},
destroyed() {
- window.removeEventListener("scroll", this.onScroll);
+ if (this.scrollContainer) {
+ this.scrollContainer.removeEventListener("scroll", this.onScroll);
+ } else {
+ window.removeEventListener("scroll", this.onScroll);
+ }
},
throttle(interval, callback) {
let lastCallAt = 0;
let timer;
return (...args) => {
- let now = Date.now();
- let remainingTime = interval - (now - lastCallAt);
+ const now = Date.now();
+ const remainingTime = interval - (now - lastCallAt);
if (remainingTime <= 0 || remainingTime > interval) {
if (timer) {
clearTimeout(timer);
@@ -1236,17 +1417,136 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
}
};
var hooks_default = Hooks;
+ var ElementRef = class {
+ static onUnlock(el, callback) {
+ if (!dom_default.isLocked(el) && !el.closest(`[${PHX_REF_LOCK}]`)) {
+ return callback();
+ }
+ const closestLock = el.closest(`[${PHX_REF_LOCK}]`);
+ const ref = closestLock.closest(`[${PHX_REF_LOCK}]`).getAttribute(PHX_REF_LOCK);
+ closestLock.addEventListener(`phx:undo-lock:${ref}`, () => {
+ callback();
+ }, { once: true });
+ }
+ constructor(el) {
+ this.el = el;
+ this.loadingRef = el.hasAttribute(PHX_REF_LOADING) ? parseInt(el.getAttribute(PHX_REF_LOADING), 10) : null;
+ this.lockRef = el.hasAttribute(PHX_REF_LOCK) ? parseInt(el.getAttribute(PHX_REF_LOCK), 10) : null;
+ }
+ maybeUndo(ref, phxEvent, eachCloneCallback) {
+ if (!this.isWithin(ref)) {
+ dom_default.updatePrivate(this.el, PHX_PENDING_REFS, [], (pendingRefs) => {
+ pendingRefs.push(ref);
+ return pendingRefs;
+ });
+ return;
+ }
+ this.undoLocks(ref, phxEvent, eachCloneCallback);
+ this.undoLoading(ref, phxEvent);
+ dom_default.updatePrivate(this.el, PHX_PENDING_REFS, [], (pendingRefs) => {
+ return pendingRefs.filter((pendingRef) => {
+ let opts = {
+ detail: { ref: pendingRef, event: phxEvent },
+ bubbles: true,
+ cancelable: false
+ };
+ if (this.loadingRef && this.loadingRef > pendingRef) {
+ this.el.dispatchEvent(new CustomEvent(`phx:undo-loading:${pendingRef}`, opts));
+ }
+ if (this.lockRef && this.lockRef > pendingRef) {
+ this.el.dispatchEvent(new CustomEvent(`phx:undo-lock:${pendingRef}`, opts));
+ }
+ return pendingRef > ref;
+ });
+ });
+ if (this.isFullyResolvedBy(ref)) {
+ this.el.removeAttribute(PHX_REF_SRC);
+ }
+ }
+ isWithin(ref) {
+ return !(this.loadingRef !== null && this.loadingRef > ref && this.lockRef !== null && this.lockRef > ref);
+ }
+ undoLocks(ref, phxEvent, eachCloneCallback) {
+ if (!this.isLockUndoneBy(ref)) {
+ return;
+ }
+ const clonedTree = dom_default.private(this.el, PHX_REF_LOCK);
+ if (clonedTree) {
+ eachCloneCallback(clonedTree);
+ dom_default.deletePrivate(this.el, PHX_REF_LOCK);
+ }
+ this.el.removeAttribute(PHX_REF_LOCK);
+ const opts = {
+ detail: { ref, event: phxEvent },
+ bubbles: true,
+ cancelable: false
+ };
+ this.el.dispatchEvent(new CustomEvent(`phx:undo-lock:${this.lockRef}`, opts));
+ }
+ undoLoading(ref, phxEvent) {
+ if (!this.isLoadingUndoneBy(ref)) {
+ if (this.canUndoLoading(ref) && this.el.classList.contains("phx-submit-loading")) {
+ this.el.classList.remove("phx-change-loading");
+ }
+ return;
+ }
+ if (this.canUndoLoading(ref)) {
+ this.el.removeAttribute(PHX_REF_LOADING);
+ const disabledVal = this.el.getAttribute(PHX_DISABLED);
+ const readOnlyVal = this.el.getAttribute(PHX_READONLY);
+ if (readOnlyVal !== null) {
+ this.el.readOnly = readOnlyVal === "true" ? true : false;
+ this.el.removeAttribute(PHX_READONLY);
+ }
+ if (disabledVal !== null) {
+ this.el.disabled = disabledVal === "true" ? true : false;
+ this.el.removeAttribute(PHX_DISABLED);
+ }
+ const disableRestore = this.el.getAttribute(PHX_DISABLE_WITH_RESTORE);
+ if (disableRestore !== null) {
+ this.el.textContent = disableRestore;
+ this.el.removeAttribute(PHX_DISABLE_WITH_RESTORE);
+ }
+ const opts = {
+ detail: { ref, event: phxEvent },
+ bubbles: true,
+ cancelable: false
+ };
+ this.el.dispatchEvent(new CustomEvent(`phx:undo-loading:${this.loadingRef}`, opts));
+ }
+ PHX_EVENT_CLASSES.forEach((name) => {
+ if (name !== "phx-submit-loading" || this.canUndoLoading(ref)) {
+ dom_default.removeClass(this.el, name);
+ }
+ });
+ }
+ isLoadingUndoneBy(ref) {
+ return this.loadingRef === null ? false : this.loadingRef <= ref;
+ }
+ isLockUndoneBy(ref) {
+ return this.lockRef === null ? false : this.lockRef <= ref;
+ }
+ isFullyResolvedBy(ref) {
+ return (this.loadingRef === null || this.loadingRef <= ref) && (this.lockRef === null || this.lockRef <= ref);
+ }
+ canUndoLoading(ref) {
+ return this.lockRef === null || this.lockRef <= ref;
+ }
+ };
var DOMPostMorphRestorer = class {
constructor(containerBefore, containerAfter, updateType) {
- let idsBefore = new Set();
- let idsAfter = new Set([...containerAfter.children].map((child) => child.id));
- let elementsToModify = [];
+ const idsBefore = /* @__PURE__ */ new Set();
+ const idsAfter = new Set([...containerAfter.children].map((child) => child.id));
+ const 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 });
+ const previousElementId = child.previousElementSibling && child.previousElementSibling.id;
+ elementsToModify.push({
+ elementId: child.id,
+ previousElementId
+ });
}
}
});
@@ -1256,12 +1556,15 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
this.elementIdsToAdd = [...idsAfter].filter((id) => !idsBefore.has(id));
}
perform() {
- let container = dom_default.byId(this.containerId);
+ const container = dom_default.byId(this.containerId);
+ if (!container) {
+ return;
+ }
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;
+ const isInRightPlace = elem.previousElementSibling && elem.previousElementSibling.id == previousElem.id;
if (!isInRightPlace) {
previousElem.insertAdjacentElement("afterend", elem);
}
@@ -1269,7 +1572,7 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
});
} else {
maybe(document.getElementById(elementToModify.elementId), (elem) => {
- let isInRightPlace = elem.previousElementSibling == null;
+ const isInRightPlace = elem.previousElementSibling == null;
if (!isInRightPlace) {
container.insertAdjacentElement("afterbegin", elem);
}
@@ -1458,6 +1761,10 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
if (nodeName === "OPTGROUP") {
optgroup = curChild;
curChild = optgroup.firstChild;
+ if (!curChild) {
+ curChild = optgroup.nextSibling;
+ optgroup = null;
+ }
} else {
if (nodeName === "OPTION") {
if (curChild.hasAttribute("selected")) {
@@ -1517,7 +1824,7 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
return parent.appendChild(child);
};
var childrenOnly = options.childrenOnly === true;
- var fromNodesLookup = Object.create(null);
+ var fromNodesLookup = /* @__PURE__ */ Object.create(null);
var keyedRemovalList = [];
function addKeyedRemoval(key) {
keyedRemovalList.push(key);
@@ -1600,8 +1907,12 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
delete fromNodesLookup[toElKey];
}
if (!childrenOnly2) {
- if (onBeforeElUpdated(fromEl, toEl) === false) {
+ var beforeUpdateResult = onBeforeElUpdated(fromEl, toEl);
+ if (beforeUpdateResult === false) {
return;
+ } else if (beforeUpdateResult instanceof HTMLElement) {
+ fromEl = beforeUpdateResult;
+ indexTree(fromEl);
}
morphAttrs2(fromEl, toEl);
onElUpdated(fromEl);
@@ -1616,7 +1927,7 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
}
}
function morphChildren(fromEl, toEl) {
- var skipFrom = skipFromChildren(fromEl);
+ var skipFrom = skipFromChildren(fromEl, toEl);
var curToNodeChild = toEl.firstChild;
var curFromNodeChild = fromEl.firstChild;
var curToNodeKey;
@@ -1653,6 +1964,7 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
removeNode(curFromNodeChild, fromEl, true);
}
curFromNodeChild = matchingFromEl;
+ curFromNodeKey = getNodeKey(curFromNodeChild);
}
} else {
isCompatible = false;
@@ -1763,18 +2075,7 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
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) {
+ constructor(view, container, id, html, streams, targetCID, opts = {}) {
this.view = view;
this.liveSocket = view.liveSocket;
this.container = container;
@@ -1783,10 +2084,12 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
this.html = html;
this.streams = streams;
this.streamInserts = {};
+ this.streamComponentRestore = {};
this.targetCID = targetCID;
this.cidPatch = isCid(this.targetCID);
this.pendingRemoves = [];
this.phxRemove = this.liveSocket.binding("remove");
+ this.targetContainer = this.isCIDPatch() ? this.targetCIDContainer(html) : container;
this.callbacks = {
beforeadded: [],
beforeupdated: [],
@@ -1797,6 +2100,8 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
afterphxChildAdded: [],
aftertransitionsDiscarded: []
};
+ this.withChildren = opts.withChildren || opts.undoRef || false;
+ this.undoRef = opts.undoRef;
}
before(kind, callback) {
this.callbacks[`before${kind}`].push(callback);
@@ -1811,98 +2116,94 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
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 = "");
+ const phxUpdate = this.liveSocket.binding(PHX_UPDATE);
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) {
+ perform(isJoinPatch) {
+ const { view, liveSocket: liveSocket2, html, container } = this;
+ let targetContainer = this.targetContainer;
+ if (this.isCIDPatch() && !this.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);
- }
- });
+ if (this.isCIDPatch()) {
+ const closestLock = targetContainer.closest(`[${PHX_REF_LOCK}]`);
+ if (closestLock) {
+ const clonedTree = dom_default.private(closestLock, PHX_REF_LOCK);
+ if (clonedTree) {
+ targetContainer = clonedTree.querySelector(`[data-phx-component="${this.targetCID}"]`);
}
- 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,
+ }
+ }
+ const focused = liveSocket2.getActiveElement();
+ const { selectionStart, selectionEnd } = focused && dom_default.hasSelectionRange(focused) ? focused : {};
+ const phxUpdate = liveSocket2.binding(PHX_UPDATE);
+ const phxViewportTop = liveSocket2.binding(PHX_VIEWPORT_TOP);
+ const phxViewportBottom = liveSocket2.binding(PHX_VIEWPORT_BOTTOM);
+ const phxTriggerExternal = liveSocket2.binding(PHX_TRIGGER_ACTION);
+ const added = [];
+ const updates = [];
+ const appendPrependUpdates = [];
+ const portalCallbacks = [];
+ let externalFormTriggered = null;
+ const morph = (targetContainer2, source, withChildren = this.withChildren) => {
+ const morphCallbacks = {
+ childrenOnly: targetContainer2.getAttribute(PHX_COMPONENT) === null && !withChildren,
getNodeKey: (node) => {
- return dom_default.isPhxDestroyed(node) ? null : node.id;
+ if (dom_default.isPhxDestroyed(node)) {
+ return null;
+ }
+ if (isJoinPatch) {
+ return node.id;
+ }
+ return node.id || node.getAttribute && node.getAttribute(PHX_MAGIC_ID);
},
skipFromChildren: (from) => {
return from.getAttribute(phxUpdate) === PHX_STREAM;
},
addChild: (parent, child) => {
- let { ref, streamAt, limit } = this.getStreamInsert(child);
+ const { ref, streamAt } = 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));
+ this.setStreamRef(child, ref);
if (streamAt === 0) {
parent.insertAdjacentElement("afterbegin", child);
} else if (streamAt === -1) {
- parent.appendChild(child);
+ const lastChild = parent.lastElementChild;
+ if (lastChild && !lastChild.hasAttribute(PHX_STREAM_REF)) {
+ const nonStreamChild = Array.from(parent.children).find((c) => !c.hasAttribute(PHX_STREAM_REF));
+ parent.insertBefore(child, nonStreamChild);
+ } else {
+ parent.appendChild(child);
+ }
} else if (streamAt > 0) {
- let sibling = Array.from(parent.children)[streamAt];
+ const 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);
+ var _a;
+ if (((_a = this.getStreamInsert(el)) == null ? void 0 : _a.updateOnly) && !this.streamComponentRestore[el.id]) {
+ return false;
+ }
+ dom_default.maintainPrivateHooks(el, el, phxViewportTop, phxViewportBottom);
this.trackBefore("added", el);
- return el;
+ let morphedEl = el;
+ if (this.streamComponentRestore[el.id]) {
+ morphedEl = this.streamComponentRestore[el.id];
+ delete this.streamComponentRestore[el.id];
+ morph(morphedEl, el, true);
+ }
+ return morphedEl;
},
onNodeAdded: (el) => {
if (el.getAttribute) {
- this.maybeReOrderStream(el);
+ this.maybeReOrderStream(el, true);
+ }
+ if (dom_default.isPortalTemplate(el)) {
+ portalCallbacks.push(() => this.teleport(el, morph));
}
if (el instanceof HTMLImageElement && el.srcset) {
el.srcset = el.srcset;
@@ -1912,12 +2213,12 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
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);
}
+ if (el.nodeName === "SCRIPT" && el.hasAttribute(PHX_RUNTIME_HOOK)) {
+ this.handleRuntimeHook(el, source);
+ }
added.push(el);
},
onNodeDiscarded: (el) => this.onNodeDiscarded(el),
@@ -1925,7 +2226,14 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
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"])) {
+ if (el.parentElement !== null && el.id && dom_default.isPhxUpdate(el.parentElement, phxUpdate, [
+ PHX_STREAM,
+ "append",
+ "prepend"
+ ])) {
+ return false;
+ }
+ if (el.getAttribute && el.getAttribute(PHX_TELEPORTED_REF)) {
return false;
}
if (this.maybePendingRemove(el)) {
@@ -1934,6 +2242,14 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
if (this.skipCIDSibling(el)) {
return false;
}
+ if (dom_default.isPortalTemplate(el)) {
+ const teleportedEl = document.getElementById(el.content.firstElementChild.id);
+ if (teleportedEl) {
+ teleportedEl.remove();
+ morphCallbacks.onNodeDiscarded(teleportedEl);
+ this.view.dropPortalElementId(teleportedEl.id);
+ }
+ }
return true;
},
onElUpdated: (el) => {
@@ -1941,37 +2257,68 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
externalFormTriggered = el;
}
updates.push(el);
- this.maybeReOrderStream(el);
+ this.maybeReOrderStream(el, false);
},
onBeforeElUpdated: (fromEl, toEl) => {
- dom_default.maybeAddPrivateHooks(toEl, phxViewportTop, phxViewportBottom);
+ if (fromEl.id && fromEl.isSameNode(targetContainer2) && fromEl.id !== toEl.id) {
+ morphCallbacks.onNodeDiscarded(fromEl);
+ fromEl.replaceWith(toEl);
+ return morphCallbacks.onNodeAdded(toEl);
+ }
+ dom_default.syncPendingAttrs(fromEl, toEl);
+ dom_default.maintainPrivateHooks(fromEl, toEl, phxViewportTop, phxViewportBottom);
dom_default.cleanChildNodes(toEl, phxUpdate);
if (this.skipCIDSibling(toEl)) {
+ this.maybeReOrderStream(fromEl);
return false;
}
if (dom_default.isPhxSticky(fromEl)) {
+ [PHX_SESSION, PHX_STATIC, PHX_ROOT_ID].map((attr) => [
+ attr,
+ fromEl.getAttribute(attr),
+ toEl.getAttribute(attr)
+ ]).forEach(([attr, fromVal, toVal]) => {
+ if (toVal && fromVal !== toVal) {
+ fromEl.setAttribute(attr, toVal);
+ }
+ });
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 });
+ dom_default.mergeAttrs(fromEl, toEl, {
+ isIgnored: dom_default.isIgnored(fromEl, phxUpdate)
+ });
updates.push(fromEl);
dom_default.applyStickyOperations(fromEl);
return false;
}
- if (fromEl.type === "number" && (fromEl.validity && fromEl.validity.badInput)) {
+ 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);
+ const isFocusedFormEl = focused && fromEl.isSameNode(focused) && dom_default.isFormInput(fromEl);
+ const focusedSelectChanged = isFocusedFormEl && this.isChangedSelect(fromEl, toEl);
+ if (fromEl.hasAttribute(PHX_REF_SRC)) {
+ const ref = new ElementRef(fromEl);
+ if (ref.lockRef && (!this.undoRef || !ref.isLockUndoneBy(this.undoRef))) {
+ if (dom_default.isUploadInput(fromEl)) {
+ dom_default.mergeAttrs(fromEl, toEl, { isIgnored: true });
+ this.trackBefore("updated", fromEl, toEl);
+ updates.push(fromEl);
+ }
+ dom_default.applyStickyOperations(fromEl);
+ const isLocked = fromEl.hasAttribute(PHX_REF_LOCK);
+ const clone2 = isLocked ? dom_default.private(fromEl, PHX_REF_LOCK) || fromEl.cloneNode(true) : null;
+ if (clone2) {
+ dom_default.putPrivate(fromEl, PHX_REF_LOCK, clone2);
+ if (!isFocusedFormEl) {
+ fromEl = clone2;
+ }
+ }
}
- dom_default.applyStickyOperations(fromEl);
- return false;
}
if (dom_default.isPhxChild(toEl)) {
- let prevSession = fromEl.getAttribute(PHX_SESSION);
+ const prevSession = fromEl.getAttribute(PHX_SESSION);
dom_default.mergeAttrs(fromEl, toEl, { exclude: [PHX_STATIC] });
if (prevSession !== "") {
fromEl.setAttribute(PHX_SESSION, prevSession);
@@ -1980,42 +2327,91 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
dom_default.applyStickyOperations(fromEl);
return false;
}
+ if (this.undoRef && dom_default.private(toEl, PHX_REF_LOCK)) {
+ dom_default.putPrivate(fromEl, PHX_REF_LOCK, dom_default.private(toEl, PHX_REF_LOCK));
+ }
dom_default.copyPrivates(toEl, fromEl);
- let isFocusedFormEl = focused && fromEl.isSameNode(focused) && dom_default.isFormInput(fromEl);
- if (isFocusedFormEl && fromEl.type !== "hidden") {
+ if (dom_default.isPortalTemplate(toEl)) {
+ portalCallbacks.push(() => this.teleport(toEl, morph));
+ return false;
+ }
+ if (isFocusedFormEl && fromEl.type !== "hidden" && !focusedSelectChanged) {
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 (focusedSelectChanged) {
+ fromEl.blur();
+ }
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;
+ return fromEl;
+ }
+ }
+ };
+ morphdom_esm_default(targetContainer2, source, morphCallbacks);
+ };
+ this.trackBefore("added", container);
+ this.trackBefore("updated", container, container);
+ liveSocket2.time("morphdom", () => {
+ this.streams.forEach(([ref, inserts, deleteIds, reset]) => {
+ inserts.forEach(([key, streamAt, limit, updateOnly]) => {
+ this.streamInserts[key] = { ref, streamAt, limit, reset, updateOnly };
+ });
+ if (reset !== void 0) {
+ dom_default.all(container, `[${PHX_STREAM_REF}="${ref}"]`, (child) => {
+ this.removeStreamChildElement(child);
+ });
+ }
+ deleteIds.forEach((id) => {
+ const child = container.querySelector(`[id="${id}"]`);
+ if (child) {
+ this.removeStreamChildElement(child);
+ }
+ });
+ });
+ if (isJoinPatch) {
+ dom_default.all(this.container, `[${phxUpdate}=${PHX_STREAM}]`).filter((el) => this.view.ownsElement(el)).forEach((el) => {
+ Array.from(el.children).forEach((child) => {
+ this.removeStreamChildElement(child, true);
+ });
+ });
+ }
+ morph(targetContainer, html);
+ portalCallbacks.forEach((callback) => callback());
+ this.view.portalElementIds.forEach((id) => {
+ const el = document.getElementById(id);
+ if (el) {
+ const source = document.getElementById(el.getAttribute(PHX_TELEPORTED_SRC));
+ if (!source) {
+ el.remove();
+ this.onNodeDiscarded(el);
+ this.view.dropPortalElementId(id);
}
}
});
});
if (liveSocket2.isDebugEnabled()) {
detectDuplicateIds();
+ detectInvalidStreamInserts(this.streamInserts);
+ Array.from(document.querySelectorAll("input[name=id]")).forEach((node) => {
+ if (node instanceof HTMLInputElement && node.form) {
+ console.error('Detected an input with name="id" inside a form! This will cause problems when patching the DOM.\n', node);
+ }
+ });
}
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));
@@ -2023,6 +2419,18 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
this.transitionPendingRemoves();
if (externalFormTriggered) {
liveSocket2.unload();
+ const submitter = dom_default.private(externalFormTriggered, "submitter");
+ if (submitter && submitter.name && targetContainer.contains(submitter)) {
+ const input = document.createElement("input");
+ input.type = "hidden";
+ const formId = submitter.getAttribute("form");
+ if (formId) {
+ input.setAttribute("form", formId);
+ }
+ input.name = submitter.name;
+ input.value = submitter.value;
+ submitter.parentElement.insertBefore(input, submitter);
+ }
Object.getPrototypeOf(externalFormTriggered).submit.call(externalFormTriggered);
}
return true;
@@ -2041,31 +2449,48 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
return false;
}
}
- removeStreamChildElement(child) {
- if (!this.maybePendingRemove(child)) {
+ removeStreamChildElement(child, force = false) {
+ if (!force && !this.view.ownsElement(child)) {
+ return;
+ }
+ if (this.streamInserts[child.id]) {
+ this.streamComponentRestore[child.id] = child;
child.remove();
- this.onNodeDiscarded(child);
+ } else {
+ if (!this.maybePendingRemove(child)) {
+ child.remove();
+ this.onNodeDiscarded(child);
+ }
}
}
getStreamInsert(el) {
- let insert = el.id ? this.streamInserts[el.id] : {};
+ const insert = el.id ? this.streamInserts[el.id] : {};
return insert || {};
}
- maybeReOrderStream(el) {
- let { ref, streamAt, limit } = this.getStreamInsert(el);
+ setStreamRef(el, ref) {
+ dom_default.putSticky(el, PHX_STREAM_REF, (el2) => el2.setAttribute(PHX_STREAM_REF, ref));
+ }
+ maybeReOrderStream(el, isNew) {
+ const { ref, streamAt, reset } = 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);
+ this.setStreamRef(el, ref);
+ if (!reset && !isNew) {
+ return;
+ }
+ if (!el.parentElement) {
+ return;
+ }
+ 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);
+ const children = Array.from(el.parentElement.children);
+ const oldIndex = children.indexOf(el);
if (streamAt >= children.length - 1) {
el.parentElement.appendChild(el);
} else {
- let sibling = children[streamAt];
+ const sibling = children[streamAt];
if (oldIndex > streamAt) {
el.parentElement.insertBefore(el, sibling);
} else {
@@ -2073,14 +2498,23 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
}
}
}
+ this.maybeLimitStream(el);
+ }
+ maybeLimitStream(el) {
+ const { limit } = this.getStreamInsert(el);
+ const children = limit !== null && Array.from(el.parentElement.children);
+ if (limit && limit < 0 && children.length > limit * -1) {
+ children.slice(0, children.length + limit).forEach((child) => this.removeStreamChildElement(child));
+ } else if (limit && limit >= 0 && children.length > limit) {
+ children.slice(limit).forEach((child) => this.removeStreamChildElement(child));
+ }
}
transitionPendingRemoves() {
- let { pendingRemoves, liveSocket: liveSocket2 } = this;
+ const { pendingRemoves, liveSocket: liveSocket2 } = this;
if (pendingRemoves.length > 0) {
- liveSocket2.transitionRemoves(pendingRemoves);
- liveSocket2.requestDOMUpdate(() => {
+ liveSocket2.transitionRemoves(pendingRemoves, () => {
pendingRemoves.forEach((el) => {
- let child = dom_default.firstPhxChild(el);
+ const child = dom_default.firstPhxChild(el);
if (child) {
liveSocket2.destroyViewByEl(child);
}
@@ -2090,53 +2524,177 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
});
}
}
+ isChangedSelect(fromEl, toEl) {
+ if (!(fromEl instanceof HTMLSelectElement) || fromEl.multiple) {
+ return false;
+ }
+ if (fromEl.options.length !== toEl.options.length) {
+ return true;
+ }
+ toEl.value = fromEl.value;
+ return !fromEl.isEqualNode(toEl);
+ }
isCIDPatch() {
return this.cidPatch;
}
skipCIDSibling(el) {
- return el.nodeType === Node.ELEMENT_NODE && el.getAttribute(PHX_SKIP) !== null;
+ return el.nodeType === Node.ELEMENT_NODE && el.hasAttribute(PHX_SKIP);
}
targetCIDContainer(html) {
if (!this.isCIDPatch()) {
return;
}
- let [first, ...rest] = dom_default.findComponentNodeList(this.container, this.targetCID);
+ const [first, ...rest] = dom_default.findComponentNodeList(this.view.id, 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;
+ indexOf(parent, child) {
+ return Array.from(parent.children).indexOf(child);
+ }
+ teleport(el, morph) {
+ const targetSelector = el.getAttribute(PHX_PORTAL);
+ const portalContainer = document.querySelector(targetSelector);
+ if (!portalContainer) {
+ throw new Error("portal target with selector " + targetSelector + " not found");
+ }
+ const toTeleport = el.content.firstElementChild;
+ if (this.skipCIDSibling(toTeleport)) {
+ return;
+ }
+ if (!(toTeleport == null ? void 0 : toTeleport.id)) {
+ throw new Error("phx-portal template must have a single root element with ID!");
+ }
+ const existing = document.getElementById(toTeleport.id);
+ let portalTarget;
+ if (existing) {
+ if (!portalContainer.contains(existing)) {
+ portalContainer.appendChild(existing);
+ }
+ portalTarget = existing;
} 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 = "";
+ portalTarget = document.createElement(toTeleport.tagName);
+ portalContainer.appendChild(portalTarget);
+ }
+ toTeleport.setAttribute(PHX_TELEPORTED_REF, this.view.id);
+ toTeleport.setAttribute(PHX_TELEPORTED_SRC, el.id);
+ morph(portalTarget, toTeleport, true);
+ toTeleport.removeAttribute(PHX_TELEPORTED_REF);
+ toTeleport.removeAttribute(PHX_TELEPORTED_SRC);
+ this.view.pushPortalElementId(toTeleport.id);
+ }
+ handleRuntimeHook(el, source) {
+ const name = el.getAttribute(PHX_RUNTIME_HOOK);
+ let nonce = el.hasAttribute("nonce") ? el.getAttribute("nonce") : null;
+ if (el.hasAttribute("nonce")) {
+ const template = document.createElement("template");
+ template.innerHTML = source;
+ nonce = template.content.querySelector(`script[${PHX_RUNTIME_HOOK}="${CSS.escape(name)}"]`).getAttribute("nonce");
+ }
+ const script = document.createElement("script");
+ script.textContent = el.textContent;
+ dom_default.mergeAttrs(script, el, { isIgnored: false });
+ if (nonce) {
+ script.nonce = nonce;
+ }
+ el.replaceWith(script);
+ el = script;
+ }
+ };
+ var VOID_TAGS = /* @__PURE__ */ new Set([
+ "area",
+ "base",
+ "br",
+ "col",
+ "command",
+ "embed",
+ "hr",
+ "img",
+ "input",
+ "keygen",
+ "link",
+ "meta",
+ "param",
+ "source",
+ "track",
+ "wbr"
+ ]);
+ var quoteChars = /* @__PURE__ */ new Set(["'", '"']);
+ var modifyRoot = (html, attrs, clearInnerHTML) => {
+ let i = 0;
+ let insideComment = false;
+ let beforeTag, afterTag, tag, tagNameEndsAt, id, newHTML;
+ const lookahead = html.match(/^(\s*(?:\s*)*)<([^\s\/>]+)/);
+ if (lookahead === null) {
+ throw new Error(`malformed html ${html}`);
+ }
+ i = lookahead[0].length;
+ beforeTag = lookahead[1];
+ tag = lookahead[2];
+ tagNameEndsAt = i;
+ for (i; i < html.length; i++) {
+ if (html.charAt(i) === ">") {
+ break;
+ }
+ if (html.charAt(i) === "=") {
+ const isId = html.slice(i - 3, i) === " id";
+ i++;
+ const char = html.charAt(i);
+ if (quoteChars.has(char)) {
+ const attrStartsAt = i;
+ i++;
+ for (i; i < html.length; i++) {
+ if (html.charAt(i) === char) {
+ break;
+ }
}
- });
- Array.from(template.content.childNodes).forEach((el) => diffContainer.insertBefore(el, firstComponent));
- firstComponent.remove();
- return diffContainer.outerHTML;
+ if (isId) {
+ id = html.slice(attrStartsAt + 1, i);
+ break;
+ }
+ }
}
}
- indexOf(parent, child) {
- return Array.from(parent.children).indexOf(child);
+ let closeAt = html.length - 1;
+ insideComment = false;
+ while (closeAt >= beforeTag.length + tag.length) {
+ const char = html.charAt(closeAt);
+ if (insideComment) {
+ if (char === "-" && html.slice(closeAt - 3, closeAt) === "" && html.slice(closeAt - 2, closeAt) === "--") {
+ insideComment = true;
+ closeAt -= 3;
+ } else if (char === ">") {
+ break;
+ } else {
+ closeAt -= 1;
+ }
}
+ afterTag = html.slice(closeAt + 1, html.length);
+ const attrsStr = Object.keys(attrs).map((attr) => attrs[attr] === true ? attr : `${attr}="${attrs[attr]}"`).join(" ");
+ if (clearInnerHTML) {
+ const idAttrStr = id ? ` id="${id}"` : "";
+ if (VOID_TAGS.has(tag)) {
+ newHTML = `<${tag}${idAttrStr}${attrsStr === "" ? "" : " "}${attrsStr}/>`;
+ } else {
+ newHTML = `<${tag}${idAttrStr}${attrsStr === "" ? "" : " "}${attrsStr}>${tag}>`;
+ }
+ } else {
+ const rest = html.slice(tagNameEndsAt, closeAt + 1);
+ newHTML = `<${tag}${attrsStr === "" ? "" : " "}${attrsStr}${rest}`;
+ }
+ return [newHTML, beforeTag, afterTag];
};
var Rendered = class {
static extract(diff) {
- let { [REPLY]: reply, [EVENTS]: events, [TITLE]: title } = diff;
+ const { [REPLY]: reply, [EVENTS]: events, [TITLE]: title } = diff;
delete diff[REPLY];
delete diff[EVENTS];
delete diff[TITLE];
@@ -2145,20 +2703,26 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
constructor(viewId, rendered) {
this.viewId = viewId;
this.rendered = {};
+ this.magicId = 0;
this.mergeDiff(rendered);
}
parentViewId() {
return this.viewId;
}
toString(onlyCids) {
- let [str, streams] = this.recursiveToString(this.rendered, this.rendered[COMPONENTS], onlyCids);
- return [str, streams];
+ const { buffer: str, streams } = this.recursiveToString(this.rendered, this.rendered[COMPONENTS], onlyCids, true, {});
+ return { buffer: str, streams };
}
- recursiveToString(rendered, components = rendered[COMPONENTS], onlyCids) {
+ recursiveToString(rendered, components = rendered[COMPONENTS], onlyCids, changeTracking, rootAttrs) {
onlyCids = onlyCids ? new Set(onlyCids) : null;
- let output = { buffer: "", components, onlyCids, streams: new Set() };
- this.toOutputBuffer(rendered, null, output);
- return [output.buffer, output.streams];
+ const output = {
+ buffer: "",
+ components,
+ onlyCids,
+ streams: /* @__PURE__ */ new Set()
+ };
+ this.toOutputBuffer(rendered, null, output, changeTracking, rootAttrs);
+ return { buffer: output.buffer, streams: output.streams };
}
componentCIDs(diff) {
return Object.keys(diff[COMPONENTS] || {}).map((i) => parseInt(i));
@@ -2172,18 +2736,23 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
getComponent(diff, cid) {
return diff[COMPONENTS][cid];
}
+ resetRender(cid) {
+ if (this.rendered[COMPONENTS][cid]) {
+ this.rendered[COMPONENTS][cid].reset = true;
+ }
+ }
mergeDiff(diff) {
- let newc = diff[COMPONENTS];
- let cache = {};
+ const newc = diff[COMPONENTS];
+ const 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) {
+ const oldc = this.rendered[COMPONENTS];
+ for (const cid in newc) {
newc[cid] = this.cachedFindComponent(cid, newc[cid], oldc, newc, cache);
}
- for (let cid in newc) {
+ for (const cid in newc) {
oldc[cid] = newc[cid];
}
diff[COMPONENTS] = newc;
@@ -2202,10 +2771,10 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
tdiff = oldc[-scid];
}
stat = tdiff[STATIC];
- ndiff = this.cloneMerge(tdiff, cdiff);
+ ndiff = this.cloneMerge(tdiff, cdiff, true);
ndiff[STATIC] = stat;
} else {
- ndiff = cdiff[STATIC] !== void 0 ? cdiff : this.cloneMerge(oldc[cid] || {}, cdiff);
+ ndiff = cdiff[STATIC] !== void 0 || oldc[cid] === void 0 ? cdiff : this.cloneMerge(oldc[cid], cdiff, false);
}
cache[cid] = ndiff;
return ndiff;
@@ -2220,31 +2789,93 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
}
}
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;
+ if (source[KEYED]) {
+ this.mergeKeyed(target, source);
+ } else {
+ for (const key in source) {
+ const val = source[key];
+ const targetVal = target[key];
+ const isObjVal = isObject(val);
+ if (isObjVal && val[STATIC] === void 0 && isObject(targetVal)) {
+ this.doMutableMerge(targetVal, val);
+ } else {
+ target[key] = val;
+ }
}
}
+ if (target[ROOT]) {
+ target.newRender = true;
+ }
}
- 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);
+ clone(diff) {
+ if ("structuredClone" in window) {
+ return structuredClone(diff);
+ } else {
+ return JSON.parse(JSON.stringify(diff));
+ }
+ }
+ mergeKeyed(target, source) {
+ const clonedTarget = this.clone(target);
+ Object.entries(source[KEYED]).forEach(([i, entry]) => {
+ if (i === KEYED_COUNT) {
+ return;
+ }
+ if (Array.isArray(entry)) {
+ const [old_idx, diff] = entry;
+ target[KEYED][i] = clonedTarget[KEYED][old_idx];
+ this.doMutableMerge(target[KEYED][i], diff);
+ } else if (typeof entry === "number") {
+ const old_idx = entry;
+ target[KEYED][i] = clonedTarget[KEYED][old_idx];
+ } else if (typeof entry === "object") {
+ if (!target[KEYED][i]) {
+ target[KEYED][i] = {};
+ }
+ this.doMutableMerge(target[KEYED][i], entry);
+ }
+ });
+ if (source[KEYED][KEYED_COUNT] < target[KEYED][KEYED_COUNT]) {
+ for (let i = source[KEYED][KEYED_COUNT]; i < target[KEYED][KEYED_COUNT]; i++) {
+ delete target[KEYED][i];
}
}
+ target[KEYED][KEYED_COUNT] = source[KEYED][KEYED_COUNT];
+ if (source[STREAM]) {
+ target[STREAM] = source[STREAM];
+ }
+ if (source[TEMPLATES]) {
+ target[TEMPLATES] = source[TEMPLATES];
+ }
+ }
+ cloneMerge(target, source, pruneMagicId) {
+ let merged;
+ if (source[KEYED]) {
+ merged = this.clone(target);
+ this.mergeKeyed(merged, source);
+ } else {
+ merged = __spreadValues(__spreadValues({}, target), source);
+ for (const key in merged) {
+ const val = source[key];
+ const targetVal = target[key];
+ if (isObject(val) && val[STATIC] === void 0 && isObject(targetVal)) {
+ merged[key] = this.cloneMerge(targetVal, val, pruneMagicId);
+ } else if (val === void 0 && isObject(targetVal)) {
+ merged[key] = this.cloneMerge(targetVal, {}, pruneMagicId);
+ }
+ }
+ }
+ if (pruneMagicId) {
+ delete merged.magicId;
+ delete merged.newRender;
+ } else if (target[ROOT]) {
+ merged.newRender = true;
+ }
return merged;
}
componentToString(cid) {
- let [str, streams] = this.recursiveCIDToString(this.rendered[COMPONENTS], cid, null, false);
- return [str, streams];
+ const { buffer: str, streams } = this.recursiveCIDToString(this.rendered[COMPONENTS], cid, null);
+ const [strippedHTML, _before, _after] = modifyRoot(str, {});
+ return { buffer: strippedHTML, streams };
}
pruneCIDs(cids) {
cids.forEach((cid) => delete this.rendered[COMPONENTS][cid]);
@@ -2262,222 +2893,169 @@ removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
return part;
}
}
- toOutputBuffer(rendered, templates, output) {
- if (rendered[DYNAMICS]) {
- return this.comprehensionToBuffer(rendered, templates, output);
+ nextMagicID() {
+ this.magicId++;
+ return `m${this.magicId}-${this.parentViewId()}`;
+ }
+ toOutputBuffer(rendered, templates, output, changeTracking, rootAttrs = {}) {
+ if (rendered[KEYED]) {
+ return this.comprehensionToBuffer(rendered, templates, output, changeTracking);
+ }
+ if (rendered[TEMPLATES]) {
+ templates = rendered[TEMPLATES];
+ delete rendered[TEMPLATES];
}
let { [STATIC]: statics } = rendered;
statics = this.templateStatic(statics, templates);
+ rendered[STATIC] = statics;
+ const isRoot = rendered[ROOT];
+ const prevBuffer = output.buffer;
+ if (isRoot) {
+ output.buffer = "";
+ }
+ if (changeTracking && isRoot && !rendered.magicId) {
+ rendered.newRender = true;
+ rendered.magicId = this.nextMagicID();
+ }
output.buffer += statics[0];
for (let i = 1; i < statics.length; i++) {
- this.dynamicToBuffer(rendered[i - 1], templates, output);
+ this.dynamicToBuffer(rendered[i - 1], templates, output, changeTracking);
output.buffer += statics[i];
}
+ if (isRoot) {
+ let skip = false;
+ let attrs;
+ if (changeTracking || rendered.magicId) {
+ skip = changeTracking && !rendered.newRender;
+ attrs = __spreadValues({ [PHX_MAGIC_ID]: rendered.magicId }, rootAttrs);
+ } else {
+ attrs = rootAttrs;
+ }
+ if (skip) {
+ attrs[PHX_SKIP] = true;
+ }
+ const [newRoot, commentBefore, commentAfter] = modifyRoot(output.buffer, attrs, skip);
+ rendered.newRender = false;
+ output.buffer = prevBuffer + commentBefore + newRoot + commentAfter;
+ }
}
- 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];
+ comprehensionToBuffer(rendered, templates, output, changeTracking) {
+ const keyedTemplates = templates || rendered[TEMPLATES];
+ const statics = this.templateStatic(rendered[STATIC], templates);
+ rendered[STATIC] = statics;
+ delete rendered[TEMPLATES];
+ for (let i = 0; i < rendered[KEYED][KEYED_COUNT]; i++) {
output.buffer += statics[0];
- for (let i = 1; i < statics.length; i++) {
- this.dynamicToBuffer(dynamic[i - 1], compTemplates, output);
- output.buffer += statics[i];
+ for (let j = 1; j < statics.length; j++) {
+ this.dynamicToBuffer(rendered[KEYED][i][j - 1], keyedTemplates, output, changeTracking);
+ output.buffer += statics[j];
+ }
+ }
+ if (rendered[STREAM]) {
+ const stream = rendered[STREAM];
+ const [_ref, _inserts, deleteIds, reset] = stream || [null, {}, [], null];
+ if (stream !== void 0 && (rendered[KEYED][KEYED_COUNT] > 0 || deleteIds.length > 0 || reset)) {
+ delete rendered[STREAM];
+ rendered[KEYED] = {
+ [KEYED_COUNT]: 0
+ };
+ output.streams.add(stream);
}
}
- 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) {
+ dynamicToBuffer(rendered, templates, output, changeTracking) {
if (typeof rendered === "number") {
- let [str, streams] = this.recursiveCIDToString(output.components, rendered, output.onlyCids);
+ const { buffer: str, streams } = this.recursiveCIDToString(output.components, rendered, output.onlyCids);
output.buffer += str;
- output.streams = new Set([...output.streams, ...streams]);
+ output.streams = /* @__PURE__ */ new Set([...output.streams, ...streams]);
} else if (isObject(rendered)) {
- this.toOutputBuffer(rendered, templates, output);
+ this.toOutputBuffer(rendered, templates, output, changeTracking, {});
} 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 = 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));
+ recursiveCIDToString(components, cid, onlyCids) {
+ const component = components[cid] || logError(`no component for CID ${cid}`, components);
+ const attrs = { [PHX_COMPONENT]: cid, [PHX_VIEW_REF]: this.viewId };
+ const skip = onlyCids && !onlyCids.has(cid);
+ component.newRender = !skip;
+ component.magicId = `c${cid}-${this.parentViewId()}`;
+ const changeTracking = !component.reset;
+ const { buffer: html, streams } = this.recursiveToString(component, components, onlyCids, changeTracking, attrs);
+ delete component.reset;
+ return { buffer: html, streams };
}
};
- var focusStack = null;
+ var focusStack = [];
+ var default_transition_time = 200;
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]];
+ exec(e, eventType, phxEvent, view, sourceEl, defaults) {
+ const [defaultKind, defaultArgs] = defaults || [
+ null,
+ { callback: defaults && defaults.callback }
+ ];
+ const 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);
+ if (kind === defaultKind) {
+ args = __spreadValues(__spreadValues({}, defaultArgs), args);
args.callback = args.callback || defaultArgs.callback;
}
- this.filterToEls(sourceEl, args).forEach((el) => {
- this[`exec_${kind}`](eventType, phxEvent, view, sourceEl, el, args);
+ this.filterToEls(view.liveSocket, sourceEl, args).forEach((el) => {
+ this[`exec_${kind}`](e, 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);
- });
+ isInViewport(el) {
+ const rect = el.getBoundingClientRect();
+ const windowHeight = window.innerHeight || document.documentElement.clientHeight;
+ const windowWidth = window.innerWidth || document.documentElement.clientWidth;
+ return rect.right > 0 && rect.bottom > 0 && rect.left < windowWidth && rect.top < windowHeight;
+ },
+ exec_exec(e, eventType, phxEvent, view, sourceEl, el, { attr, to }) {
+ const encodedJS = el.getAttribute(attr);
+ if (!encodedJS) {
+ throw new Error(`expected ${attr} to contain JS command on "${to}"`);
+ }
+ view.liveSocket.execJS(el, encodedJS, eventType);
},
- exec_dispatch(eventType, phxEvent, view, sourceEl, el, { to, event, detail, bubbles }) {
+ exec_dispatch(e, eventType, phxEvent, view, sourceEl, el, { event, detail, bubbles, blocking }) {
detail = detail || {};
detail.dispatcher = sourceEl;
+ if (blocking) {
+ const promise = new Promise((resolve, _reject) => {
+ detail.done = resolve;
+ });
+ view.liveSocket.asyncTransition(promise);
+ }
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) => {
+ exec_push(e, eventType, phxEvent, view, sourceEl, el, args) {
+ const {
+ event,
+ data,
+ target,
+ page_loading,
+ loading,
+ value,
+ dispatcher,
+ callback
+ } = args;
+ const pushOpts = {
+ loading,
+ value,
+ target,
+ page_loading: !!page_loading,
+ originalEvent: e
+ };
+ const targetSrc = eventType === "change" && dispatcher ? dispatcher : sourceEl;
+ const phxTarget = target || targetSrc.getAttribute(view.binding("target")) || targetSrc;
+ const handler = (targetView, targetCtx) => {
+ if (!targetView.isConnected()) {
+ return;
+ }
if (eventType === "change") {
let { newCid, _target } = args;
_target = _target || (dom_default.isFormInput(sourceEl) ? sourceEl.name : void 0);
@@ -2486,106 +3064,159 @@ within:
}
targetView.pushInput(sourceEl, targetCtx, newCid, event || phxEvent, pushOpts, callback);
} else if (eventType === "submit") {
- let { submitter } = args;
+ const { submitter } = args;
targetView.submitForm(sourceEl, targetCtx, event || phxEvent, submitter, pushOpts, callback);
} else {
targetView.pushEvent(eventType, sourceEl, targetCtx, event || phxEvent, data, pushOpts, callback);
}
+ };
+ if (args.targetView && args.targetCtx) {
+ handler(args.targetView, args.targetCtx);
+ } else {
+ view.withinTargets(phxTarget, handler);
+ }
+ },
+ exec_navigate(e, eventType, phxEvent, view, sourceEl, el, { href, replace }) {
+ view.liveSocket.historyRedirect(e, href, replace ? "replace" : "push", null, sourceEl);
+ },
+ exec_patch(e, eventType, phxEvent, view, sourceEl, el, { href, replace }) {
+ view.liveSocket.pushHistoryPatch(e, href, replace ? "replace" : "push", sourceEl);
+ },
+ exec_focus(e, eventType, phxEvent, view, sourceEl, el) {
+ aria_default.attemptFocus(el);
+ window.requestAnimationFrame(() => {
+ window.requestAnimationFrame(() => aria_default.attemptFocus(el));
});
},
- exec_navigate(eventType, phxEvent, view, sourceEl, el, { href, replace }) {
- view.liveSocket.historyRedirect(href, replace ? "replace" : "push");
+ exec_focus_first(e, eventType, phxEvent, view, sourceEl, el) {
+ aria_default.focusFirstInteractive(el) || aria_default.focusFirst(el);
+ window.requestAnimationFrame(() => {
+ window.requestAnimationFrame(() => aria_default.focusFirstInteractive(el) || aria_default.focusFirst(el));
+ });
},
- exec_patch(eventType, phxEvent, view, sourceEl, el, { href, replace }) {
- view.liveSocket.pushHistoryPatch(href, replace ? "replace" : "push", sourceEl);
+ exec_push_focus(e, eventType, phxEvent, view, sourceEl, el) {
+ focusStack.push(el || sourceEl);
},
- exec_focus(eventType, phxEvent, view, sourceEl, el) {
- window.requestAnimationFrame(() => aria_default.attemptFocus(el));
+ exec_pop_focus(_e, _eventType, _phxEvent, _view, _sourceEl, _el) {
+ const el = focusStack.pop();
+ if (el) {
+ el.focus();
+ window.requestAnimationFrame(() => {
+ window.requestAnimationFrame(() => el.focus());
+ });
+ }
},
- exec_focus_first(eventType, phxEvent, view, sourceEl, el) {
- window.requestAnimationFrame(() => aria_default.focusFirstInteractive(el) || aria_default.focusFirst(el));
+ exec_add_class(e, eventType, phxEvent, view, sourceEl, el, { names, transition, time, blocking }) {
+ this.addOrRemoveClasses(el, names, [], transition, time, view, blocking);
},
- exec_push_focus(eventType, phxEvent, view, sourceEl, el) {
- window.requestAnimationFrame(() => focusStack = el || sourceEl);
+ exec_remove_class(e, eventType, phxEvent, view, sourceEl, el, { names, transition, time, blocking }) {
+ this.addOrRemoveClasses(el, [], names, transition, time, view, blocking);
},
- exec_pop_focus(eventType, phxEvent, view, sourceEl, el) {
- window.requestAnimationFrame(() => {
- if (focusStack) {
- focusStack.focus();
- }
- focusStack = null;
- });
+ exec_toggle_class(e, eventType, phxEvent, view, sourceEl, el, { names, transition, time, blocking }) {
+ this.toggleClasses(el, names, transition, time, view, blocking);
},
- exec_add_class(eventType, phxEvent, view, sourceEl, el, { names, transition, time }) {
- this.addOrRemoveClasses(el, names, [], transition, time, view);
+ exec_toggle_attr(e, eventType, phxEvent, view, sourceEl, el, { attr: [attr, val1, val2] }) {
+ this.toggleAttr(el, attr, val1, val2);
},
- exec_remove_class(eventType, phxEvent, view, sourceEl, el, { names, transition, time }) {
- this.addOrRemoveClasses(el, [], names, transition, time, view);
+ exec_ignore_attrs(e, eventType, phxEvent, view, sourceEl, el, { attrs }) {
+ this.ignoreAttrs(el, attrs);
},
- exec_transition(eventType, phxEvent, view, sourceEl, el, { time, transition }) {
- this.addOrRemoveClasses(el, [], [], transition, time, view);
+ exec_transition(e, eventType, phxEvent, view, sourceEl, el, { time, transition, blocking }) {
+ this.addOrRemoveClasses(el, [], [], transition, time, view, blocking);
},
- exec_toggle(eventType, phxEvent, view, sourceEl, el, { display, ins, outs, time }) {
- this.toggle(eventType, view, el, display, ins, outs, time);
+ exec_toggle(e, eventType, phxEvent, view, sourceEl, el, { display, ins, outs, time, blocking }) {
+ this.toggle(eventType, view, el, display, ins, outs, time, blocking);
},
- exec_show(eventType, phxEvent, view, sourceEl, el, { display, transition, time }) {
- this.show(eventType, view, el, display, transition, time);
+ exec_show(e, eventType, phxEvent, view, sourceEl, el, { display, transition, time, blocking }) {
+ this.show(eventType, view, el, display, transition, time, blocking);
},
- exec_hide(eventType, phxEvent, view, sourceEl, el, { display, transition, time }) {
- this.hide(eventType, view, el, display, transition, time);
+ exec_hide(e, eventType, phxEvent, view, sourceEl, el, { display, transition, time, blocking }) {
+ this.hide(eventType, view, el, display, transition, time, blocking);
},
- exec_set_attr(eventType, phxEvent, view, sourceEl, el, { attr: [attr, val] }) {
+ exec_set_attr(e, eventType, phxEvent, view, sourceEl, el, { attr: [attr, val] }) {
this.setOrRemoveAttrs(el, [[attr, val]], []);
},
- exec_remove_attr(eventType, phxEvent, view, sourceEl, el, { attr }) {
+ exec_remove_attr(e, eventType, phxEvent, view, sourceEl, el, { attr }) {
this.setOrRemoveAttrs(el, [], [attr]);
},
- show(eventType, view, el, display, transition, time) {
+ ignoreAttrs(el, attrs) {
+ dom_default.putPrivate(el, "JS:ignore_attrs", {
+ apply: (fromEl, toEl) => {
+ Array.from(fromEl.attributes).forEach((attr) => {
+ if (attrs.some((toIgnore) => attr.name == toIgnore || toIgnore === "*" || toIgnore.includes("*") && attr.name.match(toIgnore) != null)) {
+ toEl.setAttribute(attr.name, attr.value);
+ }
+ });
+ }
+ });
+ },
+ onBeforeElUpdated(fromEl, toEl) {
+ const ignoreAttrs = dom_default.private(fromEl, "JS:ignore_attrs");
+ if (ignoreAttrs) {
+ ignoreAttrs.apply(fromEl, toEl);
+ }
+ },
+ show(eventType, view, el, display, transition, time, blocking) {
if (!this.isVisible(el)) {
- this.toggle(eventType, view, el, display, transition, null, time);
+ this.toggle(eventType, view, el, display, transition, null, time, blocking);
}
},
- hide(eventType, view, el, display, transition, time) {
+ hide(eventType, view, el, display, transition, time, blocking) {
if (this.isVisible(el)) {
- this.toggle(eventType, view, el, display, null, transition, time);
+ this.toggle(eventType, view, el, display, null, transition, time, blocking);
}
},
- toggle(eventType, view, el, display, ins, outs, time) {
- let [inClasses, inStartClasses, inEndClasses] = ins || [[], [], []];
- let [outClasses, outStartClasses, outEndClasses] = outs || [[], [], []];
+ toggle(eventType, view, el, display, ins, outs, time, blocking) {
+ time = time || default_transition_time;
+ const [inClasses, inStartClasses, inEndClasses] = ins || [[], [], []];
+ const [outClasses, outStartClasses, outEndClasses] = outs || [[], [], []];
if (inClasses.length > 0 || outClasses.length > 0) {
if (this.isVisible(el)) {
- let onStart = () => {
+ const 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, () => {
+ const onEnd = () => {
this.addOrRemoveClasses(el, [], outClasses.concat(outEndClasses));
dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = "none");
el.dispatchEvent(new Event("phx:hide-end"));
- });
+ };
+ el.dispatchEvent(new Event("phx:hide-start"));
+ if (blocking === false) {
+ onStart();
+ setTimeout(onEnd, time);
+ } else {
+ view.transition(time, onStart, onEnd);
+ }
} else {
if (eventType === "remove") {
return;
}
- let onStart = () => {
+ const 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);
+ const stickyDisplay = display || this.defaultDisplay(el);
window.requestAnimationFrame(() => {
this.addOrRemoveClasses(el, inClasses, []);
- window.requestAnimationFrame(() => this.addOrRemoveClasses(el, inEndClasses, inStartClasses));
+ window.requestAnimationFrame(() => {
+ dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = stickyDisplay);
+ this.addOrRemoveClasses(el, inEndClasses, inStartClasses);
+ });
});
};
- el.dispatchEvent(new Event("phx:show-start"));
- view.transition(time, onStart, () => {
+ const onEnd = () => {
this.addOrRemoveClasses(el, [], inClasses.concat(inEndClasses));
el.dispatchEvent(new Event("phx:show-end"));
- });
+ };
+ el.dispatchEvent(new Event("phx:show-start"));
+ if (blocking === false) {
+ onStart();
+ setTimeout(onEnd, time);
+ } else {
+ view.transition(time, onStart, onEnd);
+ }
}
} else {
if (this.isVisible(el)) {
@@ -2597,32 +3228,66 @@ within:
} else {
window.requestAnimationFrame(() => {
el.dispatchEvent(new Event("phx:show-start"));
- let stickyDisplay = display || this.defaultDisplay(el);
+ const 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 || [[], [], []];
+ toggleClasses(el, classes, transition, time, view, blocking) {
+ window.requestAnimationFrame(() => {
+ const [prevAdds, prevRemoves] = dom_default.getSticky(el, "classes", [[], []]);
+ const newAdds = classes.filter((name) => prevAdds.indexOf(name) < 0 && !el.classList.contains(name));
+ const newRemoves = classes.filter((name) => prevRemoves.indexOf(name) < 0 && el.classList.contains(name));
+ this.addOrRemoveClasses(el, newAdds, newRemoves, transition, time, view, blocking);
+ });
+ },
+ toggleAttr(el, attr, val1, val2) {
+ if (el.hasAttribute(attr)) {
+ if (val2 !== void 0) {
+ if (el.getAttribute(attr) === val1) {
+ this.setOrRemoveAttrs(el, [[attr, val2]], []);
+ } else {
+ this.setOrRemoveAttrs(el, [[attr, val1]], []);
+ }
+ } else {
+ this.setOrRemoveAttrs(el, [], [attr]);
+ }
+ } else {
+ this.setOrRemoveAttrs(el, [[attr, val1]], []);
+ }
+ },
+ addOrRemoveClasses(el, adds, removes, transition, time, view, blocking) {
+ time = time || default_transition_time;
+ const [transitionRun, transitionStart, transitionEnd] = transition || [
+ [],
+ [],
+ []
+ ];
if (transitionRun.length > 0) {
- let onStart = () => {
+ const 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);
+ const onDone = () => this.addOrRemoveClasses(el, adds.concat(transitionEnd), removes.concat(transitionRun).concat(transitionStart));
+ if (blocking === false) {
+ onStart();
+ setTimeout(onDone, time);
+ } else {
+ view.transition(time, onStart, onDone);
+ }
+ return;
}
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);
+ const [prevAdds, prevRemoves] = dom_default.getSticky(el, "classes", [[], []]);
+ const keepAdds = adds.filter((name) => prevAdds.indexOf(name) < 0 && !el.classList.contains(name));
+ const keepRemoves = removes.filter((name) => prevRemoves.indexOf(name) < 0 && el.classList.contains(name));
+ const newAdds = prevAdds.filter((name) => removes.indexOf(name) < 0).concat(keepAdds);
+ const newRemoves = prevRemoves.filter((name) => adds.indexOf(name) < 0).concat(keepRemoves);
dom_default.putSticky(el, "classes", (currentEl) => {
currentEl.classList.remove(...newRemoves);
currentEl.classList.add(...newAdds);
@@ -2631,10 +3296,10 @@ within:
});
},
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);
+ const [prevSets, prevRemoves] = dom_default.getSticky(el, "attrs", [[], []]);
+ const alteredAttrs = sets.map(([attr, _val]) => attr).concat(removes);
+ const newSets = prevSets.filter(([attr, _val]) => !alteredAttrs.includes(attr)).concat(sets);
+ const 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));
@@ -2647,39 +3312,340 @@ within:
isToggledOut(el, outClasses) {
return !this.isVisible(el) || this.hasAllClasses(el, outClasses);
},
- filterToEls(sourceEl, { to }) {
- return to ? dom_default.all(document, to) : [sourceEl];
+ filterToEls(liveSocket2, sourceEl, { to }) {
+ const defaultQuery = () => {
+ if (typeof to === "string") {
+ return document.querySelectorAll(to);
+ } else if (to.closest) {
+ const toEl = sourceEl.closest(to.closest);
+ return toEl ? [toEl] : [];
+ } else if (to.inner) {
+ return sourceEl.querySelectorAll(to.inner);
+ }
+ };
+ return to ? liveSocket2.jsQuerySelectorAll(sourceEl, to, defaultQuery) : [sourceEl];
},
defaultDisplay(el) {
return { tr: "table-row", td: "table-cell" }[el.tagName.toLowerCase()] || "block";
+ },
+ transitionClasses(val) {
+ if (!val) {
+ return null;
+ }
+ let [trans, tStart, tEnd] = Array.isArray(val) ? val : [val.split(" "), [], []];
+ trans = Array.isArray(trans) ? trans : trans.split(" ");
+ tStart = Array.isArray(tStart) ? tStart : tStart.split(" ");
+ tEnd = Array.isArray(tEnd) ? tEnd : tEnd.split(" ");
+ return [trans, tStart, tEnd];
}
};
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);
+ var js_commands_default = (liveSocket2, eventType) => {
+ return {
+ exec(el, encodedJS) {
+ liveSocket2.execJS(el, encodedJS, eventType);
+ },
+ show(el, opts = {}) {
+ const owner = liveSocket2.owner(el);
+ js_default.show(eventType, owner, el, opts.display, js_default.transitionClasses(opts.transition), opts.time, opts.blocking);
+ },
+ hide(el, opts = {}) {
+ const owner = liveSocket2.owner(el);
+ js_default.hide(eventType, owner, el, null, js_default.transitionClasses(opts.transition), opts.time, opts.blocking);
+ },
+ toggle(el, opts = {}) {
+ const owner = liveSocket2.owner(el);
+ const inTransition = js_default.transitionClasses(opts.in);
+ const outTransition = js_default.transitionClasses(opts.out);
+ js_default.toggle(eventType, owner, el, opts.display, inTransition, outTransition, opts.time, opts.blocking);
+ },
+ addClass(el, names, opts = {}) {
+ const classNames = Array.isArray(names) ? names : names.split(" ");
+ const owner = liveSocket2.owner(el);
+ js_default.addOrRemoveClasses(el, classNames, [], js_default.transitionClasses(opts.transition), opts.time, owner, opts.blocking);
+ },
+ removeClass(el, names, opts = {}) {
+ const classNames = Array.isArray(names) ? names : names.split(" ");
+ const owner = liveSocket2.owner(el);
+ js_default.addOrRemoveClasses(el, [], classNames, js_default.transitionClasses(opts.transition), opts.time, owner, opts.blocking);
+ },
+ toggleClass(el, names, opts = {}) {
+ const classNames = Array.isArray(names) ? names : names.split(" ");
+ const owner = liveSocket2.owner(el);
+ js_default.toggleClasses(el, classNames, js_default.transitionClasses(opts.transition), opts.time, owner, opts.blocking);
+ },
+ transition(el, transition, opts = {}) {
+ const owner = liveSocket2.owner(el);
+ js_default.addOrRemoveClasses(el, [], [], js_default.transitionClasses(transition), opts.time, owner, opts.blocking);
+ },
+ setAttribute(el, attr, val) {
+ js_default.setOrRemoveAttrs(el, [[attr, val]], []);
+ },
+ removeAttribute(el, attr) {
+ js_default.setOrRemoveAttrs(el, [], [attr]);
+ },
+ toggleAttribute(el, attr, val1, val2) {
+ js_default.toggleAttr(el, attr, val1, val2);
+ },
+ push(el, type, opts = {}) {
+ liveSocket2.withinOwners(el, (view) => {
+ const data = opts.value || {};
+ delete opts.value;
+ let e = new CustomEvent("phx:exec", { detail: { sourceElement: el } });
+ js_default.exec(e, eventType, type, view, el, ["push", __spreadValues({ data }, opts)]);
+ });
+ },
+ navigate(href, opts = {}) {
+ const customEvent = new CustomEvent("phx:exec");
+ liveSocket2.historyRedirect(customEvent, href, opts.replace ? "replace" : "push", null, null);
+ },
+ patch(href, opts = {}) {
+ const customEvent = new CustomEvent("phx:exec");
+ liveSocket2.pushHistoryPatch(customEvent, href, opts.replace ? "replace" : "push", null);
+ },
+ ignoreAttributes(el, attrs) {
+ js_default.ignoreAttrs(el, Array.isArray(attrs) ? attrs : [attrs]);
+ }
+ };
+ };
+ var HOOK_ID = "hookId";
+ var viewHookID = 1;
+ var ViewHook = class _ViewHook {
+ static makeID() {
+ return viewHookID++;
+ }
+ static elementID(el) {
+ return dom_default.private(el, HOOK_ID);
+ }
+ constructor(view, el, callbacks) {
+ this.el = el;
+ this.__attachView(view);
+ this.__listeners = /* @__PURE__ */ new Set();
+ this.__isDisconnected = false;
+ dom_default.putPrivate(this.el, HOOK_ID, _ViewHook.makeID());
+ if (callbacks) {
+ const protectedProps = /* @__PURE__ */ new Set([
+ "el",
+ "liveSocket",
+ "__view",
+ "__listeners",
+ "__isDisconnected",
+ "constructor",
+ "js",
+ "pushEvent",
+ "pushEventTo",
+ "handleEvent",
+ "removeHandleEvent",
+ "upload",
+ "uploadTo",
+ "__mounted",
+ "__updated",
+ "__beforeUpdate",
+ "__destroyed",
+ "__reconnected",
+ "__disconnected",
+ "__cleanup__"
+ ]);
+ for (const key in callbacks) {
+ if (Object.prototype.hasOwnProperty.call(callbacks, key)) {
+ this[key] = callbacks[key];
+ if (protectedProps.has(key)) {
+ console.warn(`Hook object for element #${el.id} overwrites core property '${key}'!`);
+ }
+ }
+ }
+ const lifecycleMethods = [
+ "mounted",
+ "beforeUpdate",
+ "updated",
+ "destroyed",
+ "disconnected",
+ "reconnected"
+ ];
+ lifecycleMethods.forEach((methodName) => {
+ if (callbacks[methodName] && typeof callbacks[methodName] === "function") {
+ this[methodName] = callbacks[methodName];
+ }
+ });
+ }
+ }
+ __attachView(view) {
+ if (view) {
+ this.__view = () => view;
+ this.liveSocket = view.liveSocket;
+ } else {
+ this.__view = () => {
+ throw new Error(`hook not yet attached to a live view: ${this.el.outerHTML}`);
+ };
+ this.liveSocket = null;
+ }
+ }
+ mounted() {
+ }
+ beforeUpdate() {
+ }
+ updated() {
+ }
+ destroyed() {
+ }
+ disconnected() {
+ }
+ reconnected() {
+ }
+ __mounted() {
+ this.mounted();
+ }
+ __updated() {
+ this.updated();
+ }
+ __beforeUpdate() {
+ this.beforeUpdate();
+ }
+ __destroyed() {
+ this.destroyed();
+ dom_default.deletePrivate(this.el, HOOK_ID);
+ }
+ __reconnected() {
+ if (this.__isDisconnected) {
+ this.__isDisconnected = false;
+ this.reconnected();
+ }
+ }
+ __disconnected() {
+ this.__isDisconnected = true;
+ this.disconnected();
+ }
+ js() {
+ return __spreadProps(__spreadValues({}, js_commands_default(this.__view().liveSocket, "hook")), {
+ exec: (encodedJS) => {
+ this.__view().liveSocket.execJS(this.el, encodedJS, "hook");
+ }
+ });
+ }
+ pushEvent(event, payload, onReply) {
+ const promise = this.__view().pushHookEvent(this.el, null, event, payload || {});
+ if (onReply === void 0) {
+ return promise.then(({ reply }) => reply);
+ }
+ promise.then(({ reply, ref }) => onReply(reply, ref)).catch(() => {
+ });
+ return;
+ }
+ pushEventTo(selectorOrTarget, event, payload, onReply) {
+ if (onReply === void 0) {
+ const targetPair = [];
+ this.__view().withinTargets(selectorOrTarget, (view, targetCtx) => {
+ targetPair.push({ view, targetCtx });
+ });
+ const promises = targetPair.map(({ view, targetCtx }) => {
+ return view.pushHookEvent(this.el, targetCtx, event, payload || {});
+ });
+ return Promise.allSettled(promises);
+ }
+ this.__view().withinTargets(selectorOrTarget, (view, targetCtx) => {
+ view.pushHookEvent(this.el, targetCtx, event, payload || {}).then(({ reply, ref }) => onReply(reply, ref)).catch(() => {
+ });
+ });
+ return;
+ }
+ handleEvent(event, callback) {
+ const callbackRef = {
+ event,
+ callback: (customEvent) => callback(customEvent.detail)
+ };
+ window.addEventListener(`phx:${event}`, callbackRef.callback);
+ this.__listeners.add(callbackRef);
+ return callbackRef;
+ }
+ removeHandleEvent(ref) {
+ window.removeEventListener(`phx:${ref.event}`, ref.callback);
+ this.__listeners.delete(ref);
+ }
+ upload(name, files) {
+ return this.__view().dispatchUploads(null, name, files);
+ }
+ uploadTo(selectorOrTarget, name, files) {
+ return this.__view().withinTargets(selectorOrTarget, (view, targetCtx) => {
+ view.dispatchUploads(targetCtx, name, files);
+ });
+ }
+ __cleanup__() {
+ this.__listeners.forEach((callbackRef) => this.removeHandleEvent(callbackRef));
+ }
+ };
+ var prependFormDataKey = (key, prefix) => {
+ const isArray = key.endsWith("[]");
+ let baseKey = isArray ? key.slice(0, -2) : key;
+ baseKey = baseKey.replace(/([^\[\]]+)(\]?$)/, `${prefix}$1$2`);
+ if (isArray) {
+ baseKey += "[]";
+ }
+ return baseKey;
+ };
+ var serializeForm = (form, opts, onlyNames = []) => {
+ const { submitter } = opts;
+ let injectedElement;
+ if (submitter && submitter.name) {
+ const input = document.createElement("input");
+ input.type = "hidden";
+ const formId = submitter.getAttribute("form");
+ if (formId) {
+ input.setAttribute("form", formId);
+ }
+ input.name = submitter.name;
+ input.value = submitter.value;
+ submitter.parentElement.insertBefore(input, submitter);
+ injectedElement = input;
}
- let toRemove = [];
+ const formData = new FormData(form);
+ const 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()) {
+ const params = new URLSearchParams();
+ const { inputsUnused, onlyHiddenInputs } = Array.from(form.elements).reduce((acc, input) => {
+ const { inputsUnused: inputsUnused2, onlyHiddenInputs: onlyHiddenInputs2 } = acc;
+ const key = input.name;
+ if (!key) {
+ return acc;
+ }
+ if (inputsUnused2[key] === void 0) {
+ inputsUnused2[key] = true;
+ }
+ if (onlyHiddenInputs2[key] === void 0) {
+ onlyHiddenInputs2[key] = true;
+ }
+ const isUsed = dom_default.private(input, PHX_HAS_FOCUSED) || dom_default.private(input, PHX_HAS_SUBMITTED);
+ const isHidden = input.type === "hidden";
+ inputsUnused2[key] = inputsUnused2[key] && !isUsed;
+ onlyHiddenInputs2[key] = onlyHiddenInputs2[key] && isHidden;
+ return acc;
+ }, { inputsUnused: {}, onlyHiddenInputs: {} });
+ for (const [key, val] of formData.entries()) {
if (onlyNames.length === 0 || onlyNames.indexOf(key) >= 0) {
- params.append(key, val);
+ const isUnused = inputsUnused[key];
+ const hidden = onlyHiddenInputs[key];
+ if (isUnused && !(submitter && submitter.name == key) && !hidden) {
+ params.append(prependFormDataKey(key, "_unused_"), "");
+ }
+ if (typeof val === "string") {
+ params.append(key, val);
+ }
}
}
- for (let metaKey in meta) {
- params.append(metaKey, meta[metaKey]);
+ if (submitter && injectedElement) {
+ submitter.parentElement.removeChild(injectedElement);
}
return params.toString();
};
- var View = class {
+ var View = class _View {
+ static closestView(el) {
+ const liveViewEl = el.closest(PHX_VIEW_SELECTOR);
+ return liveViewEl ? dom_default.private(liveViewEl, "view") : null;
+ }
constructor(el, liveSocket2, parentView, flash, liveReferer) {
this.isDead = false;
this.liveSocket = liveSocket2;
@@ -2687,15 +3653,30 @@ within:
this.parent = parentView;
this.root = parentView ? parentView.root : this;
this.el = el;
+ const boundView = dom_default.private(this.el, "view");
+ if (boundView !== void 0 && boundView.isDead !== true) {
+ logError(`The DOM element for this view has already been bound to a view.
+
+ An element can only ever be associated with a single view!
+ Please ensure that you are not trying to initialize multiple LiveSockets on the same page.
+ This could happen if you're accidentally trying to render your root layout more than once.
+ Ensure that the template set on the LiveView is different than the root layout.
+ `, { view: boundView });
+ throw new Error("Cannot bind multiple views to the same DOM element.");
+ }
+ dom_default.putPrivate(this.el, "view", this);
this.id = this.el.id;
this.ref = 0;
+ this.lastAckRef = null;
this.childJoins = 0;
this.loaderTimer = null;
+ this.disconnectedTimer = null;
this.pendingDiffs = [];
- this.pruningCIDs = [];
+ this.pendingForms = /* @__PURE__ */ new Set();
this.redirect = false;
this.href = null;
this.joinCount = this.parent ? this.parent.joinCount - 1 : 0;
+ this.joinAttempts = 0;
this.joinPending = true;
this.destroyed = false;
this.joinCallback = function(onDone) {
@@ -2703,22 +3684,25 @@ within:
};
this.stopCallback = function() {
};
- this.pendingJoinOps = this.parent ? null : [];
+ this.pendingJoinOps = [];
this.viewHooks = {};
- this.uploaders = {};
this.formSubmits = [];
this.children = this.parent ? null : {};
this.root.children[this.id] = {};
+ this.formsForRecovery = {};
this.channel = this.liveSocket.channel(`lv:${this.id}`, () => {
+ const url = this.href && this.expandURL(this.href);
return {
- redirect: this.redirect ? this.href : void 0,
- url: this.redirect ? void 0 : this.href || void 0,
+ redirect: this.redirect ? url : void 0,
+ url: this.redirect ? void 0 : url || void 0,
params: this.connectParams(liveReferer),
session: this.getSession(),
static: this.getStatic(),
- flash: this.flash
+ flash: this.flash,
+ sticky: this.el.hasAttribute(PHX_STICKY)
};
});
+ this.portalElementIds = /* @__PURE__ */ new Set();
}
setHref(href) {
this.href = href;
@@ -2731,13 +3715,15 @@ within:
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");
+ const params = this.liveSocket.params(this.el);
+ const 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["_mount_attempts"] = this.joinAttempts;
params["_live_referer"] = liveReferer;
+ this.joinAttempts++;
return params;
}
isConnected() {
@@ -2747,21 +3733,23 @@ within:
return this.el.getAttribute(PHX_SESSION);
}
getStatic() {
- let val = this.el.getAttribute(PHX_STATIC);
+ const val = this.el.getAttribute(PHX_STATIC);
return val === "" ? null : val;
}
destroy(callback = function() {
}) {
this.destroyAllChildren();
+ this.destroyPortalElements();
this.destroyed = true;
+ dom_default.deletePrivate(this.el, "view");
delete this.root.children[this.id];
if (this.parent) {
delete this.root.children[this.parent.id][this.id];
}
clearTimeout(this.loaderTimer);
- let onFinished = () => {
+ const onFinished = () => {
callback();
- for (let id in this.viewHooks) {
+ for (const id in this.viewHooks) {
this.destroyHook(this.viewHooks[id]);
}
};
@@ -2778,7 +3766,7 @@ within:
if (timeout) {
this.loaderTimer = setTimeout(() => this.showLoader(), timeout);
} else {
- for (let id in this.viewHooks) {
+ for (const id in this.viewHooks) {
this.viewHooks[id].__disconnected();
}
this.setContainerClasses(PHX_LOADING_CLASS);
@@ -2789,11 +3777,12 @@ within:
}
hideLoader() {
clearTimeout(this.loaderTimer);
+ clearTimeout(this.disconnectedTimer);
this.setContainerClasses(PHX_CONNECTED_CLASS);
this.execAll(this.binding("connected"));
}
triggerReconnected() {
- for (let id in this.viewHooks) {
+ for (const id in this.viewHooks) {
this.viewHooks[id].__reconnected();
}
}
@@ -2804,19 +3793,19 @@ within:
}) {
this.liveSocket.transition(time, onStart, onDone);
}
- withinTargets(phxTarget, callback) {
+ withinTargets(phxTarget, callback, dom = document) {
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);
+ const targets = dom_default.findComponentNodeList(this.id, phxTarget, dom);
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));
+ const targets = Array.from(dom.querySelectorAll(phxTarget));
if (targets.length === 0) {
logError(`nothing found matching the phx-target selector "${phxTarget}"`);
}
@@ -2825,99 +3814,132 @@ within:
}
applyDiff(type, rawDiff, callback) {
this.log(type, () => ["", clone(rawDiff)]);
- let { diff, reply, events, title } = Rendered.extract(rawDiff);
+ const { diff, reply, events, title } = Rendered.extract(rawDiff);
callback({ diff, reply, events });
- if (title) {
+ if (typeof title === "string" || type == "mount" && this.isMain()) {
window.requestAnimationFrame(() => dom_default.putTitle(title));
}
}
onJoin(resp) {
- let { rendered, container } = resp;
+ const { rendered, container, liveview_version, pid } = resp;
if (container) {
- let [tag, attrs] = container;
+ const [tag, attrs] = container;
this.el = dom_default.replaceRootContainer(this.el, tag, attrs);
}
this.childJoins = 0;
this.joinPending = true;
this.flash = null;
+ if (this.root === this) {
+ this.formsForRecovery = this.getFormsForRecovery();
+ }
+ if (this.isMain() && window.history.state === null) {
+ browser_default.pushState("replace", {
+ type: "patch",
+ id: this.id,
+ position: this.liveSocket.currentHistoryPosition
+ });
+ }
+ if (liveview_version !== this.liveSocket.version()) {
+ console.error(`LiveView asset version mismatch. JavaScript version ${this.liveSocket.version()} vs. server ${liveview_version}. To avoid issues, please ensure that your assets use the same version as the server.`);
+ }
+ if (pid) {
+ this.el.setAttribute(PHX_LV_PID, pid);
+ }
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");
+ const [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.joinAttempts = 0;
+ this.maybeRecoverForms(html, () => {
this.onJoinComplete(resp, html, streams, events);
- }
+ });
});
}
dropPendingRefs() {
- dom_default.all(document, `[${PHX_REF_SRC}="${this.id}"][${PHX_REF}]`, (el) => {
- el.removeAttribute(PHX_REF);
+ dom_default.all(document, `[${PHX_REF_SRC}="${this.refSrc()}"]`, (el) => {
+ el.removeAttribute(PHX_REF_LOADING);
el.removeAttribute(PHX_REF_SRC);
+ el.removeAttribute(PHX_REF_LOCK);
});
}
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);
+ const newChildren = dom_default.findPhxChildrenInFragment(html, this.id).filter((toEl) => {
+ const fromEl = toEl.id && this.el.querySelector(`[id="${toEl.id}"]`);
+ const phxStatic = fromEl && fromEl.getAttribute(PHX_STATIC);
if (phxStatic) {
toEl.setAttribute(PHX_STATIC, phxStatic);
}
+ if (fromEl) {
+ fromEl.setAttribute(PHX_ROOT_ID, this.root.id);
+ }
return this.joinChild(toEl);
});
if (newChildren.length === 0) {
if (this.parent) {
- this.root.pendingJoinOps.push([this, () => this.applyJoinPatch(live_patch, html, streams, events)]);
+ 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)]);
+ 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() {
+ execNewMounted(parent = document) {
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.all(parent, `[${phxViewportTop}], [${phxViewportBottom}]`, (hookEl) => {
+ dom_default.maintainPrivateHooks(hookEl, hookEl, phxViewportTop, phxViewportBottom);
this.maybeAddNewHook(hookEl);
});
- dom_default.all(this.el, `[${this.binding(PHX_HOOK)}], [data-phx-${PHX_HOOK}]`, (hookEl) => {
+ this.all(parent, `[${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));
+ this.all(parent, `[${this.binding(PHX_MOUNTED)}]`, (el) => {
+ this.maybeMounted(el);
+ });
+ }
+ all(parent, selector, callback) {
+ dom_default.all(parent, selector, (el) => {
+ if (this.ownsElement(el)) {
+ callback(el);
+ }
+ });
}
applyJoinPatch(live_patch, html, streams, events) {
+ if (this.joinCount > 1) {
+ if (this.pendingJoinOps.length) {
+ this.pendingJoinOps.forEach((cb) => typeof cb === "function" && cb());
+ this.pendingJoinOps = [];
+ }
+ }
this.attachTrueDocEl();
- let patch = new DOMPatch(this, this.el, this.id, html, streams, null);
+ const patch = new DOMPatch(this, this.el, this.id, html, streams, null);
patch.markPrunableContentForRemoval();
- this.performPatch(patch, false);
+ this.performPatch(patch, false, true);
this.joinNewChildren();
this.execNewMounted();
this.joinPending = false;
this.liveSocket.dispatchEvents(events);
this.applyPendingUpdates();
if (live_patch) {
- let { kind, to } = live_patch;
+ const { kind, to } = live_patch;
this.liveSocket.historyPatch(to, kind);
}
this.hideLoader();
@@ -2928,33 +3950,37 @@ within:
}
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));
+ const hook = this.getHook(fromEl);
+ const 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");
+ const phxMounted = el.getAttribute(this.binding(PHX_MOUNTED));
+ const 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);
+ maybeAddNewHook(el) {
+ const newHook = this.addHook(el);
if (newHook) {
newHook.__mounted();
}
}
- performPatch(patch, pruneCids) {
- let removedEls = [];
+ performPatch(patch, pruneCids, isJoinPatch = false) {
+ const removedEls = [];
let phxChildrenAdded = false;
- let updatedHookIds = new Set();
+ const updatedHookIds = /* @__PURE__ */ new Set();
+ this.liveSocket.triggerDOM("onPatchStart", [patch.targetContainer]);
patch.after("added", (el) => {
this.liveSocket.triggerDOM("onNodeAdded", [el]);
+ const phxViewportTop = this.binding(PHX_VIEWPORT_TOP);
+ const phxViewportBottom = this.binding(PHX_VIEWPORT_BOTTOM);
+ dom_default.maintainPrivateHooks(el, el, phxViewportTop, phxViewportBottom);
this.maybeAddNewHook(el);
if (el.getAttribute) {
this.maybeMounted(el);
@@ -2968,10 +3994,11 @@ within:
}
});
patch.before("updated", (fromEl, toEl) => {
- let hook = this.triggerBeforeUpdateHook(fromEl, toEl);
+ const hook = this.triggerBeforeUpdateHook(fromEl, toEl);
if (hook) {
updatedHookIds.add(fromEl.id);
}
+ js_default.onBeforeElUpdated(fromEl, toEl);
});
patch.after("updated", (el) => {
if (updatedHookIds.has(el.id)) {
@@ -2984,23 +4011,24 @@ within:
}
});
patch.after("transitionsDiscarded", (els) => this.afterElementsRemoved(els, pruneCids));
- patch.perform();
+ patch.perform(isJoinPatch);
this.afterElementsRemoved(removedEls, pruneCids);
+ this.liveSocket.triggerDOM("onPatchEnd", [patch.targetContainer]);
return phxChildrenAdded;
}
afterElementsRemoved(elements, pruneCids) {
- let destroyedCIDs = [];
+ const destroyedCIDs = [];
elements.forEach((parent) => {
- let components = dom_default.all(parent, `[${PHX_COMPONENT}]`);
- let hooks = dom_default.all(parent, `[${this.binding(PHX_HOOK)}]`);
+ const components = dom_default.all(parent, `[${PHX_VIEW_REF}="${this.id}"][${PHX_COMPONENT}]`);
+ const hooks = dom_default.all(parent, `[${this.binding(PHX_HOOK)}], [data-phx-hook]`);
components.concat(parent).forEach((el) => {
- let cid = this.componentID(el);
- if (isCid(cid) && destroyedCIDs.indexOf(cid) === -1) {
+ const cid = this.componentID(el);
+ if (isCid(cid) && destroyedCIDs.indexOf(cid) === -1 && el.getAttribute(PHX_VIEW_REF) === this.id) {
destroyedCIDs.push(cid);
}
});
hooks.concat(parent).forEach((hookEl) => {
- let hook = this.getHook(hookEl);
+ const hook = this.getHook(hookEl);
hook && this.destroyHook(hook);
});
});
@@ -3009,21 +4037,52 @@ within:
}
}
joinNewChildren() {
- dom_default.findPhxChildren(this.el, this.id).forEach((el) => this.joinChild(el));
+ dom_default.findPhxChildren(document, this.id).forEach((el) => this.joinChild(el));
+ }
+ maybeRecoverForms(html, callback) {
+ const phxChange = this.binding("change");
+ const oldForms = this.root.formsForRecovery;
+ const template = document.createElement("template");
+ template.innerHTML = html;
+ dom_default.all(template.content, `[${PHX_PORTAL}]`).forEach((portalTemplate) => {
+ template.content.firstElementChild.appendChild(portalTemplate.content.firstElementChild);
+ });
+ const rootEl = template.content.firstElementChild;
+ rootEl.id = this.id;
+ rootEl.setAttribute(PHX_ROOT_ID, this.root.id);
+ rootEl.setAttribute(PHX_SESSION, this.getSession());
+ rootEl.setAttribute(PHX_STATIC, this.getStatic());
+ rootEl.setAttribute(PHX_PARENT_ID, this.parent ? this.parent.id : null);
+ const formsToRecover = dom_default.all(template.content, "form").filter((newForm) => newForm.id && oldForms[newForm.id]).filter((newForm) => !this.pendingForms.has(newForm.id)).filter((newForm) => oldForms[newForm.id].getAttribute(phxChange) === newForm.getAttribute(phxChange)).map((newForm) => {
+ return [oldForms[newForm.id], newForm];
+ });
+ if (formsToRecover.length === 0) {
+ return callback();
+ }
+ formsToRecover.forEach(([oldForm, newForm], i) => {
+ this.pendingForms.add(newForm.id);
+ this.pushFormRecovery(oldForm, newForm, template.content.firstElementChild, () => {
+ this.pendingForms.delete(newForm.id);
+ if (i === formsToRecover.length - 1) {
+ callback();
+ }
+ });
+ });
}
getChildById(id) {
return this.root.children[this.id][id];
}
getDescendentByEl(el) {
+ var _a;
if (el.id === this.id) {
return this;
} else {
- return this.children[el.getAttribute(PHX_PARENT_ID)][el.id];
+ return (_a = this.children[el.getAttribute(PHX_PARENT_ID)]) == null ? void 0 : _a[el.id];
}
}
destroyDescendent(id) {
- for (let parentId in this.root.children) {
- for (let childId in this.root.children[parentId]) {
+ for (const parentId in this.root.children) {
+ for (const childId in this.root.children[parentId]) {
if (childId === id) {
return this.root.children[parentId][childId].destroy();
}
@@ -3031,9 +4090,9 @@ within:
}
}
joinChild(el) {
- let child = this.getChildById(el.id);
+ const child = this.getChildById(el.id);
if (!child) {
- let view = new View(el, this.liveSocket, this);
+ const view = new _View(el, this.liveSocket, this);
this.root.children[this.id][view.id] = view;
view.join();
this.childJoins++;
@@ -3054,6 +4113,8 @@ within:
}
}
onAllChildJoinsComplete() {
+ this.pendingForms.clear();
+ this.formsForRecovery = {};
this.joinCallback(() => {
this.pendingJoinOps.forEach(([view, op]) => {
if (!view.isDestroyed()) {
@@ -3063,15 +4124,18 @@ within:
this.pendingJoinOps = [];
});
}
- update(diff, events) {
+ update(diff, events, isPending = false) {
if (this.isJoinPending() || this.liveSocket.hasPendingLink() && this.root.isMain()) {
- return this.pendingDiffs.push({ diff, events });
+ if (!isPending) {
+ this.pendingDiffs.push({ diff, events });
+ }
+ return false;
}
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));
+ const parentCids = dom_default.findExistingParentCIDs(this.id, this.rendered.componentCIDs(diff));
parentCids.forEach((parentCID) => {
if (this.componentPatch(this.rendered.getComponent(diff, parentCID), parentCID)) {
phxChildrenAdded = true;
@@ -3080,8 +4144,8 @@ within:
});
} 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);
+ const [html, streams] = this.renderContainer(diff, "update");
+ const patch = new DOMPatch(this, this.el, this.id, html, streams, null);
phxChildrenAdded = this.performPatch(patch, true);
});
}
@@ -3089,66 +4153,96 @@ within:
if (phxChildrenAdded) {
this.joinNewChildren();
}
+ return true;
}
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);
+ const tag = this.el.tagName;
+ const cids = diff ? this.rendered.componentCIDs(diff) : null;
+ const { buffer: html, streams } = this.rendered.toString(cids);
return [`<${tag}>${html}${tag}>`, 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);
+ const { buffer: html, streams } = this.rendered.componentToString(cid);
+ const patch = new DOMPatch(this, this.el, this.id, html, streams, cid);
+ const childrenAdded = this.performPatch(patch, true);
return childrenAdded;
}
getHook(el) {
return this.viewHooks[ViewHook.elementID(el)];
}
addHook(el) {
- if (ViewHook.elementID(el) || !el.getAttribute) {
+ const hookElId = ViewHook.elementID(el);
+ if (el.getAttribute && !this.ownsElement(el)) {
return;
}
- let hookName = el.getAttribute(`data-phx-${PHX_HOOK}`) || el.getAttribute(this.binding(PHX_HOOK));
- if (hookName && !this.ownsElement(el)) {
+ if (hookElId && !this.viewHooks[hookElId]) {
+ const hook = dom_default.getCustomElHook(el) || logError(`no hook found for custom element: ${el.id}`);
+ this.viewHooks[hookElId] = hook;
+ hook.__attachView(this);
+ return hook;
+ } else if (hookElId || !el.getAttribute) {
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);
+ } else {
+ const hookName = el.getAttribute(`data-phx-${PHX_HOOK}`) || el.getAttribute(this.binding(PHX_HOOK));
+ if (!hookName) {
+ return;
+ }
+ const hookDefinition = this.liveSocket.getHookDefinition(hookName);
+ if (hookDefinition) {
+ if (!el.id) {
+ logError(`no DOM ID for hook "${hookName}". Hooks require a unique ID on each element.`, el);
+ return;
+ }
+ let hookInstance;
+ try {
+ if (typeof hookDefinition === "function" && hookDefinition.prototype instanceof ViewHook) {
+ hookInstance = new hookDefinition(this, el);
+ } else if (typeof hookDefinition === "object" && hookDefinition !== null) {
+ hookInstance = new ViewHook(this, el, hookDefinition);
+ } else {
+ logError(`Invalid hook definition for "${hookName}". Expected a class extending ViewHook or an object definition.`, el);
+ return;
+ }
+ } catch (e) {
+ const errorMessage = e instanceof Error ? e.message : String(e);
+ logError(`Failed to create hook "${hookName}": ${errorMessage}`, el);
+ return;
+ }
+ this.viewHooks[ViewHook.elementID(hookInstance.el)] = hookInstance;
+ return hookInstance;
+ } else if (hookName !== null) {
+ logError(`unknown hook found for "${hookName}"`, 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) {
+ const hookId = ViewHook.elementID(hook.el);
hook.__destroyed();
hook.__cleanup__();
- delete this.viewHooks[ViewHook.elementID(hook.el)];
+ delete this.viewHooks[hookId];
}
applyPendingUpdates() {
- this.pendingDiffs.forEach(({ diff, events }) => this.update(diff, events));
- this.pendingDiffs = [];
+ this.pendingDiffs = this.pendingDiffs.filter(({ diff, events }) => !this.update(diff, events, true));
this.eachChild((child) => child.applyPendingUpdates());
}
eachChild(callback) {
- let children = this.root.children[this.id] || {};
- for (let id in children) {
+ const children = this.root.children[this.id] || {};
+ for (const 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)]);
+ if (this.joinCount > 1) {
+ this.pendingJoinOps.push(() => cb(resp));
+ } else {
+ this.root.pendingJoinOps.push([this, () => cb(resp)]);
+ }
} else {
this.liveSocket.requestDOMUpdate(() => cb(resp));
}
@@ -3170,20 +4264,23 @@ within:
this.eachChild((child) => child.destroy());
}
onLiveRedirect(redir) {
- let { to, kind, flash } = redir;
- let url = this.expandURL(to);
- this.liveSocket.historyRedirect(url, kind, flash);
+ const { to, kind, flash } = redir;
+ const url = this.expandURL(to);
+ const e = new CustomEvent("phx:server-navigate", {
+ detail: { to, kind, flash }
+ });
+ this.liveSocket.historyRedirect(e, url, kind, flash);
}
onLivePatch(redir) {
- let { to, kind } = redir;
+ const { 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);
+ onRedirect({ to, flash, reloadToken }) {
+ this.liveSocket.redirect(to, flash, reloadToken);
}
isDestroyed() {
return this.destroyed;
@@ -3191,37 +4288,44 @@ within:
joinDead() {
this.isDead = true;
}
+ joinPush() {
+ this.joinPush = this.joinPush || this.channel.join();
+ return this.joinPush;
+ }
join(callback) {
this.showLoader(this.liveSocket.loaderTimeout);
this.bindChannel();
if (this.isMain()) {
- this.stopCallback = this.liveSocket.withPageLoading({ to: this.href, kind: "initial" });
+ 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" }));
+ this.wrapPush(() => this.channel.join(), {
+ ok: (resp) => this.liveSocket.requestDOMUpdate(() => this.onJoin(resp)),
+ error: (error) => this.onJoinError(error),
+ timeout: () => 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 });
- }
+ this.log("error", () => [
+ `failed mount with ${resp.status}. Falling back to page reload`,
+ resp
+ ]);
+ this.onRedirect({ to: this.root.href, reloadToken: resp.token });
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 });
- }
+ this.log("error", () => [
+ "unauthorized live_redirect. Falling back to page request",
+ resp
+ ]);
+ this.onRedirect({ to: this.root.href, flash: this.flash });
return;
}
if (resp.redirect || resp.live_redirect) {
@@ -3234,24 +4338,40 @@ within:
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);
+ if (this.isMain()) {
+ this.displayError([PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS], { unstructuredError: resp, errorKind: "server" });
+ if (this.liveSocket.isConnected()) {
+ this.liveSocket.reloadWithJitter(this);
+ }
+ } else {
+ if (this.joinAttempts >= MAX_CHILD_JOIN_ATTEMPTS) {
+ this.root.displayError([PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS], { unstructuredError: resp, errorKind: "server" });
+ this.log("error", () => [
+ `giving up trying to mount after ${MAX_CHILD_JOIN_ATTEMPTS} tries`,
+ resp
+ ]);
+ this.destroy();
+ }
+ const trueChildEl = dom_default.byId(this.el.id);
+ if (trueChildEl) {
+ dom_default.mergeAttrs(trueChildEl, this.el);
+ this.displayError([PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS], { unstructuredError: resp, errorKind: "server" });
+ this.el = trueChildEl;
+ } else {
+ this.destroy();
+ }
}
}
onClose(reason) {
if (this.isDestroyed()) {
return;
}
- if (this.liveSocket.hasPendingLink() && reason !== "leave") {
+ if (this.isMain() && 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);
}
@@ -3263,133 +4383,239 @@ within:
}
if (!this.liveSocket.isUnloaded()) {
if (this.liveSocket.isConnected()) {
- this.displayError([PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS]);
+ this.displayError([PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS], { unstructuredError: reason, errorKind: "server" });
} else {
- this.displayError([PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_CLIENT_ERROR_CLASS]);
+ this.displayError([PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_CLIENT_ERROR_CLASS], { unstructuredError: reason, errorKind: "client" });
}
}
}
- displayError(classes) {
+ displayError(classes, details = {}) {
if (this.isMain()) {
- dom_default.dispatchEvent(window, "phx:page-loading-start", { detail: { to: this.href, kind: "error" } });
+ dom_default.dispatchEvent(window, "phx:page-loading-start", {
+ detail: __spreadValues({ to: this.href, kind: "error" }, details)
+ });
}
this.showLoader();
this.setContainerClasses(...classes);
- this.execAll(this.binding("disconnected"));
+ this.delayedDisconnected();
+ }
+ delayedDisconnected() {
+ this.disconnectedTimer = setTimeout(() => {
+ this.execAll(this.binding("disconnected"));
+ }, this.liveSocket.disconnectedTimeout);
+ }
+ wrapPush(callerPush, receives) {
+ const latency = this.liveSocket.getLatencySim();
+ const withLatency = latency ? (cb) => setTimeout(() => !this.isDestroyed() && cb(), latency) : (cb) => !this.isDestroyed() && cb();
+ withLatency(() => {
+ callerPush().receive("ok", (resp) => withLatency(() => receives.ok && receives.ok(resp))).receive("error", (reason) => withLatency(() => receives.error && receives.error(reason))).receive("timeout", () => withLatency(() => receives.timeout && receives.timeout()));
+ });
}
- pushWithReply(refGenerator, event, payload, onReply = function() {
- }) {
+ pushWithReply(refGenerator, event, payload) {
if (!this.isConnected()) {
- return;
+ return Promise.reject(new Error("no connection"));
}
- let [ref, [el], opts] = refGenerator ? refGenerator() : [null, [], {}];
+ const [ref, [el], opts] = refGenerator ? refGenerator({ payload }) : [null, [], {}];
+ const oldJoinCount = this.joinCount;
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 (opts.page_loading) {
+ 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);
+ return new Promise((resolve, reject) => {
+ this.wrapPush(() => this.channel.push(event, payload, PUSH_TIMEOUT), {
+ ok: (resp) => {
+ if (ref !== null) {
+ this.lastAckRef = ref;
}
- if (resp.live_redirect) {
- this.onLiveRedirect(resp.live_redirect);
+ const 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();
+ resolve({ resp, reply: hookReply, ref });
+ };
+ if (resp.diff) {
+ this.liveSocket.requestDOMUpdate(() => {
+ this.applyDiff("update", resp.diff, ({ diff, reply, events }) => {
+ if (ref !== null) {
+ this.undoRefs(ref, payload.event);
+ }
+ this.update(diff, events);
+ finish(reply);
+ });
+ });
+ } else {
+ if (ref !== null) {
+ this.undoRefs(ref, payload.event);
+ }
+ finish(null);
}
- 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);
+ },
+ error: (reason) => reject(new Error(`failed with reason: ${JSON.stringify(reason)}`)),
+ timeout: () => {
+ reject(new Error("timeout"));
+ if (this.joinCount === oldJoinCount) {
+ this.liveSocket.reloadWithJitter(this, () => {
+ this.log("timeout", () => [
+ "received timeout while communicating with server. Falling back to hard refresh for recovery"
+ ]);
});
- });
- } else {
- if (ref !== null) {
- this.undoRefs(ref);
}
- finish(null);
}
});
});
}
- undoRefs(ref) {
+ undoRefs(ref, phxEvent, onlyEls) {
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();
+ const selector = `[${PHX_REF_SRC}="${this.refSrc()}"]`;
+ if (onlyEls) {
+ onlyEls = new Set(onlyEls);
+ dom_default.all(document, selector, (parent) => {
+ if (onlyEls && !onlyEls.has(parent)) {
+ return;
}
- dom_default.deletePrivate(el, PHX_REF);
+ dom_default.all(parent, selector, (child) => this.undoElRef(child, ref, phxEvent));
+ this.undoElRef(parent, ref, phxEvent);
+ });
+ } else {
+ dom_default.all(document, selector, (el) => this.undoElRef(el, ref, phxEvent));
+ }
+ }
+ undoElRef(el, ref, phxEvent) {
+ const elRef = new ElementRef(el);
+ elRef.maybeUndo(ref, phxEvent, (clonedTree) => {
+ const patch = new DOMPatch(this, el, this.id, clonedTree, [], null, {
+ undoRef: ref
+ });
+ const phxChildrenAdded = this.performPatch(patch, true);
+ dom_default.all(el, `[${PHX_REF_SRC}="${this.refSrc()}"]`, (child) => this.undoElRef(child, ref, phxEvent));
+ if (phxChildrenAdded) {
+ this.joinNewChildren();
}
});
}
- putRef(elements, event, opts = {}) {
- let newRef = this.ref++;
- let disableWith = this.binding(PHX_DISABLE_WITH);
+ refSrc() {
+ return this.el.id;
+ }
+ putRef(elements, phxEvent, eventType, opts = {}) {
+ const newRef = this.ref++;
+ const disableWith = this.binding(PHX_DISABLE_WITH);
if (opts.loading) {
- elements = elements.concat(dom_default.all(document, opts.loading));
+ const loadingEls = dom_default.all(document, opts.loading).map((el) => {
+ return { el, lock: true, loading: true };
+ });
+ elements = elements.concat(loadingEls);
}
- 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);
+ for (const { el, lock, loading } of elements) {
+ if (!lock && !loading) {
+ throw new Error("putRef requires lock or loading");
+ }
+ el.setAttribute(PHX_REF_SRC, this.refSrc());
+ if (loading) {
+ el.setAttribute(PHX_REF_LOADING, newRef);
+ }
+ if (lock) {
+ el.setAttribute(PHX_REF_LOCK, newRef);
+ }
+ if (!loading || opts.submitter && !(el === opts.submitter || el === opts.form)) {
+ continue;
+ }
+ const lockCompletePromise = new Promise((resolve) => {
+ el.addEventListener(`phx:undo-lock:${newRef}`, () => resolve(detail), {
+ once: true
+ });
+ });
+ const loadingCompletePromise = new Promise((resolve) => {
+ el.addEventListener(`phx:undo-loading:${newRef}`, () => resolve(detail), { once: true });
+ });
+ el.classList.add(`phx-${eventType}-loading`);
+ const disableText = el.getAttribute(disableWith);
if (disableText !== null) {
if (!el.getAttribute(PHX_DISABLE_WITH_RESTORE)) {
- el.setAttribute(PHX_DISABLE_WITH_RESTORE, el.innerText);
+ el.setAttribute(PHX_DISABLE_WITH_RESTORE, el.textContent);
}
if (disableText !== "") {
- el.innerText = disableText;
+ el.textContent = disableText;
}
+ el.setAttribute(PHX_DISABLED, el.getAttribute(PHX_DISABLED) || el.disabled);
el.setAttribute("disabled", "");
}
- });
- return [newRef, elements, opts];
+ const detail = {
+ event: phxEvent,
+ eventType,
+ ref: newRef,
+ isLoading: loading,
+ isLocked: lock,
+ lockElements: elements.filter(({ lock: lock2 }) => lock2).map(({ el: el2 }) => el2),
+ loadingElements: elements.filter(({ loading: loading2 }) => loading2).map(({ el: el2 }) => el2),
+ unlock: (els) => {
+ els = Array.isArray(els) ? els : [els];
+ this.undoRefs(newRef, phxEvent, els);
+ },
+ lockComplete: lockCompletePromise,
+ loadingComplete: loadingCompletePromise,
+ lock: (lockEl) => {
+ return new Promise((resolve) => {
+ if (this.isAcked(newRef)) {
+ return resolve(detail);
+ }
+ lockEl.setAttribute(PHX_REF_LOCK, newRef);
+ lockEl.setAttribute(PHX_REF_SRC, this.refSrc());
+ lockEl.addEventListener(`phx:lock-stop:${newRef}`, () => resolve(detail), { once: true });
+ });
+ }
+ };
+ if (opts.payload) {
+ detail["payload"] = opts.payload;
+ }
+ if (opts.target) {
+ detail["target"] = opts.target;
+ }
+ if (opts.originalEvent) {
+ detail["originalEvent"] = opts.originalEvent;
+ }
+ el.dispatchEvent(new CustomEvent("phx:push", {
+ detail,
+ bubbles: true,
+ cancelable: false
+ }));
+ if (phxEvent) {
+ el.dispatchEvent(new CustomEvent(`phx:push:${phxEvent}`, {
+ detail,
+ bubbles: true,
+ cancelable: false
+ }));
+ }
+ }
+ return [newRef, elements.map(({ el }) => el), opts];
+ }
+ isAcked(ref) {
+ return this.lastAckRef !== null && this.lastAckRef >= ref;
}
componentID(el) {
- let cid = el.getAttribute && el.getAttribute(PHX_COMPONENT);
+ const 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"));
+ const cidOrSelector = opts.target || target.getAttribute(this.binding("target"));
if (isCid(cidOrSelector)) {
return parseInt(cidOrSelector);
} else if (targetCtx && (cidOrSelector !== null || opts.target)) {
@@ -3407,27 +4633,33 @@ within:
return null;
}
}
- pushHookEvent(el, targetCtx, event, payload, onReply) {
+ pushHookEvent(el, targetCtx, event, payload) {
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", {
+ this.log("hook", () => [
+ "unable to push hook event. LiveView not connected",
+ event,
+ payload
+ ]);
+ return Promise.reject(new Error("unable to push hook event. LiveView not connected"));
+ }
+ const refGenerator = () => this.putRef([{ el, loading: true, lock: true }], event, "hook", {
+ payload,
+ target: targetCtx
+ });
+ return this.pushWithReply(refGenerator, "event", {
type: "hook",
event,
value: payload,
cid: this.closestComponentID(targetCtx)
- }, (resp, reply) => onReply(reply, ref));
- return ref;
+ }).then(({ resp: _resp, reply, ref }) => ({ reply, ref }));
}
extractMeta(el, meta, value) {
- let prefix = this.binding("value-");
+ const prefix = this.binding("value-");
for (let i = 0; i < el.attributes.length; i++) {
if (!meta) {
meta = {};
}
- let name = el.attributes[i].name;
+ const name = el.attributes[i].name;
if (name.startsWith(prefix)) {
meta[name.replace(prefix, "")] = el.getAttribute(name);
}
@@ -3445,19 +4677,21 @@ within:
if (!meta) {
meta = {};
}
- for (let key in value) {
+ for (const 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", {
+ this.pushWithReply((maybePayload) => this.putRef([{ el, loading: true, lock: true }], phxEvent, type, __spreadProps(__spreadValues({}, opts), {
+ payload: maybePayload == null ? void 0 : maybePayload.payload
+ })), "event", {
type,
event: phxEvent,
value: this.extractMeta(el, meta, opts.value),
cid: this.targetComponentID(el, targetCtx, opts)
- }, (resp, reply) => onReply && onReply(reply));
+ }).then(({ reply }) => onReply && onReply(reply)).catch((error) => logError("Failed to push event", error));
}
pushFileProgress(fileEl, entryRef, progress, onReply = function() {
}) {
@@ -3468,51 +4702,69 @@ within:
entry_ref: entryRef,
progress,
cid: view.targetComponentID(fileEl.form, targetCtx)
- }, onReply);
+ }).then(() => onReply()).catch((error) => logError("Failed to push file progress", error));
});
}
pushInput(inputEl, targetCtx, forceCid, phxEvent, opts, callback) {
+ if (!inputEl.form) {
+ throw new Error("form events require the input to be inside a form");
+ }
let uploads;
- let cid = isCid(forceCid) ? forceCid : this.targetComponentID(inputEl.form, targetCtx);
- let refGenerator = () => this.putRef([inputEl, inputEl.form], "change", opts);
+ const cid = isCid(forceCid) ? forceCid : this.targetComponentID(inputEl.form, targetCtx, opts);
+ const refGenerator = (maybePayload) => {
+ return this.putRef([
+ { el: inputEl, loading: true, lock: true },
+ { el: inputEl.form, loading: true, lock: true }
+ ], phxEvent, "change", __spreadProps(__spreadValues({}, opts), { payload: maybePayload == null ? void 0 : maybePayload.payload }));
+ };
let formData;
- let meta = this.extractMeta(inputEl.form);
+ const meta = this.extractMeta(inputEl.form, {}, opts.value);
+ const serializeOpts = {};
+ if (inputEl instanceof HTMLButtonElement) {
+ serializeOpts.submitter = inputEl;
+ }
if (inputEl.getAttribute(this.binding("change"))) {
- formData = serializeForm(inputEl.form, __spreadValues({ _target: opts._target }, meta), [inputEl.name]);
+ formData = serializeForm(inputEl.form, serializeOpts, [inputEl.name]);
} else {
- formData = serializeForm(inputEl.form, __spreadValues({ _target: opts._target }, meta));
+ formData = serializeForm(inputEl.form, serializeOpts);
}
if (dom_default.isUploadInput(inputEl) && inputEl.files && inputEl.files.length > 0) {
LiveUploader.trackFiles(inputEl, Array.from(inputEl.files));
}
uploads = LiveUploader.serializeUploads(inputEl);
- let event = {
+ const event = {
type: "form",
event: phxEvent,
value: formData,
+ meta: __spreadValues({
+ _target: opts._target || "undefined"
+ }, meta),
uploads,
cid
};
- this.pushWithReply(refGenerator, "event", event, (resp) => {
- dom_default.showError(inputEl, this.liveSocket.binding(PHX_FEEDBACK_FOR));
+ this.pushWithReply(refGenerator, "event", event).then(({ resp }) => {
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);
- });
- }
+ ElementRef.onUnlock(inputEl, () => {
+ if (LiveUploader.filesAwaitingPreflight(inputEl).length > 0) {
+ const [ref, _els] = refGenerator();
+ this.undoRefs(ref, phxEvent, [inputEl.form]);
+ this.uploadFiles(inputEl.form, phxEvent, targetCtx, ref, cid, (_uploads) => {
+ callback && callback(resp);
+ this.triggerAwaitingSubmit(inputEl.form, phxEvent);
+ this.undoRefs(ref, phxEvent);
+ });
+ }
+ });
} else {
callback && callback(resp);
}
- });
+ }).catch((error) => logError("Failed to push input event", error));
}
- triggerAwaitingSubmit(formEl) {
- let awaitingSubmit = this.getScheduledSubmit(formEl);
+ triggerAwaitingSubmit(formEl, phxEvent) {
+ const awaitingSubmit = this.getScheduledSubmit(formEl);
if (awaitingSubmit) {
- let [_el, _ref, _opts, callback] = awaitingSubmit;
- this.cancelSubmit(formEl);
+ const [_el, _ref, _opts, callback] = awaitingSubmit;
+ this.cancelSubmit(formEl, phxEvent);
callback();
}
}
@@ -3525,30 +4777,30 @@ within:
}
this.formSubmits.push([formEl, ref, opts, callback]);
}
- cancelSubmit(formEl) {
- this.formSubmits = this.formSubmits.filter(([el, ref, _callback]) => {
+ cancelSubmit(formEl, phxEvent) {
+ this.formSubmits = this.formSubmits.filter(([el, ref, _opts, _callback]) => {
if (el.isSameNode(formEl)) {
- this.undoRefs(ref);
+ this.undoRefs(ref, phxEvent);
return false;
} else {
return true;
}
});
}
- disableForm(formEl, opts = {}) {
- let filterIgnored = (el) => {
- let userIgnored = closestPhxBinding(el, `${this.binding(PHX_UPDATE)}=ignore`, el.form);
+ disableForm(formEl, phxEvent, opts = {}) {
+ const filterIgnored = (el) => {
+ const userIgnored = closestPhxBinding(el, `${this.binding(PHX_UPDATE)}=ignore`, el.form);
return !(userIgnored || closestPhxBinding(el, "data-phx-update=ignore", el.form));
};
- let filterDisables = (el) => {
+ const 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);
+ const filterButton = (el) => el.tagName == "BUTTON";
+ const filterInput = (el) => ["INPUT", "TEXTAREA", "SELECT"].includes(el.tagName);
+ const formElements = Array.from(formEl.elements);
+ const disables = formElements.filter(filterDisables);
+ const buttons = formElements.filter(filterButton).filter(filterIgnored);
+ const inputs = formElements.filter(filterInput).filter(filterIgnored);
buttons.forEach((button) => {
button.setAttribute(PHX_DISABLED, button.disabled);
button.disabled = true;
@@ -3561,67 +4813,90 @@ within:
input.disabled = true;
}
});
- formEl.setAttribute(this.binding(PHX_PAGE_LOADING), "");
- return this.putRef([formEl].concat(disables).concat(buttons).concat(inputs), "submit", opts);
+ const formEls = disables.concat(buttons).concat(inputs).map((el) => {
+ return { el, loading: true, lock: true };
+ });
+ const els = [{ el: formEl, loading: true, lock: false }].concat(formEls).reverse();
+ return this.putRef(els, phxEvent, "submit", opts);
}
pushFormSubmit(formEl, targetCtx, phxEvent, submitter, opts, onReply) {
- let refGenerator = () => this.disableForm(formEl, opts);
- let cid = this.targetComponentID(formEl, targetCtx);
+ const refGenerator = (maybePayload) => this.disableForm(formEl, phxEvent, __spreadProps(__spreadValues({}, opts), {
+ form: formEl,
+ payload: maybePayload == null ? void 0 : maybePayload.payload,
+ submitter
+ }));
+ dom_default.putPrivate(formEl, "submitter", submitter);
+ const cid = this.targetComponentID(formEl, targetCtx);
if (LiveUploader.hasUploadsInProgress(formEl)) {
- let [ref, _els] = refGenerator();
- let push = () => this.pushFormSubmit(formEl, submitter, targetCtx, phxEvent, opts, onReply);
+ const [ref, _els] = refGenerator();
+ const push = () => this.pushFormSubmit(formEl, targetCtx, phxEvent, submitter, 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));
+ const [ref, els] = refGenerator();
+ const proxyRefGen = () => [ref, els, opts];
+ this.uploadFiles(formEl, phxEvent, targetCtx, ref, cid, (_uploads) => {
+ if (LiveUploader.inputsAwaitingPreflight(formEl).length > 0) {
+ return this.undoRefs(ref, phxEvent);
+ }
+ const meta = this.extractMeta(formEl, {}, opts.value);
+ const formData = serializeForm(formEl, { submitter });
this.pushWithReply(proxyRefGen, "event", {
type: "form",
event: phxEvent,
value: formData,
+ meta,
cid
- }, onReply);
+ }).then(({ resp }) => onReply(resp)).catch((error) => logError("Failed to push form submit", error));
});
- } else if (!(formEl.hasAttribute(PHX_REF) && formEl.classList.contains("phx-submit-loading"))) {
- let meta = this.extractMeta(formEl);
- let formData = serializeForm(formEl, __spreadValues({ submitter }, meta));
+ } else if (!(formEl.hasAttribute(PHX_REF_SRC) && formEl.classList.contains("phx-submit-loading"))) {
+ const meta = this.extractMeta(formEl, {}, opts.value);
+ const formData = serializeForm(formEl, { submitter });
this.pushWithReply(refGenerator, "event", {
type: "form",
event: phxEvent,
value: formData,
+ meta,
cid
- }, onReply);
+ }).then(({ resp }) => onReply(resp)).catch((error) => logError("Failed to push form submit", error));
}
}
- uploadFiles(formEl, targetCtx, ref, cid, onComplete) {
- let joinCountAtUpload = this.joinCount;
- let inputEls = LiveUploader.activeFileInputs(formEl);
+ uploadFiles(formEl, phxEvent, targetCtx, ref, cid, onComplete) {
+ const joinCountAtUpload = this.joinCount;
+ const inputEls = LiveUploader.activeFileInputs(formEl);
let numFileInputsInProgress = inputEls.length;
inputEls.forEach((inputEl) => {
- let uploader = new LiveUploader(inputEl, this, () => {
+ const uploader = new LiveUploader(inputEl, this, () => {
numFileInputsInProgress--;
if (numFileInputsInProgress === 0) {
onComplete();
}
});
- this.uploaders[inputEl] = uploader;
- let entries = uploader.entries().map((entry) => entry.toPreflightPayload());
- let payload = {
+ const entries = uploader.entries().map((entry) => entry.toPreflightPayload());
+ if (entries.length === 0) {
+ numFileInputsInProgress--;
+ return;
+ }
+ const 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.pushWithReply(null, "allow_upload", payload).then(({ 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]);
+ uploader.entries().forEach((entry) => {
+ if (resp.entries && !resp.entries[entry.ref]) {
+ this.handleFailedEntryPreflight(entry.ref, "failed preflight", uploader);
+ }
+ });
+ if (resp.error || Object.keys(resp.entries).length === 0) {
+ this.undoRefs(ref, phxEvent);
+ const errors = resp.error || [];
+ errors.map(([entry_ref, reason]) => {
+ this.handleFailedEntryPreflight(entry_ref, reason, uploader);
+ });
} else {
- let onError = (callback) => {
+ const onError = (callback) => {
this.channel.onError(() => {
if (this.joinCount === joinCountAtUpload) {
callback();
@@ -3630,38 +4905,85 @@ within:
};
uploader.initAdapterUpload(resp, onError, this.liveSocket);
}
- });
+ }).catch((error) => logError("Failed to push upload", error));
});
}
- dispatchUploads(name, filesOrBlobs) {
- let inputs = dom_default.findUploadInputs(this.el).filter((el) => el.name === name);
+ handleFailedEntryPreflight(uploadRef, reason, uploader) {
+ if (uploader.isAutoUpload()) {
+ const entry = uploader.entries().find((entry2) => entry2.ref === uploadRef.toString());
+ if (entry) {
+ entry.cancel();
+ }
+ } else {
+ uploader.entries().map((entry) => entry.cancel());
+ }
+ this.log("upload", () => [`error for entry ${uploadRef}`, reason]);
+ }
+ dispatchUploads(targetCtx, name, filesOrBlobs) {
+ const targetElement = this.targetCtxElement(targetCtx) || this.el;
+ const inputs = dom_default.findUploadInputs(targetElement).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 } });
+ 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 }]);
- });
+ targetCtxElement(targetCtx) {
+ if (isCid(targetCtx)) {
+ const [target] = dom_default.findComponentNodeList(this.id, targetCtx);
+ return target;
+ } else if (targetCtx) {
+ return targetCtx;
+ } else {
+ return null;
+ }
}
- 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) => {
+ pushFormRecovery(oldForm, newForm, templateDom, callback) {
+ const phxChange = this.binding("change");
+ const phxTarget = newForm.getAttribute(this.binding("target")) || newForm;
+ const phxEvent = newForm.getAttribute(this.binding(PHX_AUTO_RECOVER)) || newForm.getAttribute(this.binding("change"));
+ const inputs = Array.from(oldForm.elements).filter((el) => dom_default.isFormInput(el) && el.name && !el.hasAttribute(phxChange));
+ if (inputs.length === 0) {
+ callback();
+ return;
+ }
+ inputs.forEach((input2) => input2.hasAttribute(PHX_UPLOAD_REF) && LiveUploader.clearFiles(input2));
+ const input = inputs.find((el) => el.type !== "hidden") || inputs[0];
+ let pending = 0;
+ this.withinTargets(phxTarget, (targetView, targetCtx) => {
+ const cid = this.targetComponentID(newForm, targetCtx);
+ pending++;
+ let e = new CustomEvent("phx:form-recovery", {
+ detail: { sourceElement: oldForm }
+ });
+ js_default.exec(e, "change", phxEvent, this, input, [
+ "push",
+ {
+ _target: input.name,
+ targetView,
+ targetCtx,
+ newCid: cid,
+ callback: () => {
+ pending--;
+ if (pending === 0) {
+ callback();
+ }
+ }
+ }
+ ]);
+ }, templateDom);
+ }
+ pushLinkPatch(e, href, targetEl, callback) {
+ const linkRef = this.liveSocket.setPendingLink(href);
+ const loading = e.isTrusted && e.type !== "popstate";
+ const refGen = targetEl ? () => this.putRef([{ el: targetEl, loading, lock: true }], null, "click") : null;
+ const fallback = () => this.liveSocket.redirect(window.location.href);
+ const url = href.startsWith("/") ? `${location.protocol}//${location.host}${href}` : href;
+ this.pushWithReply(refGen, "live_patch", { url }).then(({ resp }) => {
this.liveSocket.requestDOMUpdate(() => {
if (resp.link_redirect) {
this.liveSocket.replaceMain(href, null, callback, linkRef);
@@ -3673,67 +4995,96 @@ within:
callback && callback(linkRef);
}
});
- });
- if (push) {
- push.receive("timeout", fallback);
- } else {
- fallback();
- }
+ }, ({ error: _error, timeout: _timeout }) => fallback());
}
- formsForRecovery(html) {
+ getFormsForRecovery() {
if (this.joinCount === 0) {
- return [];
+ 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);
+ const phxChange = this.binding("change");
+ return dom_default.all(document, `#${CSS.escape(this.id)} form[${phxChange}], [${PHX_TELEPORTED_REF}="${CSS.escape(this.id)}"] form[${phxChange}]`).filter((form) => form.id).filter((form) => form.elements.length > 0).filter((form) => form.getAttribute(this.binding(PHX_AUTO_RECOVER)) !== "ignore").map((form) => {
+ const clonedForm = form.cloneNode(true);
+ morphdom_esm_default(clonedForm, form, {
+ onBeforeElUpdated: (fromEl, toEl) => {
+ dom_default.copyPrivates(fromEl, toEl);
+ if (fromEl.getAttribute("form") === form.id) {
+ fromEl.parentNode.removeChild(fromEl);
+ return false;
+ }
+ return true;
+ }
+ });
+ const externalElements = document.querySelectorAll(`[form="${CSS.escape(form.id)}"]`);
+ Array.from(externalElements).forEach((el) => {
+ const clonedEl = el.cloneNode(true);
+ morphdom_esm_default(clonedEl, el);
+ dom_default.copyPrivates(clonedEl, el);
+ clonedEl.removeAttribute("form");
+ clonedForm.appendChild(clonedEl);
+ });
+ return clonedForm;
+ }).reduce((acc, form) => {
+ acc[form.id] = form;
+ return acc;
+ }, {});
}
maybePushComponentsDestroyed(destroyedCIDs) {
let willDestroyCIDs = destroyedCIDs.filter((cid) => {
- return dom_default.findComponentNodeList(this.el, cid).length === 0;
+ return dom_default.findComponentNodeList(this.id, cid).length === 0;
});
+ const onError = (error) => {
+ if (!this.isDestroyed()) {
+ logError("Failed to push components destroyed", error);
+ }
+ };
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);
+ willDestroyCIDs.forEach((cid) => this.rendered.resetRender(cid));
+ this.pushWithReply(null, "cids_will_destroy", { cids: willDestroyCIDs }).then(() => {
+ this.liveSocket.requestDOMUpdate(() => {
+ let completelyDestroyCIDs = willDestroyCIDs.filter((cid) => {
+ return dom_default.findComponentNodeList(this.id, cid).length === 0;
});
- }
- });
+ if (completelyDestroyCIDs.length > 0) {
+ this.pushWithReply(null, "cids_destroyed", {
+ cids: completelyDestroyCIDs
+ }).then(({ resp }) => {
+ this.rendered.pruneCIDs(resp.cids);
+ }).catch(onError);
+ }
+ });
+ }).catch(onError);
}
}
ownsElement(el) {
- let parentViewEl = el.closest(PHX_VIEW_SELECTOR);
+ let parentViewEl = dom_default.closestViewEl(el);
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);
+ const 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);
}
+ pushPortalElementId(id) {
+ this.portalElementIds.add(id);
+ }
+ dropPortalElementId(id) {
+ this.portalElementIds.delete(id);
+ }
+ destroyPortalElements() {
+ this.portalElementIds.forEach((id) => {
+ const el = document.getElementById(id);
+ if (el) {
+ el.remove();
+ }
+ });
+ }
};
var LiveSocket = class {
constructor(url, phxSocket, opts = {}) {
@@ -3754,7 +5105,6 @@ within:
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;
@@ -3768,6 +5118,7 @@ within:
this.hooks = opts.hooks || {};
this.uploaders = opts.uploaders || {};
this.loaderTimeout = opts.loaderTimeout || LOADER_TIMEOUT;
+ this.disconnectedTimeout = opts.disconnectedTimeout || DISCONNECTED_TIMEOUT;
this.reloadWithJitterTimer = null;
this.maxReloads = opts.maxReloads || MAX_RELOADS;
this.reloadJitterMin = opts.reloadJitterMin || RELOAD_JITTER_MIN;
@@ -3776,8 +5127,18 @@ within:
this.localStorage = opts.localStorage || window.localStorage;
this.sessionStorage = opts.sessionStorage || window.sessionStorage;
this.boundTopLevelEvents = false;
- this.domCallbacks = Object.assign({ onNodeAdded: closure(), onBeforeElUpdated: closure() }, opts.dom || {});
+ this.boundEventNames = /* @__PURE__ */ new Set();
+ this.blockPhxChangeWhileComposing = opts.blockPhxChangeWhileComposing || false;
+ this.serverCloseRef = null;
+ this.domCallbacks = Object.assign({
+ jsQuerySelectorAll: null,
+ onPatchStart: closure(),
+ onPatchEnd: closure(),
+ onNodeAdded: closure(),
+ onBeforeElUpdated: closure()
+ }, opts.dom || {});
this.transitions = new TransitionSet();
+ this.currentHistoryPosition = parseInt(this.sessionStorage.getItem(PHX_LV_HISTORY_POSITION)) || 0;
window.addEventListener("pagehide", (_e) => {
this.unloaded = true;
});
@@ -3787,6 +5148,9 @@ within:
}
});
}
+ version() {
+ return "1.1.17";
+ }
isProfileEnabled() {
return this.sessionStorage.getItem(PHX_LV_PROFILE) === "true";
}
@@ -3817,7 +5181,7 @@ within:
this.sessionStorage.removeItem(PHX_LV_LATENCY_SIM);
}
getLatencySim() {
- let str = this.sessionStorage.getItem(PHX_LV_LATENCY_SIM);
+ const str = this.sessionStorage.getItem(PHX_LV_LATENCY_SIM);
return str ? parseInt(str) : null;
}
getSocket() {
@@ -3827,7 +5191,8 @@ within:
if (window.location.hostname === "localhost" && !this.isDebugDisabled()) {
this.enableDebug();
}
- let doConnect = () => {
+ const doConnect = () => {
+ this.resetReloadStatus();
if (this.joinRootViews()) {
this.bindTopLevelEvents();
this.socket.connect();
@@ -3846,6 +5211,10 @@ within:
}
disconnect(callback) {
clearTimeout(this.reloadWithJitterTimer);
+ if (this.serverCloseRef) {
+ this.socket.off(this.serverCloseRef);
+ this.serverCloseRef = null;
+ }
this.socket.disconnect(callback);
}
replaceTransport(transport) {
@@ -3854,12 +5223,11 @@ within:
this.connect();
}
execJS(el, encodedJS, eventType = null) {
- this.owner(el, (view) => js_default.exec(eventType, encodedJS, view, el));
+ const e = new CustomEvent("phx:exec", { detail: { sourceElement: el } });
+ this.owner(el, (view) => js_default.exec(e, eventType, encodedJS, view, el));
}
- execJSHookPush(el, phxEvent, data, callback) {
- this.withinOwners(el, (view) => {
- js_default.exec("hook", phxEvent, view, el, ["push", { data, callback }]);
- });
+ js() {
+ return js_commands_default(this, "js");
}
unload() {
if (this.unloaded) {
@@ -3880,29 +5248,32 @@ within:
return func();
}
console.time(name);
- let result = func();
+ const result = func();
console.timeEnd(name);
return result;
}
log(view, kind, msgCallback) {
if (this.viewLogger) {
- let [msg, obj] = msgCallback();
+ const [msg, obj] = msgCallback();
this.viewLogger(view, kind, msg, obj);
} else if (this.isDebugEnabled()) {
- let [msg, obj] = msgCallback();
+ const [msg, obj] = msgCallback();
debug(view, kind, msg, obj);
}
}
requestDOMUpdate(callback) {
this.transitions.after(callback);
}
+ asyncTransition(promise) {
+ this.transitions.addAsyncTransition(promise);
+ }
transition(time, onStart, onDone = function() {
}) {
this.transitions.addTransition(time, onStart, onDone);
}
onChannel(channel, event, cb) {
channel.on(event, (data) => {
- let latency = this.getLatencySim();
+ const latency = this.getLatencySim();
if (!latency) {
cb(data);
} else {
@@ -3910,44 +5281,14 @@ within:
}
});
}
- 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;
+ const minMs = this.reloadJitterMin;
+ const 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) {
+ const 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(() => {
@@ -3955,9 +5296,13 @@ within:
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`]);
+ 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;
@@ -3966,8 +5311,30 @@ within:
}
}, afterMs);
}
- getHookCallbacks(name) {
- return name && name.startsWith("Phoenix.") ? hooks_default[name.split(".")[1]] : this.hooks[name];
+ getHookDefinition(name) {
+ if (!name) {
+ return;
+ }
+ return this.maybeInternalHook(name) || this.hooks[name] || this.maybeRuntimeHook(name);
+ }
+ maybeInternalHook(name) {
+ return name && name.startsWith("Phoenix.") && hooks_default[name.split(".")[1]];
+ }
+ maybeRuntimeHook(name) {
+ const runtimeHook = document.querySelector(`script[${PHX_RUNTIME_HOOK}="${CSS.escape(name)}"]`);
+ if (!runtimeHook) {
+ return;
+ }
+ let callbacks = window[`phx_hook_${name}`];
+ if (!callbacks || typeof callbacks !== "function") {
+ logError("a runtime hook must be a function", runtimeHook);
+ return;
+ }
+ const hookDefiniton = callbacks();
+ if (hookDefiniton && (typeof hookDefiniton === "object" || typeof hookDefiniton === "function")) {
+ return hookDefiniton;
+ }
+ logError("runtime hook must return an object with hook callbacks or an instance of ViewHook", runtimeHook);
}
isUnloaded() {
return this.unloaded;
@@ -3985,23 +5352,29 @@ within:
return this.socket.channel(topic, params);
}
joinDeadView() {
- let body = document.body;
+ const body = document.body;
if (body && !this.isPhxView(body) && !this.isPhxView(document.firstElementChild)) {
- let view = this.newRootView(body);
+ const view = this.newRootView(body);
view.setHref(this.getHref());
view.joinDead();
if (!this.main) {
this.main = view;
}
- window.requestAnimationFrame(() => view.execNewMounted());
+ window.requestAnimationFrame(() => {
+ var _a;
+ view.execNewMounted();
+ this.maybeScroll((_a = history.state) == null ? void 0 : _a.scroll);
+ });
}
}
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());
+ const view = this.newRootView(rootEl);
+ if (!dom_default.isPhxSticky(rootEl)) {
+ view.setHref(this.getHref());
+ }
view.join();
if (rootEl.hasAttribute(PHX_MAIN)) {
this.main = view;
@@ -4011,71 +5384,95 @@ within:
});
return rootsFound;
}
- redirect(to, flash) {
+ redirect(to, flash, reloadToken) {
+ if (reloadToken) {
+ browser_default.setCookie(PHX_RELOAD_STATUS, reloadToken, 60);
+ }
this.unload();
browser_default.redirect(to, flash);
}
replaceMain(href, flash, callback = null, linkRef = this.setPendingLink(href)) {
- let liveReferer = this.currentLocation.href;
+ const liveReferer = this.currentLocation.href;
this.outgoingMainEl = this.outgoingMainEl || this.main.el;
- let newMainEl = dom_default.cloneNode(this.outgoingMainEl, "");
+ const stickies = dom_default.findPhxSticky(document) || [];
+ const removeEls = dom_default.all(this.outgoingMainEl, `[${this.binding("remove")}]`).filter((el) => !dom_default.isChildOfAny(el, stickies));
+ const 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.transitionRemoves(removeEls);
this.main.join((joinCount, onDone) => {
if (joinCount === 1 && this.commitPendingLink(linkRef)) {
this.requestDOMUpdate(() => {
- dom_default.findPhxSticky(document).forEach((el) => newMainEl.appendChild(el));
+ removeEls.forEach((el) => el.remove());
+ stickies.forEach((el) => newMainEl.appendChild(el));
this.outgoingMainEl.replaceWith(newMainEl);
this.outgoingMainEl = null;
- callback && requestAnimationFrame(() => callback(linkRef));
+ callback && callback(linkRef);
onDone();
});
}
});
}
- transitionRemoves(elements) {
- let removeAttr = this.binding("remove");
- elements = elements || dom_default.all(document, `[${removeAttr}]`);
+ transitionRemoves(elements, callback) {
+ const removeAttr = this.binding("remove");
+ const silenceEvents = (e) => {
+ e.preventDefault();
+ e.stopImmediatePropagation();
+ };
elements.forEach((el) => {
+ for (const event of this.boundEventNames) {
+ el.addEventListener(event, silenceEvents, true);
+ }
this.execJS(el, el.getAttribute(removeAttr), "remove");
});
+ this.requestDOMUpdate(() => {
+ elements.forEach((el) => {
+ for (const event of this.boundEventNames) {
+ el.removeEventListener(event, silenceEvents, true);
+ }
+ });
+ callback && callback();
+ });
}
isPhxView(el) {
return el.getAttribute && el.getAttribute(PHX_SESSION) !== null;
}
newRootView(el, flash, liveReferer) {
- let view = new View(el, this, null, flash, liveReferer);
+ const 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);
+ let view;
+ const viewEl = dom_default.closestViewEl(childEl);
+ if (viewEl) {
+ view = this.getViewByEl(viewEl);
+ } else {
+ view = this.main;
}
+ return view && callback ? callback(view) : view;
}
withinOwners(childEl, callback) {
this.owner(childEl, (view) => callback(view, childEl));
}
getViewByEl(el) {
- let rootId = el.getAttribute(PHX_ROOT_ID);
+ const 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) {
+ for (const 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));
+ const root = this.getRootById(el.getAttribute(PHX_ROOT_ID));
if (root && root.id === el.id) {
root.destroy();
delete this.roots[root.id];
@@ -4083,27 +5480,8 @@ within:
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;
- }
+ return document.activeElement;
}
dropActiveElement(view) {
if (this.prevActive && view.ownsElement(this.prevActive)) {
@@ -4111,13 +5489,13 @@ within:
}
}
restorePreviouslyActiveFocus() {
- if (this.prevActive && this.prevActive !== document.body) {
+ if (this.prevActive && this.prevActive !== document.body && this.prevActive instanceof HTMLElement) {
this.prevActive.focus();
}
}
blurActiveElement() {
this.prevActive = this.getActiveElement();
- if (this.prevActive !== document.body) {
+ if (this.prevActive !== document.body && this.prevActive instanceof HTMLElement) {
this.prevActive.blur();
}
}
@@ -4126,7 +5504,7 @@ within:
return;
}
this.boundTopLevelEvents = true;
- this.socket.onClose((event) => {
+ this.serverCloseRef = this.socket.onClose((event) => {
if (event && event.code === 1e3 && this.main) {
return this.reloadWithJitter(this.main);
}
@@ -4147,60 +5525,64 @@ within:
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();
+ this.bind({ keyup: "keyup", keydown: "keydown" }, (e, type, view, targetEl, phxEvent, _phxTarget) => {
+ const matchKey = targetEl.getAttribute(this.binding(PHX_KEY));
+ const 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 }]);
+ const data = __spreadValues({ key: e.key }, this.eventMeta(type, e, targetEl));
+ js_default.exec(e, 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: "focusout", focus: "focusin" }, (e, type, view, targetEl, phxEvent, phxTarget) => {
+ if (!phxTarget) {
+ const data = __spreadValues({ key: e.key }, this.eventMeta(type, e, targetEl));
+ js_default.exec(e, type, phxEvent, view, targetEl, ["push", { data }]);
}
});
- this.bind({ blur: "blur", focus: "focus" }, (e, type, view, targetEl, targetCtx, phxEvent, phxTarget) => {
+ this.bind({ blur: "blur", focus: "focus" }, (e, type, view, targetEl, phxEvent, phxTarget) => {
if (phxTarget === "window") {
- let data = this.eventMeta(type, e, targetEl);
- js_default.exec(type, phxEvent, view, targetEl, ["push", { data }]);
+ const data = this.eventMeta(type, e, targetEl);
+ js_default.exec(e, type, phxEvent, view, targetEl, ["push", { data }]);
}
});
- window.addEventListener("dragover", (e) => e.preventDefault());
- window.addEventListener("drop", (e) => {
+ this.on("dragover", (e) => e.preventDefault());
+ this.on("drop", (e) => {
e.preventDefault();
- let dropTargetId = maybe(closestPhxBinding(e.target, this.binding(PHX_DROP_TARGET)), (trueTarget) => {
+ const 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)) {
+ const dropTarget = dropTargetId && document.getElementById(dropTargetId);
+ const files = Array.from(e.dataTransfer.files || []);
+ if (!dropTarget || !(dropTarget instanceof HTMLInputElement) || 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;
+ const uploadTarget = e.target;
if (!dom_default.isUploadInput(uploadTarget)) {
return;
}
- let files = Array.from(e.detail.files || []).filter((f) => f instanceof File || f instanceof Blob);
+ const 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];
+ const callback = this.metadataCallbacks[eventName];
return callback ? callback(e, targetEl) : {};
}
setPendingLink(href) {
this.linkRef++;
this.pendingLink = href;
+ this.resetReloadStatus();
return this.linkRef;
}
+ resetReloadStatus() {
+ browser_default.deleteCookie(PHX_RELOAD_STATUS);
+ }
commitPendingLink(linkRef) {
if (this.linkRef !== linkRef) {
return false;
@@ -4217,12 +5599,12 @@ within:
return !!this.pendingLink;
}
bind(events, callback) {
- for (let event in events) {
- let browserEventName = events[event];
+ for (const event in events) {
+ const 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);
+ const binding = this.binding(event);
+ const windowBinding = this.binding(`window-${event}`);
+ const targetPhxEvent = e.target.getAttribute && e.target.getAttribute(binding);
if (targetPhxEvent) {
this.debounce(e.target, e, browserEventName, () => {
this.withinOwners(e.target, (view) => {
@@ -4231,7 +5613,7 @@ within:
});
} else {
dom_default.all(document, `[${windowBinding}]`, (el) => {
- let phxEvent = el.getAttribute(windowBinding);
+ const phxEvent = el.getAttribute(windowBinding);
this.debounce(el, e, browserEventName, () => {
this.withinOwners(el, (view) => {
callback(e, event, view, el, phxEvent, "window");
@@ -4243,25 +5625,22 @@ within:
}
}
bindClicks() {
- window.addEventListener("click", (e) => this.clickStartedAtTarget = e.target);
- this.bindClick("click", "click", false);
- this.bindClick("mousedown", "capture-click", true);
+ this.on("mousedown", (e) => this.clickStartedAtTarget = e.target);
+ this.bindClick("click", "click");
}
- bindClick(eventName, bindingName, capture) {
- let click = this.binding(bindingName);
+ bindClick(eventName, bindingName) {
+ const 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 (e.detail === 0)
+ this.clickStartedAtTarget = e.target;
+ const clickStartedAtTarget = this.clickStartedAtTarget || e.target;
+ target = closestPhxBinding(e.target, click);
+ this.dispatchClickAway(e, clickStartedAtTarget);
+ this.clickStartedAtTarget = null;
+ const phxEvent = target && target.getAttribute(click);
if (!phxEvent) {
- if (!capture && dom_default.isNewPageClick(e, window.location)) {
+ if (dom_default.isNewPageClick(e, window.location)) {
this.unload();
}
return;
@@ -4269,24 +5648,30 @@ within:
if (target.getAttribute("href") === "#") {
e.preventDefault();
}
- if (target.hasAttribute(PHX_REF)) {
+ if (target.hasAttribute(PHX_REF_SRC)) {
return;
}
this.debounce(target, e, "click", () => {
this.withinOwners(target, (view) => {
- js_default.exec("click", phxEvent, view, target, ["push", { data: this.eventMeta("click", e, target) }]);
+ js_default.exec(e, "click", phxEvent, view, target, [
+ "push",
+ { data: this.eventMeta("click", e, target) }
+ ]);
});
});
- }, capture);
+ }, false);
}
dispatchClickAway(e, clickStartedAt) {
- let phxClickAway = this.binding("click-away");
+ const 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) }]);
+ this.withinOwners(el, (view) => {
+ const phxEvent = el.getAttribute(phxClickAway);
+ if (js_default.isVisible(el) && js_default.isInViewport(el)) {
+ js_default.exec(e, "click", phxEvent, view, el, [
+ "push",
+ { data: this.eventMeta("click", e, e.target) }
+ ]);
}
});
}
@@ -4310,32 +5695,39 @@ within:
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 } });
+ const { type, backType, id, scroll, position } = event.state || {};
+ const href = window.location.href;
+ const isForward = position > this.currentHistoryPosition;
+ const navType = isForward ? type : backType || type;
+ this.currentHistoryPosition = position || 0;
+ this.sessionStorage.setItem(PHX_LV_HISTORY_POSITION, this.currentHistoryPosition.toString());
+ dom_default.dispatchEvent(window, "phx:navigate", {
+ detail: {
+ href,
+ patch: navType === "patch",
+ pop: true,
+ direction: isForward ? "forward" : "backward"
+ }
+ });
this.requestDOMUpdate(() => {
- if (this.main.isConnected() && (type === "patch" && id === this.main.id)) {
- this.main.pushLinkPatch(href, null, () => {
- this.maybeScroll(scroll);
- });
+ const callback = () => {
+ this.maybeScroll(scroll);
+ };
+ if (this.main.isConnected() && navType === "patch" && id === this.main.id) {
+ this.main.pushLinkPatch(event, href, null, callback);
} else {
- this.replaceMain(href, null, () => {
- if (root) {
- this.replaceRootHistory();
- }
- this.maybeScroll(scroll);
- });
+ this.replaceMain(href, null, callback);
}
});
}, false);
window.addEventListener("click", (e) => {
- let target = closestPhxBinding(e.target, PHX_LIVE_LINK);
- let type = target && target.getAttribute(PHX_LIVE_LINK);
+ const target = closestPhxBinding(e.target, PHX_LIVE_LINK);
+ const 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);
+ const href = target.href instanceof SVGAnimatedString ? target.href.baseVal : target.href;
+ const linkState = target.getAttribute(PHX_LINK_STATE);
e.preventDefault();
e.stopImmediatePropagation();
if (this.pendingLink === href) {
@@ -4343,13 +5735,13 @@ within:
}
this.requestDOMUpdate(() => {
if (type === "patch") {
- this.pushHistoryPatch(href, linkState, target);
+ this.pushHistoryPatch(e, href, linkState, target);
} else if (type === "redirect") {
- this.historyRedirect(href, linkState);
+ this.historyRedirect(e, href, linkState, null, target);
} else {
throw new Error(`expected ${PHX_LIVE_LINK} to be "patch" or "redirect", got: ${type}`);
}
- let phxClick = target.getAttribute(this.binding("click"));
+ const phxClick = target.getAttribute(this.binding("click"));
if (phxClick) {
this.requestDOMUpdate(() => this.execJS(target, phxClick, "click"));
}
@@ -4371,15 +5763,15 @@ within:
}
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 });
+ const done = () => dom_default.dispatchEvent(window, "phx:page-loading-stop", { detail: info });
return callback ? callback(done) : done;
}
- pushHistoryPatch(href, linkState, targetEl) {
- if (!this.isConnected()) {
+ pushHistoryPatch(e, href, linkState, targetEl) {
+ if (!this.isConnected() || !this.main.isMain()) {
return browser_default.redirect(href);
}
this.withPageLoading({ to: href, kind: "patch" }, (done) => {
- this.main.pushLinkPatch(href, targetEl, (linkRef) => {
+ this.main.pushLinkPatch(e, href, targetEl, (linkRef) => {
this.historyPatch(href, linkState, linkRef);
done();
});
@@ -4389,35 +5781,60 @@ within:
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.currentHistoryPosition++;
+ this.sessionStorage.setItem(PHX_LV_HISTORY_POSITION, this.currentHistoryPosition.toString());
+ browser_default.updateCurrentState((state) => __spreadProps(__spreadValues({}, state), { backType: "patch" }));
+ browser_default.pushState(linkState, {
+ type: "patch",
+ id: this.main.id,
+ position: this.currentHistoryPosition
+ }, href);
+ dom_default.dispatchEvent(window, "phx:navigate", {
+ detail: { patch: true, href, pop: false, direction: "forward" }
+ });
this.registerNewLocation(window.location);
}
- historyRedirect(href, linkState, flash) {
- if (!this.isConnected()) {
+ historyRedirect(e, href, linkState, flash, targetEl) {
+ const clickLoading = targetEl && e.isTrusted && e.type !== "popstate";
+ if (clickLoading) {
+ targetEl.classList.add("phx-click-loading");
+ }
+ if (!this.isConnected() || !this.main.isMain()) {
return browser_default.redirect(href, flash);
}
if (/^\/$|^\/[^\/]+.*$/.test(href)) {
- let { protocol, host } = window.location;
+ const { protocol, host } = window.location;
href = `${protocol}//${host}${href}`;
}
- let scroll = window.scrollY;
+ const 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.currentHistoryPosition++;
+ this.sessionStorage.setItem(PHX_LV_HISTORY_POSITION, this.currentHistoryPosition.toString());
+ browser_default.updateCurrentState((state) => __spreadProps(__spreadValues({}, state), {
+ backType: "redirect"
+ }));
+ browser_default.pushState(linkState, {
+ type: "redirect",
+ id: this.main.id,
+ scroll,
+ position: this.currentHistoryPosition
+ }, href);
+ dom_default.dispatchEvent(window, "phx:navigate", {
+ detail: { href, patch: false, pop: false, direction: "forward" }
+ });
this.registerNewLocation(window.location);
}
+ if (clickLoading) {
+ targetEl.classList.remove("phx-click-loading");
+ }
done();
});
});
}
- replaceRootHistory() {
- browser_default.pushState("replace", { root: true, type: "patch", id: this.main.id });
- }
registerNewLocation(newLocation) {
- let { pathname, search } = this.currentLocation;
+ const { pathname, search } = this.currentLocation;
if (pathname + search === newLocation.pathname + newLocation.search) {
return false;
} else {
@@ -4429,8 +5846,8 @@ within:
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"));
+ const phxSubmit = e.target.getAttribute(this.binding("submit"));
+ const phxChange = e.target.getAttribute(this.binding("change"));
if (!externalFormSubmitted && phxChange && !phxSubmit) {
externalFormSubmitted = true;
e.preventDefault();
@@ -4444,9 +5861,9 @@ within:
});
});
}
- }, true);
+ });
this.on("submit", (e) => {
- let phxEvent = e.target.getAttribute(this.binding("submit"));
+ const phxEvent = e.target.getAttribute(this.binding("submit"));
if (!phxEvent) {
if (dom_default.isUnloadableFormSubmit(e)) {
this.unload();
@@ -4456,60 +5873,85 @@ within:
e.preventDefault();
e.target.disabled = true;
this.withinOwners(e.target, (view) => {
- js_default.exec("submit", phxEvent, view, e.target, ["push", { submitter: e.submitter }]);
+ js_default.exec(e, "submit", phxEvent, view, e.target, [
+ "push",
+ { submitter: e.submitter }
+ ]);
});
- }, false);
- for (let type of ["change", "input"]) {
+ });
+ for (const 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 (e instanceof CustomEvent && (e.target instanceof HTMLInputElement || e.target instanceof HTMLSelectElement || e.target instanceof HTMLTextAreaElement) && e.target.form === void 0) {
+ if (e.detail && e.detail.dispatcher) {
+ throw new Error(`dispatching a custom ${type} event is only supported on input elements inside a form`);
+ }
+ return;
+ }
+ const phxChange = this.binding("change");
+ const input = e.target;
+ if (this.blockPhxChangeWhileComposing && e.isComposing) {
+ const key = `composition-listener-${type}`;
+ if (!dom_default.private(input, key)) {
+ dom_default.putPrivate(input, key, true);
+ input.addEventListener("compositionend", () => {
+ input.dispatchEvent(new Event(type, { bubbles: true }));
+ dom_default.deletePrivate(input, key);
+ }, { once: true });
+ }
+ return;
+ }
+ const inputEvent = input.getAttribute(phxChange);
+ const formEvent = input.form && input.form.getAttribute(phxChange);
+ const 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;
+ const dispatcher = inputEvent ? input : input.form;
+ const currentIterations = iterations;
iterations++;
- let { at, type: lastType } = dom_default.private(input, "prev-iteration") || {};
+ const { 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 });
+ 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 }]);
+ js_default.exec(e, "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 }));
- });
+ const form = e.target;
+ dom_default.resetForm(form);
+ const input = Array.from(form.elements).find((el) => el.type === "reset");
+ if (input) {
+ 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();
+ const phxDebounce = this.binding(PHX_DEBOUNCE);
+ const phxThrottle = this.binding(PHX_THROTTLE);
+ const defaultDebounce = this.defaults.debounce.toString();
+ const defaultThrottle = this.defaults.throttle.toString();
this.withinOwners(el, (view) => {
- let asyncFilter = () => !view.isDestroyed() && document.body.contains(el);
+ const asyncFilter = () => !view.isDestroyed() && document.body.contains(el);
dom_default.debounce(el, event, phxDebounce, defaultDebounce, phxThrottle, defaultThrottle, asyncFilter, () => {
callback();
});
@@ -4521,16 +5963,22 @@ within:
this.silenced = false;
}
on(event, callback) {
+ this.boundEventNames.add(event);
window.addEventListener(event, (e) => {
if (!this.silenced) {
callback(e);
}
});
}
+ jsQuerySelectorAll(sourceEl, query, defaultQuery) {
+ const all = this.domCallbacks.jsQuerySelectorAll;
+ return all ? all(sourceEl, query, defaultQuery) : defaultQuery();
+ }
};
var TransitionSet = class {
constructor() {
- this.transitions = new Set();
+ this.transitions = /* @__PURE__ */ new Set();
+ this.promises = /* @__PURE__ */ new Set();
this.pendingOps = [];
}
reset() {
@@ -4538,6 +5986,7 @@ within:
clearTimeout(timer);
this.transitions.delete(timer);
});
+ this.promises.clear();
this.flushPendingOps();
}
after(callback) {
@@ -4549,30 +5998,38 @@ within:
}
addTransition(time, onStart, onDone) {
onStart();
- let timer = setTimeout(() => {
+ const timer = setTimeout(() => {
this.transitions.delete(timer);
onDone();
this.flushPendingOps();
}, time);
this.transitions.add(timer);
}
+ addAsyncTransition(promise) {
+ this.promises.add(promise);
+ promise.then(() => {
+ this.promises.delete(promise);
+ this.flushPendingOps();
+ });
+ }
pushPendingOp(op) {
this.pendingOps.push(op);
}
size() {
- return this.transitions.size;
+ return this.transitions.size + this.promises.size;
}
flushPendingOps() {
if (this.size() > 0) {
return;
}
- let op = this.pendingOps.shift();
+ const op = this.pendingOps.shift();
if (op) {
op();
this.flushPendingOps();
}
}
};
+ var LiveSocket2 = LiveSocket;
// ../deps/phoenix/priv/static/phoenix.mjs
var closure2 = (value) => {
@@ -4587,7 +6044,7 @@ within:
};
var globalSelf = typeof self !== "undefined" ? self : null;
var phxWindow = typeof window !== "undefined" ? window : null;
- var global = globalSelf || phxWindow || global;
+ var global = globalSelf || phxWindow || globalThis;
var DEFAULT_VSN = "2.0.0";
var SOCKET_STATES = { connecting: 0, open: 1, closing: 2, closed: 3 };
var DEFAULT_TIMEOUT = 1e4;
@@ -4613,6 +6070,7 @@ within:
var XHR_STATES = {
complete: 4
};
+ var AUTH_TOKEN_PREFIX = "base64url.bearer.phx.";
var Push = class {
constructor(channel, event, payload, timeout) {
this.channel = channel;
@@ -4903,14 +6361,39 @@ within:
}
};
var Ajax = class {
- static request(method, endPoint, accept, body, timeout, ontimeout, callback) {
+ static request(method, endPoint, headers, body, timeout, ontimeout, callback) {
if (global.XDomainRequest) {
let req = new global.XDomainRequest();
return this.xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback);
- } else {
+ } else if (global.XMLHttpRequest) {
let req = new global.XMLHttpRequest();
- return this.xhrRequest(req, method, endPoint, accept, body, timeout, ontimeout, callback);
+ return this.xhrRequest(req, method, endPoint, headers, body, timeout, ontimeout, callback);
+ } else if (global.fetch && global.AbortController) {
+ return this.fetchRequest(method, endPoint, headers, body, timeout, ontimeout, callback);
+ } else {
+ throw new Error("No suitable XMLHttpRequest implementation found");
+ }
+ }
+ static fetchRequest(method, endPoint, headers, body, timeout, ontimeout, callback) {
+ let options = {
+ method,
+ headers,
+ body
+ };
+ let controller = null;
+ if (timeout) {
+ controller = new AbortController();
+ const _timeoutId = setTimeout(() => controller.abort(), timeout);
+ options.signal = controller.signal;
}
+ global.fetch(endPoint, options).then((response) => response.text()).then((data) => this.parseJSON(data)).then((data) => callback && callback(data)).catch((err) => {
+ if (err.name === "AbortError" && ontimeout) {
+ ontimeout();
+ } else {
+ callback && callback(null);
+ }
+ });
+ return controller;
}
static xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback) {
req.timeout = timeout;
@@ -4927,10 +6410,12 @@ within:
req.send(body);
return req;
}
- static xhrRequest(req, method, endPoint, accept, body, timeout, ontimeout, callback) {
+ static xhrRequest(req, method, endPoint, headers, body, timeout, ontimeout, callback) {
req.open(method, endPoint, true);
req.timeout = timeout;
- req.setRequestHeader("Content-Type", accept);
+ for (let [key, value] of Object.entries(headers)) {
+ req.setRequestHeader(key, value);
+ }
req.onerror = () => callback && callback(null);
req.onreadystatechange = () => {
if (req.readyState === XHR_STATES.complete && callback) {
@@ -4989,7 +6474,10 @@ within:
return btoa(binary);
};
var LongPoll = class {
- constructor(endPoint) {
+ constructor(endPoint, protocols) {
+ if (protocols && protocols.length === 2 && protocols[1].startsWith(AUTH_TOKEN_PREFIX)) {
+ this.authToken = atob(protocols[1].slice(AUTH_TOKEN_PREFIX.length));
+ }
this.endPoint = null;
this.token = null;
this.skipHeartbeat = true;
@@ -5008,7 +6496,7 @@ within:
};
this.pollEndpoint = this.normalizeEndpoint(endPoint);
this.readyState = SOCKET_STATES.connecting;
- this.poll();
+ setTimeout(() => this.poll(), 0);
}
normalizeEndpoint(endPoint) {
return endPoint.replace("ws://", "http://").replace("wss://", "https://").replace(new RegExp("(.*)/" + TRANSPORTS.websocket), "$1/" + TRANSPORTS.longpoll);
@@ -5028,7 +6516,11 @@ within:
return this.readyState === SOCKET_STATES.open || this.readyState === SOCKET_STATES.connecting;
}
poll() {
- this.ajax("GET", "application/json", null, () => this.ontimeout(), (resp) => {
+ const headers = { "Accept": "application/json" };
+ if (this.authToken) {
+ headers["X-Phoenix-AuthToken"] = this.authToken;
+ }
+ this.ajax("GET", headers, null, () => this.ontimeout(), (resp) => {
if (resp) {
var { status, token, messages } = resp;
this.token = token;
@@ -5082,7 +6574,7 @@ within:
}
batchSend(messages) {
this.awaitingBatchAck = true;
- this.ajax("POST", "application/x-ndjson", messages.join("\n"), () => this.onerror("timeout"), (resp) => {
+ this.ajax("POST", { "Content-Type": "application/x-ndjson" }, messages.join("\n"), () => this.onerror("timeout"), (resp) => {
this.awaitingBatchAck = false;
if (!resp || resp.status !== 200) {
this.onerror(resp && resp.status);
@@ -5108,13 +6600,13 @@ within:
this.onclose(opts);
}
}
- ajax(method, contentType, body, onCallerTimeout, callback) {
+ ajax(method, headers, body, onCallerTimeout, callback) {
let req;
let ontimeout = () => {
this.reqs.delete(req);
onCallerTimeout();
};
- req = Ajax.request(method, this.endpointURL(), contentType, body, this.timeout, ontimeout, (resp) => {
+ req = Ajax.request(method, this.endpointURL(), headers, body, this.timeout, ontimeout, (resp) => {
this.reqs.delete(req);
if (this.isActive()) {
callback(resp);
@@ -5228,10 +6720,15 @@ within:
this.ref = 0;
this.timeout = opts.timeout || DEFAULT_TIMEOUT;
this.transport = opts.transport || global.WebSocket || LongPoll;
+ this.primaryPassedHealthCheck = false;
+ this.longPollFallbackMs = opts.longPollFallbackMs;
+ this.fallbackTimer = null;
+ this.sessionStore = opts.sessionStorage || global && global.sessionStorage;
this.establishedConnections = 0;
this.defaultEncoder = serializer_default.encode.bind(serializer_default);
this.defaultDecoder = serializer_default.decode.bind(serializer_default);
this.closeWasClean = false;
+ this.disconnecting = false;
this.binaryType = opts.binaryType || "arraybuffer";
this.connectClock = 1;
if (this.transport !== LongPoll) {
@@ -5272,6 +6769,11 @@ within:
}
};
this.logger = opts.logger || null;
+ if (!this.logger && opts.debug) {
+ this.logger = (kind, msg, data) => {
+ console.log(`${kind}: ${msg}`, data);
+ };
+ }
this.longpollerTimeout = opts.longpollerTimeout || 2e4;
this.params = closure2(opts.params || {});
this.endPoint = `${endPoint}/${TRANSPORTS.websocket}`;
@@ -5282,6 +6784,7 @@ within:
this.reconnectTimer = new Timer(() => {
this.teardown(() => this.connect());
}, this.reconnectAfterMs);
+ this.authToken = opts.authToken;
}
getLongPollTransport() {
return LongPoll;
@@ -5289,8 +6792,8 @@ within:
replaceTransport(newTransport) {
this.connectClock++;
this.closeWasClean = true;
+ clearTimeout(this.fallbackTimer);
this.reconnectTimer.reset();
- this.sendBuffer = [];
if (this.conn) {
this.conn.close();
this.conn = null;
@@ -5312,30 +6815,31 @@ within:
}
disconnect(callback, code, reason) {
this.connectClock++;
+ this.disconnecting = true;
this.closeWasClean = true;
+ clearTimeout(this.fallbackTimer);
this.reconnectTimer.reset();
- this.teardown(callback, code, reason);
+ this.teardown(() => {
+ this.disconnecting = false;
+ callback && 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 = closure2(params);
}
- if (this.conn) {
+ if (this.conn && !this.disconnecting) {
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);
+ if (this.longPollFallbackMs && this.transport !== LongPoll) {
+ this.connectWithFallback(LongPoll, this.longPollFallbackMs);
+ } else {
+ this.transportConnect();
+ }
}
log(kind, msg, data) {
- this.logger(kind, msg, data);
+ this.logger && this.logger(kind, msg, data);
}
hasLogger() {
return this.logger !== null;
@@ -5375,14 +6879,77 @@ within:
});
return true;
}
+ transportConnect() {
+ this.connectClock++;
+ this.closeWasClean = false;
+ let protocols = void 0;
+ if (this.authToken) {
+ protocols = ["phoenix", `${AUTH_TOKEN_PREFIX}${btoa(this.authToken).replace(/=/g, "")}`];
+ }
+ this.conn = new this.transport(this.endPointURL(), protocols);
+ 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);
+ }
+ getSession(key) {
+ return this.sessionStore && this.sessionStore.getItem(key);
+ }
+ storeSession(key, val) {
+ this.sessionStore && this.sessionStore.setItem(key, val);
+ }
+ connectWithFallback(fallbackTransport, fallbackThreshold = 2500) {
+ clearTimeout(this.fallbackTimer);
+ let established = false;
+ let primaryTransport = true;
+ let openRef, errorRef;
+ let fallback = (reason) => {
+ this.log("transport", `falling back to ${fallbackTransport.name}...`, reason);
+ this.off([openRef, errorRef]);
+ primaryTransport = false;
+ this.replaceTransport(fallbackTransport);
+ this.transportConnect();
+ };
+ if (this.getSession(`phx:fallback:${fallbackTransport.name}`)) {
+ return fallback("memorized");
+ }
+ this.fallbackTimer = setTimeout(fallback, fallbackThreshold);
+ errorRef = this.onError((reason) => {
+ this.log("transport", "error", reason);
+ if (primaryTransport && !established) {
+ clearTimeout(this.fallbackTimer);
+ fallback(reason);
+ }
+ });
+ this.onOpen(() => {
+ established = true;
+ if (!primaryTransport) {
+ if (!this.primaryPassedHealthCheck) {
+ this.storeSession(`phx:fallback:${fallbackTransport.name}`, "true");
+ }
+ return this.log("transport", `established ${fallbackTransport.name} fallback`);
+ }
+ clearTimeout(this.fallbackTimer);
+ this.fallbackTimer = setTimeout(fallback, fallbackThreshold);
+ this.ping((rtt) => {
+ this.log("transport", "connected to primary after", rtt);
+ this.primaryPassedHealthCheck = true;
+ clearTimeout(this.fallbackTimer);
+ });
+ });
+ this.transportConnect();
+ }
clearHeartbeats() {
clearTimeout(this.heartbeatTimer);
clearTimeout(this.heartbeatTimeoutTimer);
}
onConnOpen() {
if (this.hasLogger())
- this.log("transport", `connected to ${this.endPointURL()}`);
+ this.log("transport", `${this.transport.name} connected to ${this.endPointURL()}`);
this.closeWasClean = false;
+ this.disconnecting = false;
this.establishedConnections++;
this.flushSendBuffer();
this.reconnectTimer.reset();
@@ -5412,7 +6979,11 @@ within:
if (!this.conn) {
return callback && callback();
}
+ let connectClock = this.connectClock;
this.waitForBufferDone(() => {
+ if (connectClock !== this.connectClock) {
+ return;
+ }
if (this.conn) {
if (code) {
this.conn.close(code, reason || "");
@@ -5421,6 +6992,9 @@ within:
}
}
this.waitForSocketClosed(() => {
+ if (connectClock !== this.connectClock) {
+ return;
+ }
if (this.conn) {
this.conn.onopen = function() {
};
@@ -5501,7 +7075,7 @@ within:
}
remove(channel) {
this.off(channel.stateChangeRefs);
- this.channels = this.channels.filter((c) => c.joinRef() !== channel.joinRef());
+ this.channels = this.channels.filter((c) => c !== channel);
}
off(refs) {
for (let key in this.stateChangeCallbacks) {
@@ -6379,7 +7953,7 @@ within:
// js/app.js
var csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content");
- var liveSocket = new LiveSocket("/live", Socket, {
+ var liveSocket = new LiveSocket2("/live", Socket, {
params: { _csrf_token: csrfToken }
});
liveSocket.connect();
@@ -6391,7 +7965,7 @@ within:
const today = new Date();
return day == today.getDate() && month == today.getMonth() + 1;
};
- var PADDY = [3, 18];
+ var PADDY = [3, 17];
if (isToday(...PADDY)) {
document.querySelector("body").classList.add("paddy");
}
@@ -6409,4 +7983,4 @@ within:
}
notifications_default();
})();
-//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vZGVwcy9waG9lbml4X2h0bWwvcHJpdi9zdGF0aWMvcGhvZW5peF9odG1sLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L2NvbnN0YW50cy5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy9lbnRyeV91cGxvYWRlci5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy91dGlscy5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy9icm93c2VyLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L2RvbS5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy91cGxvYWRfZW50cnkuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvanMvcGhvZW5peF9saXZlX3ZpZXcvbGl2ZV91cGxvYWRlci5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy9hcmlhLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L2hvb2tzLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L2RvbV9wb3N0X21vcnBoX3Jlc3RvcmVyLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL25vZGVfbW9kdWxlcy9tb3JwaGRvbS9kaXN0L21vcnBoZG9tLWVzbS5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy9kb21fcGF0Y2guanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvanMvcGhvZW5peF9saXZlX3ZpZXcvcmVuZGVyZWQuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvanMvcGhvZW5peF9saXZlX3ZpZXcvdmlld19ob29rLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L2pzLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L3ZpZXcuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvanMvcGhvZW5peF9saXZlX3ZpZXcvbGl2ZV9zb2NrZXQuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4L2Fzc2V0cy9qcy9waG9lbml4L3V0aWxzLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peC9hc3NldHMvanMvcGhvZW5peC9jb25zdGFudHMuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4L2Fzc2V0cy9qcy9waG9lbml4L3B1c2guanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4L2Fzc2V0cy9qcy9waG9lbml4L3RpbWVyLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peC9hc3NldHMvanMvcGhvZW5peC9jaGFubmVsLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peC9hc3NldHMvanMvcGhvZW5peC9hamF4LmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peC9hc3NldHMvanMvcGhvZW5peC9sb25ncG9sbC5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXgvYXNzZXRzL2pzL3Bob2VuaXgvcHJlc2VuY2UuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4L2Fzc2V0cy9qcy9waG9lbml4L3NlcmlhbGl6ZXIuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4L2Fzc2V0cy9qcy9waG9lbml4L3NvY2tldC5qcyIsICIuLi8uLi8uLi9hc3NldHMvanMvZ2hvc3QuanMiLCAiLi4vLi4vLi4vYXNzZXRzL25vZGVfbW9kdWxlcy9jYW52YXMtY29uZmV0dGkvZGlzdC9jb25mZXR0aS5tb2R1bGUubWpzIiwgIi4uLy4uLy4uL2Fzc2V0cy9qcy9ub3RpZmljYXRpb25zLmpzIiwgIi4uLy4uLy4uL2Fzc2V0cy9qcy9hcHAuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIlwidXNlIHN0cmljdFwiO1xuXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBQb2x5ZmlsbEV2ZW50ID0gZXZlbnRDb25zdHJ1Y3RvcigpO1xuXG4gIGZ1bmN0aW9uIGV2ZW50Q29uc3RydWN0b3IoKSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cuQ3VzdG9tRXZlbnQgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHdpbmRvdy5DdXN0b21FdmVudDtcbiAgICAvLyBJRTw9OSBTdXBwb3J0XG4gICAgZnVuY3Rpb24gQ3VzdG9tRXZlbnQoZXZlbnQsIHBhcmFtcykge1xuICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHtidWJibGVzOiBmYWxzZSwgY2FuY2VsYWJsZTogZmFsc2UsIGRldGFpbDogdW5kZWZpbmVkfTtcbiAgICAgIHZhciBldnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnQ3VzdG9tRXZlbnQnKTtcbiAgICAgIGV2dC5pbml0Q3VzdG9tRXZlbnQoZXZlbnQsIHBhcmFtcy5idWJibGVzLCBwYXJhbXMuY2FuY2VsYWJsZSwgcGFyYW1zLmRldGFpbCk7XG4gICAgICByZXR1cm4gZXZ0O1xuICAgIH1cbiAgICBDdXN0b21FdmVudC5wcm90b3R5cGUgPSB3aW5kb3cuRXZlbnQucHJvdG90eXBlO1xuICAgIHJldHVybiBDdXN0b21FdmVudDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGJ1aWxkSGlkZGVuSW5wdXQobmFtZSwgdmFsdWUpIHtcbiAgICB2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIik7XG4gICAgaW5wdXQudHlwZSA9IFwiaGlkZGVuXCI7XG4gICAgaW5wdXQubmFtZSA9IG5hbWU7XG4gICAgaW5wdXQudmFsdWUgPSB2YWx1ZTtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVDbGljayhlbGVtZW50LCB0YXJnZXRNb2RpZmllcktleSkge1xuICAgIHZhciB0byA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGF0YS10b1wiKSxcbiAgICAgICAgbWV0aG9kID0gYnVpbGRIaWRkZW5JbnB1dChcIl9tZXRob2RcIiwgZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJkYXRhLW1ldGhvZFwiKSksXG4gICAgICAgIGNzcmYgPSBidWlsZEhpZGRlbklucHV0KFwiX2NzcmZfdG9rZW5cIiwgZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJkYXRhLWNzcmZcIikpLFxuICAgICAgICBmb3JtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImZvcm1cIiksXG4gICAgICAgIHN1Ym1pdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbnB1dFwiKSxcbiAgICAgICAgdGFyZ2V0ID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJ0YXJnZXRcIik7XG5cbiAgICBmb3JtLm1ldGhvZCA9IChlbGVtZW50LmdldEF0dHJpYnV0ZShcImRhdGEtbWV0aG9kXCIpID09PSBcImdldFwiKSA/IFwiZ2V0XCIgOiBcInBvc3RcIjtcbiAgICBmb3JtLmFjdGlvbiA9IHRvO1xuICAgIGZvcm0uc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuXG4gICAgaWYgKHRhcmdldCkgZm9ybS50YXJnZXQgPSB0YXJnZXQ7XG4gICAgZWxzZSBpZiAodGFyZ2V0TW9kaWZpZXJLZXkpIGZvcm0udGFyZ2V0ID0gXCJfYmxhbmtcIjtcblxuICAgIGZvcm0uYXBwZW5kQ2hpbGQoY3NyZik7XG4gICAgZm9ybS5hcHBlbmRDaGlsZChtZXRob2QpO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZm9ybSk7XG5cbiAgICAvLyBJbnNlcnQgYSBidXR0b24gYW5kIGNsaWNrIGl0IGluc3RlYWQgb2YgdXNpbmcgYGZvcm0uc3VibWl0YFxuICAgIC8vIGJlY2F1c2UgdGhlIGBzdWJtaXRgIGZ1bmN0aW9uIGRvZXMgbm90IGVtaXQgYSBgc3VibWl0YCBldmVudC5cbiAgICBzdWJtaXQudHlwZSA9IFwic3VibWl0XCI7XG4gICAgZm9ybS5hcHBlbmRDaGlsZChzdWJtaXQpO1xuICAgIHN1Ym1pdC5jbGljaygpO1xuICB9XG5cbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBmdW5jdGlvbihlKSB7XG4gICAgdmFyIGVsZW1lbnQgPSBlLnRhcmdldDtcbiAgICBpZiAoZS5kZWZhdWx0UHJldmVudGVkKSByZXR1cm47XG5cbiAgICB3aGlsZSAoZWxlbWVudCAmJiBlbGVtZW50LmdldEF0dHJpYnV0ZSkge1xuICAgICAgdmFyIHBob2VuaXhMaW5rRXZlbnQgPSBuZXcgUG9seWZpbGxFdmVudCgncGhvZW5peC5saW5rLmNsaWNrJywge1xuICAgICAgICBcImJ1YmJsZXNcIjogdHJ1ZSwgXCJjYW5jZWxhYmxlXCI6IHRydWVcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoIWVsZW1lbnQuZGlzcGF0Y2hFdmVudChwaG9lbml4TGlua0V2ZW50KSkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGF0YS1tZXRob2RcIikpIHtcbiAgICAgICAgaGFuZGxlQ2xpY2soZWxlbWVudCwgZS5tZXRhS2V5IHx8IGUuc2hpZnRLZXkpO1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudE5vZGU7XG4gICAgICB9XG4gICAgfVxuICB9LCBmYWxzZSk7XG5cbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Bob2VuaXgubGluay5jbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgdmFyIG1lc3NhZ2UgPSBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoXCJkYXRhLWNvbmZpcm1cIik7XG4gICAgaWYobWVzc2FnZSAmJiAhd2luZG93LmNvbmZpcm0obWVzc2FnZSkpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gIH0sIGZhbHNlKTtcbn0pKCk7XG4iLCAiZXhwb3J0IGNvbnN0IENPTlNFQ1VUSVZFX1JFTE9BRFMgPSBcImNvbnNlY3V0aXZlLXJlbG9hZHNcIlxuZXhwb3J0IGNvbnN0IE1BWF9SRUxPQURTID0gMTBcbmV4cG9ydCBjb25zdCBSRUxPQURfSklUVEVSX01JTiA9IDUwMDBcbmV4cG9ydCBjb25zdCBSRUxPQURfSklUVEVSX01BWCA9IDEwMDAwXG5leHBvcnQgY29uc3QgRkFJTFNBRkVfSklUVEVSID0gMzAwMDBcbmV4cG9ydCBjb25zdCBQSFhfRVZFTlRfQ0xBU1NFUyA9IFtcbiAgXCJwaHgtY2xpY2stbG9hZGluZ1wiLCBcInBoeC1jaGFuZ2UtbG9hZGluZ1wiLCBcInBoeC1zdWJtaXQtbG9hZGluZ1wiLFxuICBcInBoeC1rZXlkb3duLWxvYWRpbmdcIiwgXCJwaHgta2V5dXAtbG9hZGluZ1wiLCBcInBoeC1ibHVyLWxvYWRpbmdcIiwgXCJwaHgtZm9jdXMtbG9hZGluZ1wiXG5dXG5leHBvcnQgY29uc3QgUEhYX0NPTVBPTkVOVCA9IFwiZGF0YS1waHgtY29tcG9uZW50XCJcbmV4cG9ydCBjb25zdCBQSFhfTElWRV9MSU5LID0gXCJkYXRhLXBoeC1saW5rXCJcbmV4cG9ydCBjb25zdCBQSFhfVFJBQ0tfU1RBVElDID0gXCJ0cmFjay1zdGF0aWNcIlxuZXhwb3J0IGNvbnN0IFBIWF9MSU5LX1NUQVRFID0gXCJkYXRhLXBoeC1saW5rLXN0YXRlXCJcbmV4cG9ydCBjb25zdCBQSFhfUkVGID0gXCJkYXRhLXBoeC1yZWZcIlxuZXhwb3J0IGNvbnN0IFBIWF9SRUZfU1JDID0gXCJkYXRhLXBoeC1yZWYtc3JjXCJcbmV4cG9ydCBjb25zdCBQSFhfVFJBQ0tfVVBMT0FEUyA9IFwidHJhY2stdXBsb2Fkc1wiXG5leHBvcnQgY29uc3QgUEhYX1VQTE9BRF9SRUYgPSBcImRhdGEtcGh4LXVwbG9hZC1yZWZcIlxuZXhwb3J0IGNvbnN0IFBIWF9QUkVGTElHSFRFRF9SRUZTID0gXCJkYXRhLXBoeC1wcmVmbGlnaHRlZC1yZWZzXCJcbmV4cG9ydCBjb25zdCBQSFhfRE9ORV9SRUZTID0gXCJkYXRhLXBoeC1kb25lLXJlZnNcIlxuZXhwb3J0IGNvbnN0IFBIWF9EUk9QX1RBUkdFVCA9IFwiZHJvcC10YXJnZXRcIlxuZXhwb3J0IGNvbnN0IFBIWF9BQ1RJVkVfRU5UUllfUkVGUyA9IFwiZGF0YS1waHgtYWN0aXZlLXJlZnNcIlxuZXhwb3J0IGNvbnN0IFBIWF9MSVZFX0ZJTEVfVVBEQVRFRCA9IFwicGh4OmxpdmUtZmlsZTp1cGRhdGVkXCJcbmV4cG9ydCBjb25zdCBQSFhfU0tJUCA9IFwiZGF0YS1waHgtc2tpcFwiXG5leHBvcnQgY29uc3QgUEhYX1BSVU5FID0gXCJkYXRhLXBoeC1wcnVuZVwiXG5leHBvcnQgY29uc3QgUEhYX1BBR0VfTE9BRElORyA9IFwicGFnZS1sb2FkaW5nXCJcbmV4cG9ydCBjb25zdCBQSFhfQ09OTkVDVEVEX0NMQVNTID0gXCJwaHgtY29ubmVjdGVkXCJcbmV4cG9ydCBjb25zdCBQSFhfTE9BRElOR19DTEFTUyA9IFwicGh4LWxvYWRpbmdcIlxuZXhwb3J0IGNvbnN0IFBIWF9OT19GRUVEQkFDS19DTEFTUyA9IFwicGh4LW5vLWZlZWRiYWNrXCJcbmV4cG9ydCBjb25zdCBQSFhfRVJST1JfQ0xBU1MgPSBcInBoeC1lcnJvclwiXG5leHBvcnQgY29uc3QgUEhYX0NMSUVOVF9FUlJPUl9DTEFTUyA9IFwicGh4LWNsaWVudC1lcnJvclwiXG5leHBvcnQgY29uc3QgUEhYX1NFUlZFUl9FUlJPUl9DTEFTUyA9IFwicGh4LXNlcnZlci1lcnJvclwiXG5leHBvcnQgY29uc3QgUEhYX1BBUkVOVF9JRCA9IFwiZGF0YS1waHgtcGFyZW50LWlkXCJcbmV4cG9ydCBjb25zdCBQSFhfTUFJTiA9IFwiZGF0YS1waHgtbWFpblwiXG5leHBvcnQgY29uc3QgUEhYX1JPT1RfSUQgPSBcImRhdGEtcGh4LXJvb3QtaWRcIlxuZXhwb3J0IGNvbnN0IFBIWF9WSUVXUE9SVF9UT1AgPSBcInZpZXdwb3J0LXRvcFwiXG5leHBvcnQgY29uc3QgUEhYX1ZJRVdQT1JUX0JPVFRPTSA9IFwidmlld3BvcnQtYm90dG9tXCJcbmV4cG9ydCBjb25zdCBQSFhfVFJJR0dFUl9BQ1RJT04gPSBcInRyaWdnZXItYWN0aW9uXCJcbmV4cG9ydCBjb25zdCBQSFhfRkVFREJBQ0tfRk9SID0gXCJmZWVkYmFjay1mb3JcIlxuZXhwb3J0IGNvbnN0IFBIWF9IQVNfRk9DVVNFRCA9IFwicGh4LWhhcy1mb2N1c2VkXCJcbmV4cG9ydCBjb25zdCBGT0NVU0FCTEVfSU5QVVRTID0gW1widGV4dFwiLCBcInRleHRhcmVhXCIsIFwibnVtYmVyXCIsIFwiZW1haWxcIiwgXCJwYXNzd29yZFwiLCBcInNlYXJjaFwiLCBcInRlbFwiLCBcInVybFwiLCBcImRhdGVcIiwgXCJ0aW1lXCIsIFwiZGF0ZXRpbWUtbG9jYWxcIiwgXCJjb2xvclwiLCBcInJhbmdlXCJdXG5leHBvcnQgY29uc3QgQ0hFQ0tBQkxFX0lOUFVUUyA9IFtcImNoZWNrYm94XCIsIFwicmFkaW9cIl1cbmV4cG9ydCBjb25zdCBQSFhfSEFTX1NVQk1JVFRFRCA9IFwicGh4LWhhcy1zdWJtaXR0ZWRcIlxuZXhwb3J0IGNvbnN0IFBIWF9TRVNTSU9OID0gXCJkYXRhLXBoeC1zZXNzaW9uXCJcbmV4cG9ydCBjb25zdCBQSFhfVklFV19TRUxFQ1RPUiA9IGBbJHtQSFhfU0VTU0lPTn1dYFxuZXhwb3J0IGNvbnN0IFBIWF9TVElDS1kgPSBcImRhdGEtcGh4LXN0aWNreVwiXG5leHBvcnQgY29uc3QgUEhYX1NUQVRJQyA9IFwiZGF0YS1waHgtc3RhdGljXCJcbmV4cG9ydCBjb25zdCBQSFhfUkVBRE9OTFkgPSBcImRhdGEtcGh4LXJlYWRvbmx5XCJcbmV4cG9ydCBjb25zdCBQSFhfRElTQUJMRUQgPSBcImRhdGEtcGh4LWRpc2FibGVkXCJcbmV4cG9ydCBjb25zdCBQSFhfRElTQUJMRV9XSVRIID0gXCJkaXNhYmxlLXdpdGhcIlxuZXhwb3J0IGNvbnN0IFBIWF9ESVNBQkxFX1dJVEhfUkVTVE9SRSA9IFwiZGF0YS1waHgtZGlzYWJsZS13aXRoLXJlc3RvcmVcIlxuZXhwb3J0IGNvbnN0IFBIWF9IT09LID0gXCJob29rXCJcbmV4cG9ydCBjb25zdCBQSFhfREVCT1VOQ0UgPSBcImRlYm91bmNlXCJcbmV4cG9ydCBjb25zdCBQSFhfVEhST1RUTEUgPSBcInRocm90dGxlXCJcbmV4cG9ydCBjb25zdCBQSFhfVVBEQVRFID0gXCJ1cGRhdGVcIlxuZXhwb3J0IGNvbnN0IFBIWF9TVFJFQU0gPSBcInN0cmVhbVwiXG5leHBvcnQgY29uc3QgUEhYX1NUUkVBTV9SRUYgPSBcImRhdGEtcGh4LXN0cmVhbVwiXG5leHBvcnQgY29uc3QgUEhYX0tFWSA9IFwia2V5XCJcbmV4cG9ydCBjb25zdCBQSFhfUFJJVkFURSA9IFwicGh4UHJpdmF0ZVwiXG5leHBvcnQgY29uc3QgUEhYX0FVVE9fUkVDT1ZFUiA9IFwiYXV0by1yZWNvdmVyXCJcbmV4cG9ydCBjb25zdCBQSFhfTFZfREVCVUcgPSBcInBoeDpsaXZlLXNvY2tldDpkZWJ1Z1wiXG5leHBvcnQgY29uc3QgUEhYX0xWX1BST0ZJTEUgPSBcInBoeDpsaXZlLXNvY2tldDpwcm9maWxpbmdcIlxuZXhwb3J0IGNvbnN0IFBIWF9MVl9MQVRFTkNZX1NJTSA9IFwicGh4OmxpdmUtc29ja2V0OmxhdGVuY3ktc2ltXCJcbmV4cG9ydCBjb25zdCBQSFhfUFJPR1JFU1MgPSBcInByb2dyZXNzXCJcbmV4cG9ydCBjb25zdCBQSFhfTU9VTlRFRCA9IFwibW91bnRlZFwiXG5leHBvcnQgY29uc3QgTE9BREVSX1RJTUVPVVQgPSAxXG5leHBvcnQgY29uc3QgQkVGT1JFX1VOTE9BRF9MT0FERVJfVElNRU9VVCA9IDIwMFxuZXhwb3J0IGNvbnN0IEJJTkRJTkdfUFJFRklYID0gXCJwaHgtXCJcbmV4cG9ydCBjb25zdCBQVVNIX1RJTUVPVVQgPSAzMDAwMFxuZXhwb3J0IGNvbnN0IExJTktfSEVBREVSID0gXCJ4LXJlcXVlc3RlZC13aXRoXCJcbmV4cG9ydCBjb25zdCBSRVNQT05TRV9VUkxfSEVBREVSID0gXCJ4LXJlc3BvbnNlLXVybFwiXG5leHBvcnQgY29uc3QgREVCT1VOQ0VfVFJJR0dFUiA9IFwiZGVib3VuY2UtdHJpZ2dlclwiXG5leHBvcnQgY29uc3QgVEhST1RUTEVEID0gXCJ0aHJvdHRsZWRcIlxuZXhwb3J0IGNvbnN0IERFQk9VTkNFX1BSRVZfS0VZID0gXCJkZWJvdW5jZS1wcmV2LWtleVwiXG5leHBvcnQgY29uc3QgREVGQVVMVFMgPSB7XG4gIGRlYm91bmNlOiAzMDAsXG4gIHRocm90dGxlOiAzMDBcbn1cblxuLy8gUmVuZGVyZWRcbmV4cG9ydCBjb25zdCBEWU5BTUlDUyA9IFwiZFwiXG5leHBvcnQgY29uc3QgU1RBVElDID0gXCJzXCJcbmV4cG9ydCBjb25zdCBDT01QT05FTlRTID0gXCJjXCJcbmV4cG9ydCBjb25zdCBFVkVOVFMgPSBcImVcIlxuZXhwb3J0IGNvbnN0IFJFUExZID0gXCJyXCJcbmV4cG9ydCBjb25zdCBUSVRMRSA9IFwidFwiXG5leHBvcnQgY29uc3QgVEVNUExBVEVTID0gXCJwXCJcbmV4cG9ydCBjb25zdCBTVFJFQU0gPSBcInN0cmVhbVwiXG4iLCAiaW1wb3J0IHtcbiAgbG9nRXJyb3Jcbn0gZnJvbSBcIi4vdXRpbHNcIlxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBFbnRyeVVwbG9hZGVyIHtcbiAgY29uc3RydWN0b3IoZW50cnksIGNodW5rU2l6ZSwgbGl2ZVNvY2tldCl7XG4gICAgdGhpcy5saXZlU29ja2V0ID0gbGl2ZVNvY2tldFxuICAgIHRoaXMuZW50cnkgPSBlbnRyeVxuICAgIHRoaXMub2Zmc2V0ID0gMFxuICAgIHRoaXMuY2h1bmtTaXplID0gY2h1bmtTaXplXG4gICAgdGhpcy5jaHVua1RpbWVyID0gbnVsbFxuICAgIHRoaXMuZXJyb3JlZCA9IGZhbHNlXG4gICAgdGhpcy51cGxvYWRDaGFubmVsID0gbGl2ZVNvY2tldC5jaGFubmVsKGBsdnU6JHtlbnRyeS5yZWZ9YCwge3Rva2VuOiBlbnRyeS5tZXRhZGF0YSgpfSlcbiAgfVxuXG4gIGVycm9yKHJlYXNvbil7XG4gICAgaWYodGhpcy5lcnJvcmVkKXsgcmV0dXJuIH1cbiAgICB0aGlzLmVycm9yZWQgPSB0cnVlXG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuY2h1bmtUaW1lcilcbiAgICB0aGlzLmVudHJ5LmVycm9yKHJlYXNvbilcbiAgfVxuXG4gIHVwbG9hZCgpe1xuICAgIHRoaXMudXBsb2FkQ2hhbm5lbC5vbkVycm9yKHJlYXNvbiA9PiB0aGlzLmVycm9yKHJlYXNvbikpXG4gICAgdGhpcy51cGxvYWRDaGFubmVsLmpvaW4oKVxuICAgICAgLnJlY2VpdmUoXCJva1wiLCBfZGF0YSA9PiB0aGlzLnJlYWROZXh0Q2h1bmsoKSlcbiAgICAgIC5yZWNlaXZlKFwiZXJyb3JcIiwgcmVhc29uID0+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+IHtcbiAgICAgIGlmKCF0aGlzLnNpbGVuY2VkKXsgY2FsbGJhY2soZSkgfVxuICAgIH0pXG4gIH1cbn1cblxuY2xhc3MgVHJhbnNpdGlvblNldCB7XG4gIGNvbnN0cnVjdG9yKCl7XG4gICAgdGhpcy50cmFuc2l0aW9ucyA9IG5ldyBTZXQoKVxuICAgIHRoaXMucGVuZGluZ09wcyA9IFtdXG4gIH1cblxuICByZXNldCgpe1xuICAgIHRoaXMudHJhbnNpdGlvbnMuZm9yRWFjaCh0aW1lciA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXIpXG4gICAgICB0aGlzLnRyYW5zaXRpb25zLmRlbGV0ZSh0aW1lcilcbiAgICB9KVxuICAgIHRoaXMuZmx1c2hQZW5kaW5nT3BzKClcbiAgfVxuXG4gIGFmdGVyKGNhbGxiYWNrKXtcbiAgICBpZih0aGlzLnNpemUoKSA9PT0gMCl7XG4gICAgICBjYWxsYmFjaygpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHVzaFBlbmRpbmdPcChjYWxsYmFjaylcbiAgICB9XG4gIH1cblxuICBhZGRUcmFuc2l0aW9uKHRpbWUsIG9uU3RhcnQsIG9uRG9uZSl7XG4gICAgb25TdGFydCgpXG4gICAgbGV0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnRyYW5zaXRpb25zLmRlbGV0ZSh0aW1lcilcbiAgICAgIG9uRG9uZSgpXG4gICAgICB0aGlzLmZsdXNoUGVuZGluZ09wcygpXG4gICAgfSwgdGltZSlcbiAgICB0aGlzLnRyYW5zaXRpb25zLmFkZCh0aW1lcilcbiAgfVxuXG4gIHB1c2hQZW5kaW5nT3Aob3ApeyB0aGlzLnBlbmRpbmdPcHMucHVzaChvcCkgfVxuXG4gIHNpemUoKXsgcmV0dXJuIHRoaXMudHJhbnNpdGlvbnMuc2l6ZSB9XG5cbiAgZmx1c2hQZW5kaW5nT3BzKCl7XG4gICAgaWYodGhpcy5zaXplKCkgPiAwKXsgcmV0dXJuIH1cbiAgICBsZXQgb3AgPSB0aGlzLnBlbmRpbmdPcHMuc2hpZnQoKVxuICAgIGlmKG9wKXtcbiAgICAgIG9wKClcbiAgICAgIHRoaXMuZmx1c2hQZW5kaW5nT3BzKClcbiAgICB9XG4gIH1cbn1cbiIsICIvLyB3cmFwcyB2YWx1ZSBpbiBjbG9zdXJlIG9yIHJldHVybnMgY2xvc3VyZVxuZXhwb3J0IGxldCBjbG9zdXJlID0gKHZhbHVlKSA9PiB7XG4gIGlmKHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiKXtcbiAgICByZXR1cm4gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBsZXQgY2xvc3VyZSA9IGZ1bmN0aW9uICgpeyByZXR1cm4gdmFsdWUgfVxuICAgIHJldHVybiBjbG9zdXJlXG4gIH1cbn1cbiIsICJleHBvcnQgY29uc3QgZ2xvYmFsU2VsZiA9IHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IG51bGxcbmV4cG9ydCBjb25zdCBwaHhXaW5kb3cgPSB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDogbnVsbFxuZXhwb3J0IGNvbnN0IGdsb2JhbCA9IGdsb2JhbFNlbGYgfHwgcGh4V2luZG93IHx8IGdsb2JhbFxuZXhwb3J0IGNvbnN0IERFRkFVTFRfVlNOID0gXCIyLjAuMFwiXG5leHBvcnQgY29uc3QgU09DS0VUX1NUQVRFUyA9IHtjb25uZWN0aW5nOiAwLCBvcGVuOiAxLCBjbG9zaW5nOiAyLCBjbG9zZWQ6IDN9XG5leHBvcnQgY29uc3QgREVGQVVMVF9USU1FT1VUID0gMTAwMDBcbmV4cG9ydCBjb25zdCBXU19DTE9TRV9OT1JNQUwgPSAxMDAwXG5leHBvcnQgY29uc3QgQ0hBTk5FTF9TVEFURVMgPSB7XG4gIGNsb3NlZDogXCJjbG9zZWRcIixcbiAgZXJyb3JlZDogXCJlcnJvcmVkXCIsXG4gIGpvaW5lZDogXCJqb2luZWRcIixcbiAgam9pbmluZzogXCJqb2luaW5nXCIsXG4gIGxlYXZpbmc6IFwibGVhdmluZ1wiLFxufVxuZXhwb3J0IGNvbnN0IENIQU5ORUxfRVZFTlRTID0ge1xuICBjbG9zZTogXCJwaHhfY2xvc2VcIixcbiAgZXJyb3I6IFwicGh4X2Vycm9yXCIsXG4gIGpvaW46IFwicGh4X2pvaW5cIixcbiAgcmVwbHk6IFwicGh4X3JlcGx5XCIsXG4gIGxlYXZlOiBcInBoeF9sZWF2ZVwiXG59XG5cbmV4cG9ydCBjb25zdCBUUkFOU1BPUlRTID0ge1xuICBsb25ncG9sbDogXCJsb25ncG9sbFwiLFxuICB3ZWJzb2NrZXQ6IFwid2Vic29ja2V0XCJcbn1cbmV4cG9ydCBjb25zdCBYSFJfU1RBVEVTID0ge1xuICBjb21wbGV0ZTogNFxufVxuIiwgIi8qKlxuICogSW5pdGlhbGl6ZXMgdGhlIFB1c2hcbiAqIEBwYXJhbSB7Q2hhbm5lbH0gY2hhbm5lbCAtIFRoZSBDaGFubmVsXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnQgLSBUaGUgZXZlbnQsIGZvciBleGFtcGxlIGBcInBoeF9qb2luXCJgXG4gKiBAcGFyYW0ge09iamVjdH0gcGF5bG9hZCAtIFRoZSBwYXlsb2FkLCBmb3IgZXhhbXBsZSBge3VzZXJfaWQ6IDEyM31gXG4gKiBAcGFyYW0ge251bWJlcn0gdGltZW91dCAtIFRoZSBwdXNoIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFB1c2gge1xuICBjb25zdHJ1Y3RvcihjaGFubmVsLCBldmVudCwgcGF5bG9hZCwgdGltZW91dCl7XG4gICAgdGhpcy5jaGFubmVsID0gY2hhbm5lbFxuICAgIHRoaXMuZXZlbnQgPSBldmVudFxuICAgIHRoaXMucGF5bG9hZCA9IHBheWxvYWQgfHwgZnVuY3Rpb24gKCl7IHJldHVybiB7fSB9XG4gICAgdGhpcy5yZWNlaXZlZFJlc3AgPSBudWxsXG4gICAgdGhpcy50aW1lb3V0ID0gdGltZW91dFxuICAgIHRoaXMudGltZW91dFRpbWVyID0gbnVsbFxuICAgIHRoaXMucmVjSG9va3MgPSBbXVxuICAgIHRoaXMuc2VudCA9IGZhbHNlXG4gIH1cblxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXRcbiAgICovXG4gIHJlc2VuZCh0aW1lb3V0KXtcbiAgICB0aGlzLnRpbWVvdXQgPSB0aW1lb3V0XG4gICAgdGhpcy5yZXNldCgpXG4gICAgdGhpcy5zZW5kKClcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKi9cbiAgc2VuZCgpe1xuICAgIGlmKHRoaXMuaGFzUmVjZWl2ZWQoXCJ0aW1lb3V0XCIpKXsgcmV0dXJuIH1cbiAgICB0aGlzLnN0YXJ0VGltZW91dCgpXG4gICAgdGhpcy5zZW50ID0gdHJ1ZVxuICAgIHRoaXMuY2hhbm5lbC5zb2NrZXQucHVzaCh7XG4gICAgICB0b3BpYzogdGhpcy5jaGFubmVsLnRvcGljLFxuICAgICAgZXZlbnQ6IHRoaXMuZXZlbnQsXG4gICAgICBwYXlsb2FkOiB0aGlzLnBheWxvYWQoKSxcbiAgICAgIHJlZjogdGhpcy5yZWYsXG4gICAgICBqb2luX3JlZjogdGhpcy5jaGFubmVsLmpvaW5SZWYoKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHsqfSBzdGF0dXNcbiAgICogQHBhcmFtIHsqfSBjYWxsYmFja1xuICAgKi9cbiAgcmVjZWl2ZShzdGF0dXMsIGNhbGxiYWNrKXtcbiAgICBpZih0aGlzLmhhc1JlY2VpdmVkKHN0YXR1cykpe1xuICAgICAgY2FsbGJhY2sodGhpcy5yZWNlaXZlZFJlc3AucmVzcG9uc2UpXG4gICAgfVxuXG4gICAgdGhpcy5yZWNIb29rcy5wdXNoKHtzdGF0dXMsIGNhbGxiYWNrfSlcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICByZXNldCgpe1xuICAgIHRoaXMuY2FuY2VsUmVmRXZlbnQoKVxuICAgIHRoaXMucmVmID0gbnVsbFxuICAgIHRoaXMucmVmRXZlbnQgPSBudWxsXG4gICAgdGhpcy5yZWNlaXZlZFJlc3AgPSBudWxsXG4gICAgdGhpcy5zZW50ID0gZmFsc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgbWF0Y2hSZWNlaXZlKHtzdGF0dXMsIHJlc3BvbnNlLCBfcmVmfSl7XG4gICAgdGhpcy5yZWNIb29rcy5maWx0ZXIoaCA9PiBoLnN0YXR1cyA9PT0gc3RhdHVzKVxuICAgICAgLmZvckVhY2goaCA9PiBoLmNhbGxiYWNrKHJlc3BvbnNlKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgY2FuY2VsUmVmRXZlbnQoKXtcbiAgICBpZighdGhpcy5yZWZFdmVudCl7IHJldHVybiB9XG4gICAgdGhpcy5jaGFubmVsLm9mZih0aGlzLnJlZkV2ZW50KVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBjYW5jZWxUaW1lb3V0KCl7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZW91dFRpbWVyKVxuICAgIHRoaXMudGltZW91dFRpbWVyID0gbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBzdGFydFRpbWVvdXQoKXtcbiAgICBpZih0aGlzLnRpbWVvdXRUaW1lcil7IHRoaXMuY2FuY2VsVGltZW91dCgpIH1cbiAgICB0aGlzLnJlZiA9IHRoaXMuY2hhbm5lbC5zb2NrZXQubWFrZVJlZigpXG4gICAgdGhpcy5yZWZFdmVudCA9IHRoaXMuY2hhbm5lbC5yZXBseUV2ZW50TmFtZSh0aGlzLnJlZilcblxuICAgIHRoaXMuY2hhbm5lbC5vbih0aGlzLnJlZkV2ZW50LCBwYXlsb2FkID0+IHtcbiAgICAgIHRoaXMuY2FuY2VsUmVmRXZlbnQoKVxuICAgICAgdGhpcy5jYW5jZWxUaW1lb3V0KClcbiAgICAgIHRoaXMucmVjZWl2ZWRSZXNwID0gcGF5bG9hZFxuICAgICAgdGhpcy5tYXRjaFJlY2VpdmUocGF5bG9hZClcbiAgICB9KVxuXG4gICAgdGhpcy50aW1lb3V0VGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMudHJpZ2dlcihcInRpbWVvdXRcIiwge30pXG4gICAgfSwgdGhpcy50aW1lb3V0KVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBoYXNSZWNlaXZlZChzdGF0dXMpe1xuICAgIHJldHVybiB0aGlzLnJlY2VpdmVkUmVzcCAmJiB0aGlzLnJlY2VpdmVkUmVzcC5zdGF0dXMgPT09IHN0YXR1c1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICB0cmlnZ2VyKHN0YXR1cywgcmVzcG9uc2Upe1xuICAgIHRoaXMuY2hhbm5lbC50cmlnZ2VyKHRoaXMucmVmRXZlbnQsIHtzdGF0dXMsIHJlc3BvbnNlfSlcbiAgfVxufVxuIiwgIi8qKlxuICpcbiAqIENyZWF0ZXMgYSB0aW1lciB0aGF0IGFjY2VwdHMgYSBgdGltZXJDYWxjYCBmdW5jdGlvbiB0byBwZXJmb3JtXG4gKiBjYWxjdWxhdGVkIHRpbWVvdXQgcmV0cmllcywgc3VjaCBhcyBleHBvbmVudGlhbCBiYWNrb2ZmLlxuICpcbiAqIEBleGFtcGxlXG4gKiBsZXQgcmVjb25uZWN0VGltZXIgPSBuZXcgVGltZXIoKCkgPT4gdGhpcy5jb25uZWN0KCksIGZ1bmN0aW9uKHRyaWVzKXtcbiAqICAgcmV0dXJuIFsxMDAwLCA1MDAwLCAxMDAwMF1bdHJpZXMgLSAxXSB8fCAxMDAwMFxuICogfSlcbiAqIHJlY29ubmVjdFRpbWVyLnNjaGVkdWxlVGltZW91dCgpIC8vIGZpcmVzIGFmdGVyIDEwMDBcbiAqIHJlY29ubmVjdFRpbWVyLnNjaGVkdWxlVGltZW91dCgpIC8vIGZpcmVzIGFmdGVyIDUwMDBcbiAqIHJlY29ubmVjdFRpbWVyLnJlc2V0KClcbiAqIHJlY29ubmVjdFRpbWVyLnNjaGVkdWxlVGltZW91dCgpIC8vIGZpcmVzIGFmdGVyIDEwMDBcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICogQHBhcmFtIHtGdW5jdGlvbn0gdGltZXJDYWxjXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRpbWVyIHtcbiAgY29uc3RydWN0b3IoY2FsbGJhY2ssIHRpbWVyQ2FsYyl7XG4gICAgdGhpcy5jYWxsYmFjayA9IGNhbGxiYWNrXG4gICAgdGhpcy50aW1lckNhbGMgPSB0aW1lckNhbGNcbiAgICB0aGlzLnRpbWVyID0gbnVsbFxuICAgIHRoaXMudHJpZXMgPSAwXG4gIH1cblxuICByZXNldCgpe1xuICAgIHRoaXMudHJpZXMgPSAwXG4gICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpXG4gIH1cblxuICAvKipcbiAgICogQ2FuY2VscyBhbnkgcHJldmlvdXMgc2NoZWR1bGVUaW1lb3V0IGFuZCBzY2hlZHVsZXMgY2FsbGJhY2tcbiAgICovXG4gIHNjaGVkdWxlVGltZW91dCgpe1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVyKVxuXG4gICAgdGhpcy50aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy50cmllcyA9IHRoaXMudHJpZXMgKyAxXG4gICAgICB0aGlzLmNhbGxiYWNrKClcbiAgICB9LCB0aGlzLnRpbWVyQ2FsYyh0aGlzLnRyaWVzICsgMSkpXG4gIH1cbn1cbiIsICJpbXBvcnQge2Nsb3N1cmV9IGZyb20gXCIuL3V0aWxzXCJcbmltcG9ydCB7XG4gIENIQU5ORUxfRVZFTlRTLFxuICBDSEFOTkVMX1NUQVRFUyxcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCJcblxuaW1wb3J0IFB1c2ggZnJvbSBcIi4vcHVzaFwiXG5pbXBvcnQgVGltZXIgZnJvbSBcIi4vdGltZXJcIlxuXG4vKipcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdG9waWNcbiAqIEBwYXJhbSB7KE9iamVjdHxmdW5jdGlvbil9IHBhcmFtc1xuICogQHBhcmFtIHtTb2NrZXR9IHNvY2tldFxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDaGFubmVsIHtcbiAgY29uc3RydWN0b3IodG9waWMsIHBhcmFtcywgc29ja2V0KXtcbiAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMuY2xvc2VkXG4gICAgdGhpcy50b3BpYyA9IHRvcGljXG4gICAgdGhpcy5wYXJhbXMgPSBjbG9zdXJlKHBhcmFtcyB8fCB7fSlcbiAgICB0aGlzLnNvY2tldCA9IHNvY2tldFxuICAgIHRoaXMuYmluZGluZ3MgPSBbXVxuICAgIHRoaXMuYmluZGluZ1JlZiA9IDBcbiAgICB0aGlzLnRpbWVvdXQgPSB0aGlzLnNvY2tldC50aW1lb3V0XG4gICAgdGhpcy5qb2luZWRPbmNlID0gZmFsc2VcbiAgICB0aGlzLmpvaW5QdXNoID0gbmV3IFB1c2godGhpcywgQ0hBTk5FTF9FVkVOVFMuam9pbiwgdGhpcy5wYXJhbXMsIHRoaXMudGltZW91dClcbiAgICB0aGlzLnB1c2hCdWZmZXIgPSBbXVxuICAgIHRoaXMuc3RhdGVDaGFuZ2VSZWZzID0gW11cblxuICAgIHRoaXMucmVqb2luVGltZXIgPSBuZXcgVGltZXIoKCkgPT4ge1xuICAgICAgaWYodGhpcy5zb2NrZXQuaXNDb25uZWN0ZWQoKSl7IHRoaXMucmVqb2luKCkgfVxuICAgIH0sIHRoaXMuc29ja2V0LnJlam9pbkFmdGVyTXMpXG4gICAgdGhpcy5zdGF0ZUNoYW5nZVJlZnMucHVzaCh0aGlzLnNvY2tldC5vbkVycm9yKCgpID0+IHRoaXMucmVqb2luVGltZXIucmVzZXQoKSkpXG4gICAgdGhpcy5zdGF0ZUNoYW5nZVJlZnMucHVzaCh0aGlzLnNvY2tldC5vbk9wZW4oKCkgPT4ge1xuICAgICAgdGhpcy5yZWpvaW5UaW1lci5yZXNldCgpXG4gICAgICBpZih0aGlzLmlzRXJyb3JlZCgpKXsgdGhpcy5yZWpvaW4oKSB9XG4gICAgfSlcbiAgICApXG4gICAgdGhpcy5qb2luUHVzaC5yZWNlaXZlKFwib2tcIiwgKCkgPT4ge1xuICAgICAgdGhpcy5zdGF0ZSA9IENIQU5ORUxfU1RBVEVTLmpvaW5lZFxuICAgICAgdGhpcy5yZWpvaW5UaW1lci5yZXNldCgpXG4gICAgICB0aGlzLnB1c2hCdWZmZXIuZm9yRWFjaChwdXNoRXZlbnQgPT4gcHVzaEV2ZW50LnNlbmQoKSlcbiAgICAgIHRoaXMucHVzaEJ1ZmZlciA9IFtdXG4gICAgfSlcbiAgICB0aGlzLmpvaW5QdXNoLnJlY2VpdmUoXCJlcnJvclwiLCAoKSA9PiB7XG4gICAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMuZXJyb3JlZFxuICAgICAgaWYodGhpcy5zb2NrZXQuaXNDb25uZWN0ZWQoKSl7IHRoaXMucmVqb2luVGltZXIuc2NoZWR1bGVUaW1lb3V0KCkgfVxuICAgIH0pXG4gICAgdGhpcy5vbkNsb3NlKCgpID0+IHtcbiAgICAgIHRoaXMucmVqb2luVGltZXIucmVzZXQoKVxuICAgICAgaWYodGhpcy5zb2NrZXQuaGFzTG9nZ2VyKCkpIHRoaXMuc29ja2V0LmxvZyhcImNoYW5uZWxcIiwgYGNsb3NlICR7dGhpcy50b3BpY30gJHt0aGlzLmpvaW5SZWYoKX1gKVxuICAgICAgdGhpcy5zdGF0ZSA9IENIQU5ORUxfU1RBVEVTLmNsb3NlZFxuICAgICAgdGhpcy5zb2NrZXQucmVtb3ZlKHRoaXMpXG4gICAgfSlcbiAgICB0aGlzLm9uRXJyb3IocmVhc29uID0+IHtcbiAgICAgIGlmKHRoaXMuc29ja2V0Lmhhc0xvZ2dlcigpKSB0aGlzLnNvY2tldC5sb2coXCJjaGFubmVsXCIsIGBlcnJvciAke3RoaXMudG9waWN9YCwgcmVhc29uKVxuICAgICAgaWYodGhpcy5pc0pvaW5pbmcoKSl7IHRoaXMuam9pblB1c2gucmVzZXQoKSB9XG4gICAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMuZXJyb3JlZFxuICAgICAgaWYodGhpcy5zb2NrZXQuaXNDb25uZWN0ZWQoKSl7IHRoaXMucmVqb2luVGltZXIuc2NoZWR1bGVUaW1lb3V0KCkgfVxuICAgIH0pXG4gICAgdGhpcy5qb2luUHVzaC5yZWNlaXZlKFwidGltZW91dFwiLCAoKSA9PiB7XG4gICAgICBpZih0aGlzLnNvY2tldC5oYXNMb2dnZXIoKSkgdGhpcy5zb2NrZXQubG9nKFwiY2hhbm5lbFwiLCBgdGltZW91dCAke3RoaXMudG9waWN9ICgke3RoaXMuam9pblJlZigpfSlgLCB0aGlzLmpvaW5QdXNoLnRpbWVvdXQpXG4gICAgICBsZXQgbGVhdmVQdXNoID0gbmV3IFB1c2godGhpcywgQ0hBTk5FTF9FVkVOVFMubGVhdmUsIGNsb3N1cmUoe30pLCB0aGlzLnRpbWVvdXQpXG4gICAgICBsZWF2ZVB1c2guc2VuZCgpXG4gICAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMuZXJyb3JlZFxuICAgICAgdGhpcy5qb2luUHVzaC5yZXNldCgpXG4gICAgICBpZih0aGlzLnNvY2tldC5pc0Nvbm5lY3RlZCgpKXsgdGhpcy5yZWpvaW5UaW1lci5zY2hlZHVsZVRpbWVvdXQoKSB9XG4gICAgfSlcbiAgICB0aGlzLm9uKENIQU5ORUxfRVZFTlRTLnJlcGx5LCAocGF5bG9hZCwgcmVmKSA9PiB7XG4gICAgICB0aGlzLnRyaWdnZXIodGhpcy5yZXBseUV2ZW50TmFtZShyZWYpLCBwYXlsb2FkKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogSm9pbiB0aGUgY2hhbm5lbFxuICAgKiBAcGFyYW0ge2ludGVnZXJ9IHRpbWVvdXRcbiAgICogQHJldHVybnMge1B1c2h9XG4gICAqL1xuICBqb2luKHRpbWVvdXQgPSB0aGlzLnRpbWVvdXQpe1xuICAgIGlmKHRoaXMuam9pbmVkT25jZSl7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0cmllZCB0byBqb2luIG11bHRpcGxlIHRpbWVzLiAnam9pbicgY2FuIG9ubHkgYmUgY2FsbGVkIGEgc2luZ2xlIHRpbWUgcGVyIGNoYW5uZWwgaW5zdGFuY2VcIilcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50aW1lb3V0ID0gdGltZW91dFxuICAgICAgdGhpcy5qb2luZWRPbmNlID0gdHJ1ZVxuICAgICAgdGhpcy5yZWpvaW4oKVxuICAgICAgcmV0dXJuIHRoaXMuam9pblB1c2hcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSG9vayBpbnRvIGNoYW5uZWwgY2xvc2VcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIG9uQ2xvc2UoY2FsbGJhY2spe1xuICAgIHRoaXMub24oQ0hBTk5FTF9FVkVOVFMuY2xvc2UsIGNhbGxiYWNrKVxuICB9XG5cbiAgLyoqXG4gICAqIEhvb2sgaW50byBjaGFubmVsIGVycm9yc1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgb25FcnJvcihjYWxsYmFjayl7XG4gICAgcmV0dXJuIHRoaXMub24oQ0hBTk5FTF9FVkVOVFMuZXJyb3IsIHJlYXNvbiA9PiBjYWxsYmFjayhyZWFzb24pKVxuICB9XG5cbiAgLyoqXG4gICAqIFN1YnNjcmliZXMgb24gY2hhbm5lbCBldmVudHNcbiAgICpcbiAgICogU3Vic2NyaXB0aW9uIHJldHVybnMgYSByZWYgY291bnRlciwgd2hpY2ggY2FuIGJlIHVzZWQgbGF0ZXIgdG9cbiAgICogdW5zdWJzY3JpYmUgdGhlIGV4YWN0IGV2ZW50IGxpc3RlbmVyXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGNvbnN0IHJlZjEgPSBjaGFubmVsLm9uKFwiZXZlbnRcIiwgZG9fc3R1ZmYpXG4gICAqIGNvbnN0IHJlZjIgPSBjaGFubmVsLm9uKFwiZXZlbnRcIiwgZG9fb3RoZXJfc3R1ZmYpXG4gICAqIGNoYW5uZWwub2ZmKFwiZXZlbnRcIiwgcmVmMSlcbiAgICogLy8gU2luY2UgdW5zdWJzY3JpcHRpb24sIGRvX3N0dWZmIHdvbid0IGZpcmUsXG4gICAqIC8vIHdoaWxlIGRvX290aGVyX3N0dWZmIHdpbGwga2VlcCBmaXJpbmcgb24gdGhlIFwiZXZlbnRcIlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICogQHJldHVybnMge2ludGVnZXJ9IHJlZlxuICAgKi9cbiAgb24oZXZlbnQsIGNhbGxiYWNrKXtcbiAgICBsZXQgcmVmID0gdGhpcy5iaW5kaW5nUmVmKytcbiAgICB0aGlzLmJpbmRpbmdzLnB1c2goe2V2ZW50LCByZWYsIGNhbGxiYWNrfSlcbiAgICByZXR1cm4gcmVmXG4gIH1cblxuICAvKipcbiAgICogVW5zdWJzY3JpYmVzIG9mZiBvZiBjaGFubmVsIGV2ZW50c1xuICAgKlxuICAgKiBVc2UgdGhlIHJlZiByZXR1cm5lZCBmcm9tIGEgY2hhbm5lbC5vbigpIHRvIHVuc3Vic2NyaWJlIG9uZVxuICAgKiBoYW5kbGVyLCBvciBwYXNzIG5vdGhpbmcgZm9yIHRoZSByZWYgdG8gdW5zdWJzY3JpYmUgYWxsXG4gICAqIGhhbmRsZXJzIGZvciB0aGUgZ2l2ZW4gZXZlbnQuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIC8vIFVuc3Vic2NyaWJlIHRoZSBkb19zdHVmZiBoYW5kbGVyXG4gICAqIGNvbnN0IHJlZjEgPSBjaGFubmVsLm9uKFwiZXZlbnRcIiwgZG9fc3R1ZmYpXG4gICAqIGNoYW5uZWwub2ZmKFwiZXZlbnRcIiwgcmVmMSlcbiAgICpcbiAgICogLy8gVW5zdWJzY3JpYmUgYWxsIGhhbmRsZXJzIGZyb20gZXZlbnRcbiAgICogY2hhbm5lbC5vZmYoXCJldmVudFwiKVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcbiAgICogQHBhcmFtIHtpbnRlZ2VyfSByZWZcbiAgICovXG4gIG9mZihldmVudCwgcmVmKXtcbiAgICB0aGlzLmJpbmRpbmdzID0gdGhpcy5iaW5kaW5ncy5maWx0ZXIoKGJpbmQpID0+IHtcbiAgICAgIHJldHVybiAhKGJpbmQuZXZlbnQgPT09IGV2ZW50ICYmICh0eXBlb2YgcmVmID09PSBcInVuZGVmaW5lZFwiIHx8IHJlZiA9PT0gYmluZC5yZWYpKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGNhblB1c2goKXsgcmV0dXJuIHRoaXMuc29ja2V0LmlzQ29ubmVjdGVkKCkgJiYgdGhpcy5pc0pvaW5lZCgpIH1cblxuICAvKipcbiAgICogU2VuZHMgYSBtZXNzYWdlIGBldmVudGAgdG8gcGhvZW5peCB3aXRoIHRoZSBwYXlsb2FkIGBwYXlsb2FkYC5cbiAgICogUGhvZW5peCByZWNlaXZlcyB0aGlzIGluIHRoZSBgaGFuZGxlX2luKGV2ZW50LCBwYXlsb2FkLCBzb2NrZXQpYFxuICAgKiBmdW5jdGlvbi4gaWYgcGhvZW5peCByZXBsaWVzIG9yIGl0IHRpbWVzIG91dCAoZGVmYXVsdCAxMDAwMG1zKSxcbiAgICogdGhlbiBvcHRpb25hbGx5IHRoZSByZXBseSBjYW4gYmUgcmVjZWl2ZWQuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGNoYW5uZWwucHVzaChcImV2ZW50XCIpXG4gICAqICAgLnJlY2VpdmUoXCJva1wiLCBwYXlsb2FkID0+IGNvbnNvbGUubG9nKFwicGhvZW5peCByZXBsaWVkOlwiLCBwYXlsb2FkKSlcbiAgICogICAucmVjZWl2ZShcImVycm9yXCIsIGVyciA9PiBjb25zb2xlLmxvZyhcInBob2VuaXggZXJyb3JlZFwiLCBlcnIpKVxuICAgKiAgIC5yZWNlaXZlKFwidGltZW91dFwiLCAoKSA9PiBjb25zb2xlLmxvZyhcInRpbWVkIG91dCBwdXNoaW5nXCIpKVxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcbiAgICogQHBhcmFtIHtPYmplY3R9IHBheWxvYWRcbiAgICogQHBhcmFtIHtudW1iZXJ9IFt0aW1lb3V0XVxuICAgKiBAcmV0dXJucyB7UHVzaH1cbiAgICovXG4gIHB1c2goZXZlbnQsIHBheWxvYWQsIHRpbWVvdXQgPSB0aGlzLnRpbWVvdXQpe1xuICAgIHBheWxvYWQgPSBwYXlsb2FkIHx8IHt9XG4gICAgaWYoIXRoaXMuam9pbmVkT25jZSl7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHRyaWVkIHRvIHB1c2ggJyR7ZXZlbnR9JyB0byAnJHt0aGlzLnRvcGljfScgYmVmb3JlIGpvaW5pbmcuIFVzZSBjaGFubmVsLmpvaW4oKSBiZWZvcmUgcHVzaGluZyBldmVudHNgKVxuICAgIH1cbiAgICBsZXQgcHVzaEV2ZW50ID0gbmV3IFB1c2godGhpcywgZXZlbnQsIGZ1bmN0aW9uICgpeyByZXR1cm4gcGF5bG9hZCB9LCB0aW1lb3V0KVxuICAgIGlmKHRoaXMuY2FuUHVzaCgpKXtcbiAgICAgIHB1c2hFdmVudC5zZW5kKClcbiAgICB9IGVsc2Uge1xuICAgICAgcHVzaEV2ZW50LnN0YXJ0VGltZW91dCgpXG4gICAgICB0aGlzLnB1c2hCdWZmZXIucHVzaChwdXNoRXZlbnQpXG4gICAgfVxuXG4gICAgcmV0dXJuIHB1c2hFdmVudFxuICB9XG5cbiAgLyoqIExlYXZlcyB0aGUgY2hhbm5lbFxuICAgKlxuICAgKiBVbnN1YnNjcmliZXMgZnJvbSBzZXJ2ZXIgZXZlbnRzLCBhbmRcbiAgICogaW5zdHJ1Y3RzIGNoYW5uZWwgdG8gdGVybWluYXRlIG9uIHNlcnZlclxuICAgKlxuICAgKiBUcmlnZ2VycyBvbkNsb3NlKCkgaG9va3NcbiAgICpcbiAgICogVG8gcmVjZWl2ZSBsZWF2ZSBhY2tub3dsZWRnZW1lbnRzLCB1c2UgdGhlIGByZWNlaXZlYFxuICAgKiBob29rIHRvIGJpbmQgdG8gdGhlIHNlcnZlciBhY2ssIGllOlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBjaGFubmVsLmxlYXZlKCkucmVjZWl2ZShcIm9rXCIsICgpID0+IGFsZXJ0KFwibGVmdCFcIikgKVxuICAgKlxuICAgKiBAcGFyYW0ge2ludGVnZXJ9IHRpbWVvdXRcbiAgICogQHJldHVybnMge1B1c2h9XG4gICAqL1xuICBsZWF2ZSh0aW1lb3V0ID0gdGhpcy50aW1lb3V0KXtcbiAgICB0aGlzLnJlam9pblRpbWVyLnJlc2V0KClcbiAgICB0aGlzLmpvaW5QdXNoLmNhbmNlbFRpbWVvdXQoKVxuXG4gICAgdGhpcy5zdGF0ZSA9IENIQU5ORUxfU1RBVEVTLmxlYXZpbmdcbiAgICBsZXQgb25DbG9zZSA9ICgpID0+IHtcbiAgICAgIGlmKHRoaXMuc29ja2V0Lmhhc0xvZ2dlcigpKSB0aGlzLnNvY2tldC5sb2coXCJjaGFubmVsXCIsIGBsZWF2ZSAke3RoaXMudG9waWN9YClcbiAgICAgIHRoaXMudHJpZ2dlcihDSEFOTkVMX0VWRU5UUy5jbG9zZSwgXCJsZWF2ZVwiKVxuICAgIH1cbiAgICBsZXQgbGVhdmVQdXNoID0gbmV3IFB1c2godGhpcywgQ0hBTk5FTF9FVkVOVFMubGVhdmUsIGNsb3N1cmUoe30pLCB0aW1lb3V0KVxuICAgIGxlYXZlUHVzaC5yZWNlaXZlKFwib2tcIiwgKCkgPT4gb25DbG9zZSgpKVxuICAgICAgLnJlY2VpdmUoXCJ0aW1lb3V0XCIsICgpID0+IG9uQ2xvc2UoKSlcbiAgICBsZWF2ZVB1c2guc2VuZCgpXG4gICAgaWYoIXRoaXMuY2FuUHVzaCgpKXsgbGVhdmVQdXNoLnRyaWdnZXIoXCJva1wiLCB7fSkgfVxuXG4gICAgcmV0dXJuIGxlYXZlUHVzaFxuICB9XG5cbiAgLyoqXG4gICAqIE92ZXJyaWRhYmxlIG1lc3NhZ2UgaG9va1xuICAgKlxuICAgKiBSZWNlaXZlcyBhbGwgZXZlbnRzIGZvciBzcGVjaWFsaXplZCBtZXNzYWdlIGhhbmRsaW5nXG4gICAqIGJlZm9yZSBkaXNwYXRjaGluZyB0byB0aGUgY2hhbm5lbCBjYWxsYmFja3MuXG4gICAqXG4gICAqIE11c3QgcmV0dXJuIHRoZSBwYXlsb2FkLCBtb2RpZmllZCBvciB1bm1vZGlmaWVkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuICAgKiBAcGFyYW0ge09iamVjdH0gcGF5bG9hZFxuICAgKiBAcGFyYW0ge2ludGVnZXJ9IHJlZlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fVxuICAgKi9cbiAgb25NZXNzYWdlKF9ldmVudCwgcGF5bG9hZCwgX3JlZil7IHJldHVybiBwYXlsb2FkIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGlzTWVtYmVyKHRvcGljLCBldmVudCwgcGF5bG9hZCwgam9pblJlZil7XG4gICAgaWYodGhpcy50b3BpYyAhPT0gdG9waWMpeyByZXR1cm4gZmFsc2UgfVxuXG4gICAgaWYoam9pblJlZiAmJiBqb2luUmVmICE9PSB0aGlzLmpvaW5SZWYoKSl7XG4gICAgICBpZih0aGlzLnNvY2tldC5oYXNMb2dnZXIoKSkgdGhpcy5zb2NrZXQubG9nKFwiY2hhbm5lbFwiLCBcImRyb3BwaW5nIG91dGRhdGVkIG1lc3NhZ2VcIiwge3RvcGljLCBldmVudCwgcGF5bG9hZCwgam9pblJlZn0pXG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGpvaW5SZWYoKXsgcmV0dXJuIHRoaXMuam9pblB1c2gucmVmIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHJlam9pbih0aW1lb3V0ID0gdGhpcy50aW1lb3V0KXtcbiAgICBpZih0aGlzLmlzTGVhdmluZygpKXsgcmV0dXJuIH1cbiAgICB0aGlzLnNvY2tldC5sZWF2ZU9wZW5Ub3BpYyh0aGlzLnRvcGljKVxuICAgIHRoaXMuc3RhdGUgPSBDSEFOTkVMX1NUQVRFUy5qb2luaW5nXG4gICAgdGhpcy5qb2luUHVzaC5yZXNlbmQodGltZW91dClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgdHJpZ2dlcihldmVudCwgcGF5bG9hZCwgcmVmLCBqb2luUmVmKXtcbiAgICBsZXQgaGFuZGxlZFBheWxvYWQgPSB0aGlzLm9uTWVzc2FnZShldmVudCwgcGF5bG9hZCwgcmVmLCBqb2luUmVmKVxuICAgIGlmKHBheWxvYWQgJiYgIWhhbmRsZWRQYXlsb2FkKXsgdGhyb3cgbmV3IEVycm9yKFwiY2hhbm5lbCBvbk1lc3NhZ2UgY2FsbGJhY2tzIG11c3QgcmV0dXJuIHRoZSBwYXlsb2FkLCBtb2RpZmllZCBvciB1bm1vZGlmaWVkXCIpIH1cblxuICAgIGxldCBldmVudEJpbmRpbmdzID0gdGhpcy5iaW5kaW5ncy5maWx0ZXIoYmluZCA9PiBiaW5kLmV2ZW50ID09PSBldmVudClcblxuICAgIGZvcihsZXQgaSA9IDA7IGkgPCBldmVudEJpbmRpbmdzLmxlbmd0aDsgaSsrKXtcbiAgICAgIGxldCBiaW5kID0gZXZlbnRCaW5kaW5nc1tpXVxuICAgICAgYmluZC5jYWxsYmFjayhoYW5kbGVkUGF5bG9hZCwgcmVmLCBqb2luUmVmIHx8IHRoaXMuam9pblJlZigpKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcmVwbHlFdmVudE5hbWUocmVmKXsgcmV0dXJuIGBjaGFuX3JlcGx5XyR7cmVmfWAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgaXNDbG9zZWQoKXsgcmV0dXJuIHRoaXMuc3RhdGUgPT09IENIQU5ORUxfU1RBVEVTLmNsb3NlZCB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBpc0Vycm9yZWQoKXsgcmV0dXJuIHRoaXMuc3RhdGUgPT09IENIQU5ORUxfU1RBVEVTLmVycm9yZWQgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgaXNKb2luZWQoKXsgcmV0dXJuIHRoaXMuc3RhdGUgPT09IENIQU5ORUxfU1RBVEVTLmpvaW5lZCB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBpc0pvaW5pbmcoKXsgcmV0dXJuIHRoaXMuc3RhdGUgPT09IENIQU5ORUxfU1RBVEVTLmpvaW5pbmcgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgaXNMZWF2aW5nKCl7IHJldHVybiB0aGlzLnN0YXRlID09PSBDSEFOTkVMX1NUQVRFUy5sZWF2aW5nIH1cbn1cbiIsICJpbXBvcnQge1xuICBnbG9iYWwsXG4gIFhIUl9TVEFURVNcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCJcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQWpheCB7XG5cbiAgc3RhdGljIHJlcXVlc3QobWV0aG9kLCBlbmRQb2ludCwgYWNjZXB0LCBib2R5LCB0aW1lb3V0LCBvbnRpbWVvdXQsIGNhbGxiYWNrKXtcbiAgICBpZihnbG9iYWwuWERvbWFpblJlcXVlc3Qpe1xuICAgICAgbGV0IHJlcSA9IG5ldyBnbG9iYWwuWERvbWFpblJlcXVlc3QoKSAvLyBJRTgsIElFOVxuICAgICAgcmV0dXJuIHRoaXMueGRvbWFpblJlcXVlc3QocmVxLCBtZXRob2QsIGVuZFBvaW50LCBib2R5LCB0aW1lb3V0LCBvbnRpbWVvdXQsIGNhbGxiYWNrKVxuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgcmVxID0gbmV3IGdsb2JhbC5YTUxIdHRwUmVxdWVzdCgpIC8vIElFNyssIEZpcmVmb3gsIENocm9tZSwgT3BlcmEsIFNhZmFyaVxuICAgICAgcmV0dXJuIHRoaXMueGhyUmVxdWVzdChyZXEsIG1ldGhvZCwgZW5kUG9pbnQsIGFjY2VwdCwgYm9keSwgdGltZW91dCwgb250aW1lb3V0LCBjYWxsYmFjaylcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgeGRvbWFpblJlcXVlc3QocmVxLCBtZXRob2QsIGVuZFBvaW50LCBib2R5LCB0aW1lb3V0LCBvbnRpbWVvdXQsIGNhbGxiYWNrKXtcbiAgICByZXEudGltZW91dCA9IHRpbWVvdXRcbiAgICByZXEub3BlbihtZXRob2QsIGVuZFBvaW50KVxuICAgIHJlcS5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICBsZXQgcmVzcG9uc2UgPSB0aGlzLnBhcnNlSlNPTihyZXEucmVzcG9uc2VUZXh0KVxuICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2socmVzcG9uc2UpXG4gICAgfVxuICAgIGlmKG9udGltZW91dCl7IHJlcS5vbnRpbWVvdXQgPSBvbnRpbWVvdXQgfVxuXG4gICAgLy8gV29yayBhcm91bmQgYnVnIGluIElFOSB0aGF0IHJlcXVpcmVzIGFuIGF0dGFjaGVkIG9ucHJvZ3Jlc3MgaGFuZGxlclxuICAgIHJlcS5vbnByb2dyZXNzID0gKCkgPT4geyB9XG5cbiAgICByZXEuc2VuZChib2R5KVxuICAgIHJldHVybiByZXFcbiAgfVxuXG4gIHN0YXRpYyB4aHJSZXF1ZXN0KHJlcSwgbWV0aG9kLCBlbmRQb2ludCwgYWNjZXB0LCBib2R5LCB0aW1lb3V0LCBvbnRpbWVvdXQsIGNhbGxiYWNrKXtcbiAgICByZXEub3BlbihtZXRob2QsIGVuZFBvaW50LCB0cnVlKVxuICAgIHJlcS50aW1lb3V0ID0gdGltZW91dFxuICAgIHJlcS5zZXRSZXF1ZXN0SGVhZGVyKFwiQ29udGVudC1UeXBlXCIsIGFjY2VwdClcbiAgICByZXEub25lcnJvciA9ICgpID0+IGNhbGxiYWNrICYmIGNhbGxiYWNrKG51bGwpXG4gICAgcmVxLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgIGlmKHJlcS5yZWFkeVN0YXRlID09PSBYSFJfU1RBVEVTLmNvbXBsZXRlICYmIGNhbGxiYWNrKXtcbiAgICAgICAgbGV0IHJlc3BvbnNlID0gdGhpcy5wYXJzZUpTT04ocmVxLnJlc3BvbnNlVGV4dClcbiAgICAgICAgY2FsbGJhY2socmVzcG9uc2UpXG4gICAgICB9XG4gICAgfVxuICAgIGlmKG9udGltZW91dCl7IHJlcS5vbnRpbWVvdXQgPSBvbnRpbWVvdXQgfVxuXG4gICAgcmVxLnNlbmQoYm9keSlcbiAgICByZXR1cm4gcmVxXG4gIH1cblxuICBzdGF0aWMgcGFyc2VKU09OKHJlc3Ape1xuICAgIGlmKCFyZXNwIHx8IHJlc3AgPT09IFwiXCIpeyByZXR1cm4gbnVsbCB9XG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEpTT04ucGFyc2UocmVzcClcbiAgICB9IGNhdGNoIChlKXtcbiAgICAgIGNvbnNvbGUgJiYgY29uc29sZS5sb2coXCJmYWlsZWQgdG8gcGFyc2UgSlNPTiByZXNwb25zZVwiLCByZXNwKVxuICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgc2VyaWFsaXplKG9iaiwgcGFyZW50S2V5KXtcbiAgICBsZXQgcXVlcnlTdHIgPSBbXVxuICAgIGZvcih2YXIga2V5IGluIG9iail7XG4gICAgICBpZighT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSl7IGNvbnRpbnVlIH1cbiAgICAgIGxldCBwYXJhbUtleSA9IHBhcmVudEtleSA/IGAke3BhcmVudEtleX1bJHtrZXl9XWAgOiBrZXlcbiAgICAgIGxldCBwYXJhbVZhbCA9IG9ialtrZXldXG4gICAgICBpZih0eXBlb2YgcGFyYW1WYWwgPT09IFwib2JqZWN0XCIpe1xuICAgICAgICBxdWVyeVN0ci5wdXNoKHRoaXMuc2VyaWFsaXplKHBhcmFtVmFsLCBwYXJhbUtleSkpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBxdWVyeVN0ci5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChwYXJhbUtleSkgKyBcIj1cIiArIGVuY29kZVVSSUNvbXBvbmVudChwYXJhbVZhbCkpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBxdWVyeVN0ci5qb2luKFwiJlwiKVxuICB9XG5cbiAgc3RhdGljIGFwcGVuZFBhcmFtcyh1cmwsIHBhcmFtcyl7XG4gICAgaWYoT2JqZWN0LmtleXMocGFyYW1zKS5sZW5ndGggPT09IDApeyByZXR1cm4gdXJsIH1cblxuICAgIGxldCBwcmVmaXggPSB1cmwubWF0Y2goL1xcPy8pID8gXCImXCIgOiBcIj9cIlxuICAgIHJldHVybiBgJHt1cmx9JHtwcmVmaXh9JHt0aGlzLnNlcmlhbGl6ZShwYXJhbXMpfWBcbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIFNPQ0tFVF9TVEFURVMsXG4gIFRSQU5TUE9SVFNcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCJcblxuaW1wb3J0IEFqYXggZnJvbSBcIi4vYWpheFwiXG5cbmxldCBhcnJheUJ1ZmZlclRvQmFzZTY0ID0gKGJ1ZmZlcikgPT4ge1xuICBsZXQgYmluYXJ5ID0gXCJcIlxuICBsZXQgYnl0ZXMgPSBuZXcgVWludDhBcnJheShidWZmZXIpXG4gIGxldCBsZW4gPSBieXRlcy5ieXRlTGVuZ3RoXG4gIGZvcihsZXQgaSA9IDA7IGkgPCBsZW47IGkrKyl7IGJpbmFyeSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldKSB9XG4gIHJldHVybiBidG9hKGJpbmFyeSlcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTG9uZ1BvbGwge1xuXG4gIGNvbnN0cnVjdG9yKGVuZFBvaW50KXtcbiAgICB0aGlzLmVuZFBvaW50ID0gbnVsbFxuICAgIHRoaXMudG9rZW4gPSBudWxsXG4gICAgdGhpcy5za2lwSGVhcnRiZWF0ID0gdHJ1ZVxuICAgIHRoaXMucmVxcyA9IG5ldyBTZXQoKVxuICAgIHRoaXMuYXdhaXRpbmdCYXRjaEFjayA9IGZhbHNlXG4gICAgdGhpcy5jdXJyZW50QmF0Y2ggPSBudWxsXG4gICAgdGhpcy5jdXJyZW50QmF0Y2hUaW1lciA9IG51bGxcbiAgICB0aGlzLmJhdGNoQnVmZmVyID0gW11cbiAgICB0aGlzLm9ub3BlbiA9IGZ1bmN0aW9uICgpeyB9IC8vIG5vb3BcbiAgICB0aGlzLm9uZXJyb3IgPSBmdW5jdGlvbiAoKXsgfSAvLyBub29wXG4gICAgdGhpcy5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAoKXsgfSAvLyBub29wXG4gICAgdGhpcy5vbmNsb3NlID0gZnVuY3Rpb24gKCl7IH0gLy8gbm9vcFxuICAgIHRoaXMucG9sbEVuZHBvaW50ID0gdGhpcy5ub3JtYWxpemVFbmRwb2ludChlbmRQb2ludClcbiAgICB0aGlzLnJlYWR5U3RhdGUgPSBTT0NLRVRfU1RBVEVTLmNvbm5lY3RpbmdcbiAgICB0aGlzLnBvbGwoKVxuICB9XG5cbiAgbm9ybWFsaXplRW5kcG9pbnQoZW5kUG9pbnQpe1xuICAgIHJldHVybiAoZW5kUG9pbnRcbiAgICAgIC5yZXBsYWNlKFwid3M6Ly9cIiwgXCJodHRwOi8vXCIpXG4gICAgICAucmVwbGFjZShcIndzczovL1wiLCBcImh0dHBzOi8vXCIpXG4gICAgICAucmVwbGFjZShuZXcgUmVnRXhwKFwiKC4qKVxcL1wiICsgVFJBTlNQT1JUUy53ZWJzb2NrZXQpLCBcIiQxL1wiICsgVFJBTlNQT1JUUy5sb25ncG9sbCkpXG4gIH1cblxuICBlbmRwb2ludFVSTCgpe1xuICAgIHJldHVybiBBamF4LmFwcGVuZFBhcmFtcyh0aGlzLnBvbGxFbmRwb2ludCwge3Rva2VuOiB0aGlzLnRva2VufSlcbiAgfVxuXG4gIGNsb3NlQW5kUmV0cnkoY29kZSwgcmVhc29uLCB3YXNDbGVhbil7XG4gICAgdGhpcy5jbG9zZShjb2RlLCByZWFzb24sIHdhc0NsZWFuKVxuICAgIHRoaXMucmVhZHlTdGF0ZSA9IFNPQ0tFVF9TVEFURVMuY29ubmVjdGluZ1xuICB9XG5cbiAgb250aW1lb3V0KCl7XG4gICAgdGhpcy5vbmVycm9yKFwidGltZW91dFwiKVxuICAgIHRoaXMuY2xvc2VBbmRSZXRyeSgxMDA1LCBcInRpbWVvdXRcIiwgZmFsc2UpXG4gIH1cblxuICBpc0FjdGl2ZSgpeyByZXR1cm4gdGhpcy5yZWFkeVN0YXRlID09PSBTT0NLRVRfU1RBVEVTLm9wZW4gfHwgdGhpcy5yZWFkeVN0YXRlID09PSBTT0NLRVRfU1RBVEVTLmNvbm5lY3RpbmcgfVxuXG4gIHBvbGwoKXtcbiAgICB0aGlzLmFqYXgoXCJHRVRcIiwgXCJhcHBsaWNhdGlvbi9qc29uXCIsIG51bGwsICgpID0+IHRoaXMub250aW1lb3V0KCksIHJlc3AgPT4ge1xuICAgICAgaWYocmVzcCl7XG4gICAgICAgIHZhciB7c3RhdHVzLCB0b2tlbiwgbWVzc2FnZXN9ID0gcmVzcFxuICAgICAgICB0aGlzLnRva2VuID0gdG9rZW5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXR1cyA9IDBcbiAgICAgIH1cblxuICAgICAgc3dpdGNoKHN0YXR1cyl7XG4gICAgICAgIGNhc2UgMjAwOlxuICAgICAgICAgIG1lc3NhZ2VzLmZvckVhY2gobXNnID0+IHtcbiAgICAgICAgICAgIC8vIFRhc2tzIGFyZSB3aGF0IHRoaW5ncyBsaWtlIGV2ZW50IGhhbmRsZXJzLCBzZXRUaW1lb3V0IGNhbGxiYWNrcyxcbiAgICAgICAgICAgIC8vIHByb21pc2UgcmVzb2x2ZXMgYW5kIG1vcmUgYXJlIHJ1biB3aXRoaW4uXG4gICAgICAgICAgICAvLyBJbiBtb2Rlcm4gYnJvd3NlcnMsIHRoZXJlIGFyZSB0d28gZGlmZmVyZW50IGtpbmRzIG9mIHRhc2tzLFxuICAgICAgICAgICAgLy8gbWljcm90YXNrcyBhbmQgbWFjcm90YXNrcy5cbiAgICAgICAgICAgIC8vIE1pY3JvdGFza3MgYXJlIG1haW5seSB1c2VkIGZvciBQcm9taXNlcywgd2hpbGUgbWFjcm90YXNrcyBhcmVcbiAgICAgICAgICAgIC8vIHVzZWQgZm9yIGV2ZXJ5dGhpbmcgZWxzZS5cbiAgICAgICAgICAgIC8vIE1pY3JvdGFza3MgYWx3YXlzIGhhdmUgcHJpb3JpdHkgb3ZlciBtYWNyb3Rhc2tzLiBJZiB0aGUgSlMgZW5naW5lXG4gICAgICAgICAgICAvLyBpcyBsb29raW5nIGZvciBhIHRhc2sgdG8gcnVuLCBpdCB3aWxsIGFsd2F5cyB0cnkgdG8gZW1wdHkgdGhlXG4gICAgICAgICAgICAvLyBtaWNyb3Rhc2sgcXVldWUgYmVmb3JlIGF0dGVtcHRpbmcgdG8gcnVuIGFueXRoaW5nIGZyb20gdGhlXG4gICAgICAgICAgICAvLyBtYWNyb3Rhc2sgcXVldWUuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gRm9yIHRoZSBXZWJTb2NrZXQgdHJhbnNwb3J0LCBtZXNzYWdlcyBhbHdheXMgYXJyaXZlIGluIHRoZWlyIG93blxuICAgICAgICAgICAgLy8gZXZlbnQuIFRoaXMgbWVhbnMgdGhhdCBpZiBhbnkgcHJvbWlzZXMgYXJlIHJlc29sdmVkIGZyb20gd2l0aGluLFxuICAgICAgICAgICAgLy8gdGhlaXIgY2FsbGJhY2tzIHdpbGwgYWx3YXlzIGZpbmlzaCBleGVjdXRpb24gYnkgdGhlIHRpbWUgdGhlXG4gICAgICAgICAgICAvLyBuZXh0IG1lc3NhZ2UgZXZlbnQgaGFuZGxlciBpcyBydW4uXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gSW4gb3JkZXIgdG8gZW11bGF0ZSB0aGlzIGJlaGF2aW91ciwgd2UgbmVlZCB0byBtYWtlIHN1cmUgZWFjaFxuICAgICAgICAgICAgLy8gb25tZXNzYWdlIGhhbmRsZXIgaXMgcnVuIHdpdGhpbiBpdHMgb3duIG1hY3JvdGFzay5cbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5vbm1lc3NhZ2Uoe2RhdGE6IG1zZ30pLCAwKVxuICAgICAgICAgIH0pXG4gICAgICAgICAgdGhpcy5wb2xsKClcbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDIwNDpcbiAgICAgICAgICB0aGlzLnBvbGwoKVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgNDEwOlxuICAgICAgICAgIHRoaXMucmVhZHlTdGF0ZSA9IFNPQ0tFVF9TVEFURVMub3BlblxuICAgICAgICAgIHRoaXMub25vcGVuKHt9KVxuICAgICAgICAgIHRoaXMucG9sbCgpXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSA0MDM6XG4gICAgICAgICAgdGhpcy5vbmVycm9yKDQwMylcbiAgICAgICAgICB0aGlzLmNsb3NlKDEwMDgsIFwiZm9yYmlkZGVuXCIsIGZhbHNlKVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMDpcbiAgICAgICAgY2FzZSA1MDA6XG4gICAgICAgICAgdGhpcy5vbmVycm9yKDUwMClcbiAgICAgICAgICB0aGlzLmNsb3NlQW5kUmV0cnkoMTAxMSwgXCJpbnRlcm5hbCBzZXJ2ZXIgZXJyb3JcIiwgNTAwKVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcihgdW5oYW5kbGVkIHBvbGwgc3RhdHVzICR7c3RhdHVzfWApXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIC8vIHdlIGNvbGxlY3QgYWxsIHB1c2hlcyB3aXRoaW4gdGhlIGN1cnJlbnQgZXZlbnQgbG9vcCBieVxuICAvLyBzZXRUaW1lb3V0IDAsIHdoaWNoIG9wdGltaXplcyBiYWNrLXRvLWJhY2sgcHJvY2VkdXJhbFxuICAvLyBwdXNoZXMgYWdhaW5zdCBhbiBlbXB0eSBidWZmZXJcblxuICBzZW5kKGJvZHkpe1xuICAgIGlmKHR5cGVvZihib2R5KSAhPT0gXCJzdHJpbmdcIil7IGJvZHkgPSBhcnJheUJ1ZmZlclRvQmFzZTY0KGJvZHkpIH1cbiAgICBpZih0aGlzLmN1cnJlbnRCYXRjaCl7XG4gICAgICB0aGlzLmN1cnJlbnRCYXRjaC5wdXNoKGJvZHkpXG4gICAgfSBlbHNlIGlmKHRoaXMuYXdhaXRpbmdCYXRjaEFjayl7XG4gICAgICB0aGlzLmJhdGNoQnVmZmVyLnB1c2goYm9keSlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jdXJyZW50QmF0Y2ggPSBbYm9keV1cbiAgICAgIHRoaXMuY3VycmVudEJhdGNoVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5iYXRjaFNlbmQodGhpcy5jdXJyZW50QmF0Y2gpXG4gICAgICAgIHRoaXMuY3VycmVudEJhdGNoID0gbnVsbFxuICAgICAgfSwgMClcbiAgICB9XG4gIH1cblxuICBiYXRjaFNlbmQobWVzc2FnZXMpe1xuICAgIHRoaXMuYXdhaXRpbmdCYXRjaEFjayA9IHRydWVcbiAgICB0aGlzLmFqYXgoXCJQT1NUXCIsIFwiYXBwbGljYXRpb24veC1uZGpzb25cIiwgbWVzc2FnZXMuam9pbihcIlxcblwiKSwgKCkgPT4gdGhpcy5vbmVycm9yKFwidGltZW91dFwiKSwgcmVzcCA9PiB7XG4gICAgICB0aGlzLmF3YWl0aW5nQmF0Y2hBY2sgPSBmYWxzZVxuICAgICAgaWYoIXJlc3AgfHwgcmVzcC5zdGF0dXMgIT09IDIwMCl7XG4gICAgICAgIHRoaXMub25lcnJvcihyZXNwICYmIHJlc3Auc3RhdHVzKVxuICAgICAgICB0aGlzLmNsb3NlQW5kUmV0cnkoMTAxMSwgXCJpbnRlcm5hbCBzZXJ2ZXIgZXJyb3JcIiwgZmFsc2UpXG4gICAgICB9IGVsc2UgaWYodGhpcy5iYXRjaEJ1ZmZlci5sZW5ndGggPiAwKXtcbiAgICAgICAgdGhpcy5iYXRjaFNlbmQodGhpcy5iYXRjaEJ1ZmZlcilcbiAgICAgICAgdGhpcy5iYXRjaEJ1ZmZlciA9IFtdXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIGNsb3NlKGNvZGUsIHJlYXNvbiwgd2FzQ2xlYW4pe1xuICAgIGZvcihsZXQgcmVxIG9mIHRoaXMucmVxcyl7IHJlcS5hYm9ydCgpIH1cbiAgICB0aGlzLnJlYWR5U3RhdGUgPSBTT0NLRVRfU1RBVEVTLmNsb3NlZFxuICAgIGxldCBvcHRzID0gT2JqZWN0LmFzc2lnbih7Y29kZTogMTAwMCwgcmVhc29uOiB1bmRlZmluZWQsIHdhc0NsZWFuOiB0cnVlfSwge2NvZGUsIHJlYXNvbiwgd2FzQ2xlYW59KVxuICAgIHRoaXMuYmF0Y2hCdWZmZXIgPSBbXVxuICAgIGNsZWFyVGltZW91dCh0aGlzLmN1cnJlbnRCYXRjaFRpbWVyKVxuICAgIHRoaXMuY3VycmVudEJhdGNoVGltZXIgPSBudWxsXG4gICAgaWYodHlwZW9mKENsb3NlRXZlbnQpICE9PSBcInVuZGVmaW5lZFwiKXtcbiAgICAgIHRoaXMub25jbG9zZShuZXcgQ2xvc2VFdmVudChcImNsb3NlXCIsIG9wdHMpKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9uY2xvc2Uob3B0cylcbiAgICB9XG4gIH1cblxuICBhamF4KG1ldGhvZCwgY29udGVudFR5cGUsIGJvZHksIG9uQ2FsbGVyVGltZW91dCwgY2FsbGJhY2spe1xuICAgIGxldCByZXFcbiAgICBsZXQgb250aW1lb3V0ID0gKCkgPT4ge1xuICAgICAgdGhpcy5yZXFzLmRlbGV0ZShyZXEpXG4gICAgICBvbkNhbGxlclRpbWVvdXQoKVxuICAgIH1cbiAgICByZXEgPSBBamF4LnJlcXVlc3QobWV0aG9kLCB0aGlzLmVuZHBvaW50VVJMKCksIGNvbnRlbnRUeXBlLCBib2R5LCB0aGlzLnRpbWVvdXQsIG9udGltZW91dCwgcmVzcCA9PiB7XG4gICAgICB0aGlzLnJlcXMuZGVsZXRlKHJlcSlcbiAgICAgIGlmKHRoaXMuaXNBY3RpdmUoKSl7IGNhbGxiYWNrKHJlc3ApIH1cbiAgICB9KVxuICAgIHRoaXMucmVxcy5hZGQocmVxKVxuICB9XG59XG4iLCAiLyoqXG4gKiBJbml0aWFsaXplcyB0aGUgUHJlc2VuY2VcbiAqIEBwYXJhbSB7Q2hhbm5lbH0gY2hhbm5lbCAtIFRoZSBDaGFubmVsXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0cyAtIFRoZSBvcHRpb25zLFxuICogICAgICAgIGZvciBleGFtcGxlIGB7ZXZlbnRzOiB7c3RhdGU6IFwic3RhdGVcIiwgZGlmZjogXCJkaWZmXCJ9fWBcbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUHJlc2VuY2Uge1xuXG4gIGNvbnN0cnVjdG9yKGNoYW5uZWwsIG9wdHMgPSB7fSl7XG4gICAgbGV0IGV2ZW50cyA9IG9wdHMuZXZlbnRzIHx8IHtzdGF0ZTogXCJwcmVzZW5jZV9zdGF0ZVwiLCBkaWZmOiBcInByZXNlbmNlX2RpZmZcIn1cbiAgICB0aGlzLnN0YXRlID0ge31cbiAgICB0aGlzLnBlbmRpbmdEaWZmcyA9IFtdXG4gICAgdGhpcy5jaGFubmVsID0gY2hhbm5lbFxuICAgIHRoaXMuam9pblJlZiA9IG51bGxcbiAgICB0aGlzLmNhbGxlciA9IHtcbiAgICAgIG9uSm9pbjogZnVuY3Rpb24gKCl7IH0sXG4gICAgICBvbkxlYXZlOiBmdW5jdGlvbiAoKXsgfSxcbiAgICAgIG9uU3luYzogZnVuY3Rpb24gKCl7IH1cbiAgICB9XG5cbiAgICB0aGlzLmNoYW5uZWwub24oZXZlbnRzLnN0YXRlLCBuZXdTdGF0ZSA9PiB7XG4gICAgICBsZXQge29uSm9pbiwgb25MZWF2ZSwgb25TeW5jfSA9IHRoaXMuY2FsbGVyXG5cbiAgICAgIHRoaXMuam9pblJlZiA9IHRoaXMuY2hhbm5lbC5qb2luUmVmKClcbiAgICAgIHRoaXMuc3RhdGUgPSBQcmVzZW5jZS5zeW5jU3RhdGUodGhpcy5zdGF0ZSwgbmV3U3RhdGUsIG9uSm9pbiwgb25MZWF2ZSlcblxuICAgICAgdGhpcy5wZW5kaW5nRGlmZnMuZm9yRWFjaChkaWZmID0+IHtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFByZXNlbmNlLnN5bmNEaWZmKHRoaXMuc3RhdGUsIGRpZmYsIG9uSm9pbiwgb25MZWF2ZSlcbiAgICAgIH0pXG4gICAgICB0aGlzLnBlbmRpbmdEaWZmcyA9IFtdXG4gICAgICBvblN5bmMoKVxuICAgIH0pXG5cbiAgICB0aGlzLmNoYW5uZWwub24oZXZlbnRzLmRpZmYsIGRpZmYgPT4ge1xuICAgICAgbGV0IHtvbkpvaW4sIG9uTGVhdmUsIG9uU3luY30gPSB0aGlzLmNhbGxlclxuXG4gICAgICBpZih0aGlzLmluUGVuZGluZ1N5bmNTdGF0ZSgpKXtcbiAgICAgICAgdGhpcy5wZW5kaW5nRGlmZnMucHVzaChkaWZmKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFByZXNlbmNlLnN5bmNEaWZmKHRoaXMuc3RhdGUsIGRpZmYsIG9uSm9pbiwgb25MZWF2ZSlcbiAgICAgICAgb25TeW5jKClcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgb25Kb2luKGNhbGxiYWNrKXsgdGhpcy5jYWxsZXIub25Kb2luID0gY2FsbGJhY2sgfVxuXG4gIG9uTGVhdmUoY2FsbGJhY2speyB0aGlzLmNhbGxlci5vbkxlYXZlID0gY2FsbGJhY2sgfVxuXG4gIG9uU3luYyhjYWxsYmFjayl7IHRoaXMuY2FsbGVyLm9uU3luYyA9IGNhbGxiYWNrIH1cblxuICBsaXN0KGJ5KXsgcmV0dXJuIFByZXNlbmNlLmxpc3QodGhpcy5zdGF0ZSwgYnkpIH1cblxuICBpblBlbmRpbmdTeW5jU3RhdGUoKXtcbiAgICByZXR1cm4gIXRoaXMuam9pblJlZiB8fCAodGhpcy5qb2luUmVmICE9PSB0aGlzLmNoYW5uZWwuam9pblJlZigpKVxuICB9XG5cbiAgLy8gbG93ZXItbGV2ZWwgcHVibGljIHN0YXRpYyBBUElcblxuICAvKipcbiAgICogVXNlZCB0byBzeW5jIHRoZSBsaXN0IG9mIHByZXNlbmNlcyBvbiB0aGUgc2VydmVyXG4gICAqIHdpdGggdGhlIGNsaWVudCdzIHN0YXRlLiBBbiBvcHRpb25hbCBgb25Kb2luYCBhbmQgYG9uTGVhdmVgIGNhbGxiYWNrIGNhblxuICAgKiBiZSBwcm92aWRlZCB0byByZWFjdCB0byBjaGFuZ2VzIGluIHRoZSBjbGllbnQncyBsb2NhbCBwcmVzZW5jZXMgYWNyb3NzXG4gICAqIGRpc2Nvbm5lY3RzIGFuZCByZWNvbm5lY3RzIHdpdGggdGhlIHNlcnZlci5cbiAgICpcbiAgICogQHJldHVybnMge1ByZXNlbmNlfVxuICAgKi9cbiAgc3RhdGljIHN5bmNTdGF0ZShjdXJyZW50U3RhdGUsIG5ld1N0YXRlLCBvbkpvaW4sIG9uTGVhdmUpe1xuICAgIGxldCBzdGF0ZSA9IHRoaXMuY2xvbmUoY3VycmVudFN0YXRlKVxuICAgIGxldCBqb2lucyA9IHt9XG4gICAgbGV0IGxlYXZlcyA9IHt9XG5cbiAgICB0aGlzLm1hcChzdGF0ZSwgKGtleSwgcHJlc2VuY2UpID0+IHtcbiAgICAgIGlmKCFuZXdTdGF0ZVtrZXldKXtcbiAgICAgICAgbGVhdmVzW2tleV0gPSBwcmVzZW5jZVxuICAgICAgfVxuICAgIH0pXG4gICAgdGhpcy5tYXAobmV3U3RhdGUsIChrZXksIG5ld1ByZXNlbmNlKSA9PiB7XG4gICAgICBsZXQgY3VycmVudFByZXNlbmNlID0gc3RhdGVba2V5XVxuICAgICAgaWYoY3VycmVudFByZXNlbmNlKXtcbiAgICAgICAgbGV0IG5ld1JlZnMgPSBuZXdQcmVzZW5jZS5tZXRhcy5tYXAobSA9PiBtLnBoeF9yZWYpXG4gICAgICAgIGxldCBjdXJSZWZzID0gY3VycmVudFByZXNlbmNlLm1ldGFzLm1hcChtID0+IG0ucGh4X3JlZilcbiAgICAgICAgbGV0IGpvaW5lZE1ldGFzID0gbmV3UHJlc2VuY2UubWV0YXMuZmlsdGVyKG0gPT4gY3VyUmVmcy5pbmRleE9mKG0ucGh4X3JlZikgPCAwKVxuICAgICAgICBsZXQgbGVmdE1ldGFzID0gY3VycmVudFByZXNlbmNlLm1ldGFzLmZpbHRlcihtID0+IG5ld1JlZnMuaW5kZXhPZihtLnBoeF9yZWYpIDwgMClcbiAgICAgICAgaWYoam9pbmVkTWV0YXMubGVuZ3RoID4gMCl7XG4gICAgICAgICAgam9pbnNba2V5XSA9IG5ld1ByZXNlbmNlXG4gICAgICAgICAgam9pbnNba2V5XS5tZXRhcyA9IGpvaW5lZE1ldGFzXG4gICAgICAgIH1cbiAgICAgICAgaWYobGVmdE1ldGFzLmxlbmd0aCA+IDApe1xuICAgICAgICAgIGxlYXZlc1trZXldID0gdGhpcy5jbG9uZShjdXJyZW50UHJlc2VuY2UpXG4gICAgICAgICAgbGVhdmVzW2tleV0ubWV0YXMgPSBsZWZ0TWV0YXNcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgam9pbnNba2V5XSA9IG5ld1ByZXNlbmNlXG4gICAgICB9XG4gICAgfSlcbiAgICByZXR1cm4gdGhpcy5zeW5jRGlmZihzdGF0ZSwge2pvaW5zOiBqb2lucywgbGVhdmVzOiBsZWF2ZXN9LCBvbkpvaW4sIG9uTGVhdmUpXG4gIH1cblxuICAvKipcbiAgICpcbiAgICogVXNlZCB0byBzeW5jIGEgZGlmZiBvZiBwcmVzZW5jZSBqb2luIGFuZCBsZWF2ZVxuICAgKiBldmVudHMgZnJvbSB0aGUgc2VydmVyLCBhcyB0aGV5IGhhcHBlbi4gTGlrZSBgc3luY1N0YXRlYCwgYHN5bmNEaWZmYFxuICAgKiBhY2NlcHRzIG9wdGlvbmFsIGBvbkpvaW5gIGFuZCBgb25MZWF2ZWAgY2FsbGJhY2tzIHRvIHJlYWN0IHRvIGEgdXNlclxuICAgKiBqb2luaW5nIG9yIGxlYXZpbmcgZnJvbSBhIGRldmljZS5cbiAgICpcbiAgICogQHJldHVybnMge1ByZXNlbmNlfVxuICAgKi9cbiAgc3RhdGljIHN5bmNEaWZmKHN0YXRlLCBkaWZmLCBvbkpvaW4sIG9uTGVhdmUpe1xuICAgIGxldCB7am9pbnMsIGxlYXZlc30gPSB0aGlzLmNsb25lKGRpZmYpXG4gICAgaWYoIW9uSm9pbil7IG9uSm9pbiA9IGZ1bmN0aW9uICgpeyB9IH1cbiAgICBpZighb25MZWF2ZSl7IG9uTGVhdmUgPSBmdW5jdGlvbiAoKXsgfSB9XG5cbiAgICB0aGlzLm1hcChqb2lucywgKGtleSwgbmV3UHJlc2VuY2UpID0+IHtcbiAgICAgIGxldCBjdXJyZW50UHJlc2VuY2UgPSBzdGF0ZVtrZXldXG4gICAgICBzdGF0ZVtrZXldID0gdGhpcy5jbG9uZShuZXdQcmVzZW5jZSlcbiAgICAgIGlmKGN1cnJlbnRQcmVzZW5jZSl7XG4gICAgICAgIGxldCBqb2luZWRSZWZzID0gc3RhdGVba2V5XS5tZXRhcy5tYXAobSA9PiBtLnBoeF9yZWYpXG4gICAgICAgIGxldCBjdXJNZXRhcyA9IGN1cnJlbnRQcmVzZW5jZS5tZXRhcy5maWx0ZXIobSA9PiBqb2luZWRSZWZzLmluZGV4T2YobS5waHhfcmVmKSA8IDApXG4gICAgICAgIHN0YXRlW2tleV0ubWV0YXMudW5zaGlmdCguLi5jdXJNZXRhcylcbiAgICAgIH1cbiAgICAgIG9uSm9pbihrZXksIGN1cnJlbnRQcmVzZW5jZSwgbmV3UHJlc2VuY2UpXG4gICAgfSlcbiAgICB0aGlzLm1hcChsZWF2ZXMsIChrZXksIGxlZnRQcmVzZW5jZSkgPT4ge1xuICAgICAgbGV0IGN1cnJlbnRQcmVzZW5jZSA9IHN0YXRlW2tleV1cbiAgICAgIGlmKCFjdXJyZW50UHJlc2VuY2UpeyByZXR1cm4gfVxuICAgICAgbGV0IHJlZnNUb1JlbW92ZSA9IGxlZnRQcmVzZW5jZS5tZXRhcy5tYXAobSA9PiBtLnBoeF9yZWYpXG4gICAgICBjdXJyZW50UHJlc2VuY2UubWV0YXMgPSBjdXJyZW50UHJlc2VuY2UubWV0YXMuZmlsdGVyKHAgPT4ge1xuICAgICAgICByZXR1cm4gcmVmc1RvUmVtb3ZlLmluZGV4T2YocC5waHhfcmVmKSA8IDBcbiAgICAgIH0pXG4gICAgICBvbkxlYXZlKGtleSwgY3VycmVudFByZXNlbmNlLCBsZWZ0UHJlc2VuY2UpXG4gICAgICBpZihjdXJyZW50UHJlc2VuY2UubWV0YXMubGVuZ3RoID09PSAwKXtcbiAgICAgICAgZGVsZXRlIHN0YXRlW2tleV1cbiAgICAgIH1cbiAgICB9KVxuICAgIHJldHVybiBzdGF0ZVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGFycmF5IG9mIHByZXNlbmNlcywgd2l0aCBzZWxlY3RlZCBtZXRhZGF0YS5cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHByZXNlbmNlc1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjaG9vc2VyXG4gICAqXG4gICAqIEByZXR1cm5zIHtQcmVzZW5jZX1cbiAgICovXG4gIHN0YXRpYyBsaXN0KHByZXNlbmNlcywgY2hvb3Nlcil7XG4gICAgaWYoIWNob29zZXIpeyBjaG9vc2VyID0gZnVuY3Rpb24gKGtleSwgcHJlcyl7IHJldHVybiBwcmVzIH0gfVxuXG4gICAgcmV0dXJuIHRoaXMubWFwKHByZXNlbmNlcywgKGtleSwgcHJlc2VuY2UpID0+IHtcbiAgICAgIHJldHVybiBjaG9vc2VyKGtleSwgcHJlc2VuY2UpXG4gICAgfSlcbiAgfVxuXG4gIC8vIHByaXZhdGVcblxuICBzdGF0aWMgbWFwKG9iaiwgZnVuYyl7XG4gICAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG9iaikubWFwKGtleSA9PiBmdW5jKGtleSwgb2JqW2tleV0pKVxuICB9XG5cbiAgc3RhdGljIGNsb25lKG9iail7IHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG9iaikpIH1cbn1cbiIsICIvKiBUaGUgZGVmYXVsdCBzZXJpYWxpemVyIGZvciBlbmNvZGluZyBhbmQgZGVjb2RpbmcgbWVzc2FnZXMgKi9cbmltcG9ydCB7XG4gIENIQU5ORUxfRVZFTlRTXG59IGZyb20gXCIuL2NvbnN0YW50c1wiXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgSEVBREVSX0xFTkdUSDogMSxcbiAgTUVUQV9MRU5HVEg6IDQsXG4gIEtJTkRTOiB7cHVzaDogMCwgcmVwbHk6IDEsIGJyb2FkY2FzdDogMn0sXG5cbiAgZW5jb2RlKG1zZywgY2FsbGJhY2spe1xuICAgIGlmKG1zZy5wYXlsb2FkLmNvbnN0cnVjdG9yID09PSBBcnJheUJ1ZmZlcil7XG4gICAgICByZXR1cm4gY2FsbGJhY2sodGhpcy5iaW5hcnlFbmNvZGUobXNnKSlcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IHBheWxvYWQgPSBbbXNnLmpvaW5fcmVmLCBtc2cucmVmLCBtc2cudG9waWMsIG1zZy5ldmVudCwgbXNnLnBheWxvYWRdXG4gICAgICByZXR1cm4gY2FsbGJhY2soSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpXG4gICAgfVxuICB9LFxuXG4gIGRlY29kZShyYXdQYXlsb2FkLCBjYWxsYmFjayl7XG4gICAgaWYocmF3UGF5bG9hZC5jb25zdHJ1Y3RvciA9PT0gQXJyYXlCdWZmZXIpe1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKHRoaXMuYmluYXJ5RGVjb2RlKHJhd1BheWxvYWQpKVxuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgW2pvaW5fcmVmLCByZWYsIHRvcGljLCBldmVudCwgcGF5bG9hZF0gPSBKU09OLnBhcnNlKHJhd1BheWxvYWQpXG4gICAgICByZXR1cm4gY2FsbGJhY2soe2pvaW5fcmVmLCByZWYsIHRvcGljLCBldmVudCwgcGF5bG9hZH0pXG4gICAgfVxuICB9LFxuXG4gIC8vIHByaXZhdGVcblxuICBiaW5hcnlFbmNvZGUobWVzc2FnZSl7XG4gICAgbGV0IHtqb2luX3JlZiwgcmVmLCBldmVudCwgdG9waWMsIHBheWxvYWR9ID0gbWVzc2FnZVxuICAgIGxldCBtZXRhTGVuZ3RoID0gdGhpcy5NRVRBX0xFTkdUSCArIGpvaW5fcmVmLmxlbmd0aCArIHJlZi5sZW5ndGggKyB0b3BpYy5sZW5ndGggKyBldmVudC5sZW5ndGhcbiAgICBsZXQgaGVhZGVyID0gbmV3IEFycmF5QnVmZmVyKHRoaXMuSEVBREVSX0xFTkdUSCArIG1ldGFMZW5ndGgpXG4gICAgbGV0IHZpZXcgPSBuZXcgRGF0YVZpZXcoaGVhZGVyKVxuICAgIGxldCBvZmZzZXQgPSAwXG5cbiAgICB2aWV3LnNldFVpbnQ4KG9mZnNldCsrLCB0aGlzLktJTkRTLnB1c2gpIC8vIGtpbmRcbiAgICB2aWV3LnNldFVpbnQ4KG9mZnNldCsrLCBqb2luX3JlZi5sZW5ndGgpXG4gICAgdmlldy5zZXRVaW50OChvZmZzZXQrKywgcmVmLmxlbmd0aClcbiAgICB2aWV3LnNldFVpbnQ4KG9mZnNldCsrLCB0b3BpYy5sZW5ndGgpXG4gICAgdmlldy5zZXRVaW50OChvZmZzZXQrKywgZXZlbnQubGVuZ3RoKVxuICAgIEFycmF5LmZyb20oam9pbl9yZWYsIGNoYXIgPT4gdmlldy5zZXRVaW50OChvZmZzZXQrKywgY2hhci5jaGFyQ29kZUF0KDApKSlcbiAgICBBcnJheS5mcm9tKHJlZiwgY2hhciA9PiB2aWV3LnNldFVpbnQ4KG9mZnNldCsrLCBjaGFyLmNoYXJDb2RlQXQoMCkpKVxuICAgIEFycmF5LmZyb20odG9waWMsIGNoYXIgPT4gdmlldy5zZXRVaW50OChvZmZzZXQrKywgY2hhci5jaGFyQ29kZUF0KDApKSlcbiAgICBBcnJheS5mcm9tKGV2ZW50LCBjaGFyID0+IHZpZXcuc2V0VWludDgob2Zmc2V0KyssIGNoYXIuY2hhckNvZGVBdCgwKSkpXG5cbiAgICB2YXIgY29tYmluZWQgPSBuZXcgVWludDhBcnJheShoZWFkZXIuYnl0ZUxlbmd0aCArIHBheWxvYWQuYnl0ZUxlbmd0aClcbiAgICBjb21iaW5lZC5zZXQobmV3IFVpbnQ4QXJyYXkoaGVhZGVyKSwgMClcbiAgICBjb21iaW5lZC5zZXQobmV3IFVpbnQ4QXJyYXkocGF5bG9hZCksIGhlYWRlci5ieXRlTGVuZ3RoKVxuXG4gICAgcmV0dXJuIGNvbWJpbmVkLmJ1ZmZlclxuICB9LFxuXG4gIGJpbmFyeURlY29kZShidWZmZXIpe1xuICAgIGxldCB2aWV3ID0gbmV3IERhdGFWaWV3KGJ1ZmZlcilcbiAgICBsZXQga2luZCA9IHZpZXcuZ2V0VWludDgoMClcbiAgICBsZXQgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigpXG4gICAgc3dpdGNoKGtpbmQpe1xuICAgICAgY2FzZSB0aGlzLktJTkRTLnB1c2g6IHJldHVybiB0aGlzLmRlY29kZVB1c2goYnVmZmVyLCB2aWV3LCBkZWNvZGVyKVxuICAgICAgY2FzZSB0aGlzLktJTkRTLnJlcGx5OiByZXR1cm4gdGhpcy5kZWNvZGVSZXBseShidWZmZXIsIHZpZXcsIGRlY29kZXIpXG4gICAgICBjYXNlIHRoaXMuS0lORFMuYnJvYWRjYXN0OiByZXR1cm4gdGhpcy5kZWNvZGVCcm9hZGNhc3QoYnVmZmVyLCB2aWV3LCBkZWNvZGVyKVxuICAgIH1cbiAgfSxcblxuICBkZWNvZGVQdXNoKGJ1ZmZlciwgdmlldywgZGVjb2Rlcil7XG4gICAgbGV0IGpvaW5SZWZTaXplID0gdmlldy5nZXRVaW50OCgxKVxuICAgIGxldCB0b3BpY1NpemUgPSB2aWV3LmdldFVpbnQ4KDIpXG4gICAgbGV0IGV2ZW50U2l6ZSA9IHZpZXcuZ2V0VWludDgoMylcbiAgICBsZXQgb2Zmc2V0ID0gdGhpcy5IRUFERVJfTEVOR1RIICsgdGhpcy5NRVRBX0xFTkdUSCAtIDEgLy8gcHVzaGVzIGhhdmUgbm8gcmVmXG4gICAgbGV0IGpvaW5SZWYgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBqb2luUmVmU2l6ZSkpXG4gICAgb2Zmc2V0ID0gb2Zmc2V0ICsgam9pblJlZlNpemVcbiAgICBsZXQgdG9waWMgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyB0b3BpY1NpemUpKVxuICAgIG9mZnNldCA9IG9mZnNldCArIHRvcGljU2l6ZVxuICAgIGxldCBldmVudCA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIGV2ZW50U2l6ZSkpXG4gICAgb2Zmc2V0ID0gb2Zmc2V0ICsgZXZlbnRTaXplXG4gICAgbGV0IGRhdGEgPSBidWZmZXIuc2xpY2Uob2Zmc2V0LCBidWZmZXIuYnl0ZUxlbmd0aClcbiAgICByZXR1cm4ge2pvaW5fcmVmOiBqb2luUmVmLCByZWY6IG51bGwsIHRvcGljOiB0b3BpYywgZXZlbnQ6IGV2ZW50LCBwYXlsb2FkOiBkYXRhfVxuICB9LFxuXG4gIGRlY29kZVJlcGx5KGJ1ZmZlciwgdmlldywgZGVjb2Rlcil7XG4gICAgbGV0IGpvaW5SZWZTaXplID0gdmlldy5nZXRVaW50OCgxKVxuICAgIGxldCByZWZTaXplID0gdmlldy5nZXRVaW50OCgyKVxuICAgIGxldCB0b3BpY1NpemUgPSB2aWV3LmdldFVpbnQ4KDMpXG4gICAgbGV0IGV2ZW50U2l6ZSA9IHZpZXcuZ2V0VWludDgoNClcbiAgICBsZXQgb2Zmc2V0ID0gdGhpcy5IRUFERVJfTEVOR1RIICsgdGhpcy5NRVRBX0xFTkdUSFxuICAgIGxldCBqb2luUmVmID0gZGVjb2Rlci5kZWNvZGUoYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgam9pblJlZlNpemUpKVxuICAgIG9mZnNldCA9IG9mZnNldCArIGpvaW5SZWZTaXplXG4gICAgbGV0IHJlZiA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIHJlZlNpemUpKVxuICAgIG9mZnNldCA9IG9mZnNldCArIHJlZlNpemVcbiAgICBsZXQgdG9waWMgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyB0b3BpY1NpemUpKVxuICAgIG9mZnNldCA9IG9mZnNldCArIHRvcGljU2l6ZVxuICAgIGxldCBldmVudCA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIGV2ZW50U2l6ZSkpXG4gICAgb2Zmc2V0ID0gb2Zmc2V0ICsgZXZlbnRTaXplXG4gICAgbGV0IGRhdGEgPSBidWZmZXIuc2xpY2Uob2Zmc2V0LCBidWZmZXIuYnl0ZUxlbmd0aClcbiAgICBsZXQgcGF5bG9hZCA9IHtzdGF0dXM6IGV2ZW50LCByZXNwb25zZTogZGF0YX1cbiAgICByZXR1cm4ge2pvaW5fcmVmOiBqb2luUmVmLCByZWY6IHJlZiwgdG9waWM6IHRvcGljLCBldmVudDogQ0hBTk5FTF9FVkVOVFMucmVwbHksIHBheWxvYWQ6IHBheWxvYWR9XG4gIH0sXG5cbiAgZGVjb2RlQnJvYWRjYXN0KGJ1ZmZlciwgdmlldywgZGVjb2Rlcil7XG4gICAgbGV0IHRvcGljU2l6ZSA9IHZpZXcuZ2V0VWludDgoMSlcbiAgICBsZXQgZXZlbnRTaXplID0gdmlldy5nZXRVaW50OCgyKVxuICAgIGxldCBvZmZzZXQgPSB0aGlzLkhFQURFUl9MRU5HVEggKyAyXG4gICAgbGV0IHRvcGljID0gZGVjb2Rlci5kZWNvZGUoYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgdG9waWNTaXplKSlcbiAgICBvZmZzZXQgPSBvZmZzZXQgKyB0b3BpY1NpemVcbiAgICBsZXQgZXZlbnQgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBldmVudFNpemUpKVxuICAgIG9mZnNldCA9IG9mZnNldCArIGV2ZW50U2l6ZVxuICAgIGxldCBkYXRhID0gYnVmZmVyLnNsaWNlKG9mZnNldCwgYnVmZmVyLmJ5dGVMZW5ndGgpXG5cbiAgICByZXR1cm4ge2pvaW5fcmVmOiBudWxsLCByZWY6IG51bGwsIHRvcGljOiB0b3BpYywgZXZlbnQ6IGV2ZW50LCBwYXlsb2FkOiBkYXRhfVxuICB9XG59XG4iLCAiaW1wb3J0IHtcbiAgZ2xvYmFsLFxuICBwaHhXaW5kb3csXG4gIENIQU5ORUxfRVZFTlRTLFxuICBERUZBVUxUX1RJTUVPVVQsXG4gIERFRkFVTFRfVlNOLFxuICBTT0NLRVRfU1RBVEVTLFxuICBUUkFOU1BPUlRTLFxuICBXU19DTE9TRV9OT1JNQUxcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCJcblxuaW1wb3J0IHtcbiAgY2xvc3VyZVxufSBmcm9tIFwiLi91dGlsc1wiXG5cbmltcG9ydCBBamF4IGZyb20gXCIuL2FqYXhcIlxuaW1wb3J0IENoYW5uZWwgZnJvbSBcIi4vY2hhbm5lbFwiXG5pbXBvcnQgTG9uZ1BvbGwgZnJvbSBcIi4vbG9uZ3BvbGxcIlxuaW1wb3J0IFNlcmlhbGl6ZXIgZnJvbSBcIi4vc2VyaWFsaXplclwiXG5pbXBvcnQgVGltZXIgZnJvbSBcIi4vdGltZXJcIlxuXG4vKiogSW5pdGlhbGl6ZXMgdGhlIFNvY2tldCAqXG4gKlxuICogRm9yIElFOCBzdXBwb3J0IHVzZSBhbiBFUzUtc2hpbSAoaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltKVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBlbmRQb2ludCAtIFRoZSBzdHJpbmcgV2ViU29ja2V0IGVuZHBvaW50LCBpZSwgYFwid3M6Ly9leGFtcGxlLmNvbS9zb2NrZXRcImAsXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYFwid3NzOi8vZXhhbXBsZS5jb21cImBcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgXCIvc29ja2V0XCJgIChpbmhlcml0ZWQgaG9zdCAmIHByb3RvY29sKVxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRzXSAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRzLnRyYW5zcG9ydF0gLSBUaGUgV2Vic29ja2V0IFRyYW5zcG9ydCwgZm9yIGV4YW1wbGUgV2ViU29ja2V0IG9yIFBob2VuaXguTG9uZ1BvbGwuXG4gKlxuICogRGVmYXVsdHMgdG8gV2ViU29ja2V0IHdpdGggYXV0b21hdGljIExvbmdQb2xsIGZhbGxiYWNrLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdHMuZW5jb2RlXSAtIFRoZSBmdW5jdGlvbiB0byBlbmNvZGUgb3V0Z29pbmcgbWVzc2FnZXMuXG4gKlxuICogRGVmYXVsdHMgdG8gSlNPTiBlbmNvZGVyLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRzLmRlY29kZV0gLSBUaGUgZnVuY3Rpb24gdG8gZGVjb2RlIGluY29taW5nIG1lc3NhZ2VzLlxuICpcbiAqIERlZmF1bHRzIHRvIEpTT046XG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogKHBheWxvYWQsIGNhbGxiYWNrKSA9PiBjYWxsYmFjayhKU09OLnBhcnNlKHBheWxvYWQpKVxuICogYGBgXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLnRpbWVvdXRdIC0gVGhlIGRlZmF1bHQgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgdG8gdHJpZ2dlciBwdXNoIHRpbWVvdXRzLlxuICpcbiAqIERlZmF1bHRzIGBERUZBVUxUX1RJTUVPVVRgXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdHMuaGVhcnRiZWF0SW50ZXJ2YWxNc10gLSBUaGUgbWlsbGlzZWMgaW50ZXJ2YWwgdG8gc2VuZCBhIGhlYXJ0YmVhdCBtZXNzYWdlXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdHMucmVjb25uZWN0QWZ0ZXJNc10gLSBUaGUgb3B0aW9uYWwgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSBtaWxsaXNlY1xuICogc29ja2V0IHJlY29ubmVjdCBpbnRlcnZhbC5cbiAqXG4gKiBEZWZhdWx0cyB0byBzdGVwcGVkIGJhY2tvZmYgb2Y6XG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogZnVuY3Rpb24odHJpZXMpe1xuICogICByZXR1cm4gWzEwLCA1MCwgMTAwLCAxNTAsIDIwMCwgMjUwLCA1MDAsIDEwMDAsIDIwMDBdW3RyaWVzIC0gMV0gfHwgNTAwMFxuICogfVxuICogYGBgYFxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5yZWpvaW5BZnRlck1zXSAtIFRoZSBvcHRpb25hbCBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIG1pbGxpc2VjXG4gKiByZWpvaW4gaW50ZXJ2YWwgZm9yIGluZGl2aWR1YWwgY2hhbm5lbHMuXG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogZnVuY3Rpb24odHJpZXMpe1xuICogICByZXR1cm4gWzEwMDAsIDIwMDAsIDUwMDBdW3RyaWVzIC0gMV0gfHwgMTAwMDBcbiAqIH1cbiAqIGBgYGBcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0cy5sb2dnZXJdIC0gVGhlIG9wdGlvbmFsIGZ1bmN0aW9uIGZvciBzcGVjaWFsaXplZCBsb2dnaW5nLCBpZTpcbiAqXG4gKiBgYGBqYXZhc2NyaXB0XG4gKiBmdW5jdGlvbihraW5kLCBtc2csIGRhdGEpIHtcbiAqICAgY29uc29sZS5sb2coYCR7a2luZH06ICR7bXNnfWAsIGRhdGEpXG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdHMubG9uZ3BvbGxlclRpbWVvdXRdIC0gVGhlIG1heGltdW0gdGltZW91dCBvZiBhIGxvbmcgcG9sbCBBSkFYIHJlcXVlc3QuXG4gKlxuICogRGVmYXVsdHMgdG8gMjBzIChkb3VibGUgdGhlIHNlcnZlciBsb25nIHBvbGwgdGltZXIpLlxuICpcbiAqIEBwYXJhbSB7KE9iamVjdHxmdW5jdGlvbil9IFtvcHRzLnBhcmFtc10gLSBUaGUgb3B0aW9uYWwgcGFyYW1zIHRvIHBhc3Mgd2hlbiBjb25uZWN0aW5nXG4gKiBAcGFyYW0ge3N0cmluZ30gW29wdHMuYmluYXJ5VHlwZV0gLSBUaGUgYmluYXJ5IHR5cGUgdG8gdXNlIGZvciBiaW5hcnkgV2ViU29ja2V0IGZyYW1lcy5cbiAqXG4gKiBEZWZhdWx0cyB0byBcImFycmF5YnVmZmVyXCJcbiAqXG4gKiBAcGFyYW0ge3Zzbn0gW29wdHMudnNuXSAtIFRoZSBzZXJpYWxpemVyJ3MgcHJvdG9jb2wgdmVyc2lvbiB0byBzZW5kIG9uIGNvbm5lY3QuXG4gKlxuICogRGVmYXVsdHMgdG8gREVGQVVMVF9WU04uXG4qL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU29ja2V0IHtcbiAgY29uc3RydWN0b3IoZW5kUG9pbnQsIG9wdHMgPSB7fSl7XG4gICAgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcyA9IHtvcGVuOiBbXSwgY2xvc2U6IFtdLCBlcnJvcjogW10sIG1lc3NhZ2U6IFtdfVxuICAgIHRoaXMuY2hhbm5lbHMgPSBbXVxuICAgIHRoaXMuc2VuZEJ1ZmZlciA9IFtdXG4gICAgdGhpcy5yZWYgPSAwXG4gICAgdGhpcy50aW1lb3V0ID0gb3B0cy50aW1lb3V0IHx8IERFRkFVTFRfVElNRU9VVFxuICAgIHRoaXMudHJhbnNwb3J0ID0gb3B0cy50cmFuc3BvcnQgfHwgZ2xvYmFsLldlYlNvY2tldCB8fCBMb25nUG9sbFxuICAgIHRoaXMuZXN0YWJsaXNoZWRDb25uZWN0aW9ucyA9IDBcbiAgICB0aGlzLmRlZmF1bHRFbmNvZGVyID0gU2VyaWFsaXplci5lbmNvZGUuYmluZChTZXJpYWxpemVyKVxuICAgIHRoaXMuZGVmYXVsdERlY29kZXIgPSBTZXJpYWxpemVyLmRlY29kZS5iaW5kKFNlcmlhbGl6ZXIpXG4gICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gZmFsc2VcbiAgICB0aGlzLmJpbmFyeVR5cGUgPSBvcHRzLmJpbmFyeVR5cGUgfHwgXCJhcnJheWJ1ZmZlclwiXG4gICAgdGhpcy5jb25uZWN0Q2xvY2sgPSAxXG4gICAgaWYodGhpcy50cmFuc3BvcnQgIT09IExvbmdQb2xsKXtcbiAgICAgIHRoaXMuZW5jb2RlID0gb3B0cy5lbmNvZGUgfHwgdGhpcy5kZWZhdWx0RW5jb2RlclxuICAgICAgdGhpcy5kZWNvZGUgPSBvcHRzLmRlY29kZSB8fCB0aGlzLmRlZmF1bHREZWNvZGVyXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZW5jb2RlID0gdGhpcy5kZWZhdWx0RW5jb2RlclxuICAgICAgdGhpcy5kZWNvZGUgPSB0aGlzLmRlZmF1bHREZWNvZGVyXG4gICAgfVxuICAgIGxldCBhd2FpdGluZ0Nvbm5lY3Rpb25PblBhZ2VTaG93ID0gbnVsbFxuICAgIGlmKHBoeFdpbmRvdyAmJiBwaHhXaW5kb3cuYWRkRXZlbnRMaXN0ZW5lcil7XG4gICAgICBwaHhXaW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInBhZ2VoaWRlXCIsIF9lID0+IHtcbiAgICAgICAgaWYodGhpcy5jb25uKXtcbiAgICAgICAgICB0aGlzLmRpc2Nvbm5lY3QoKVxuICAgICAgICAgIGF3YWl0aW5nQ29ubmVjdGlvbk9uUGFnZVNob3cgPSB0aGlzLmNvbm5lY3RDbG9ja1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgcGh4V2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJwYWdlc2hvd1wiLCBfZSA9PiB7XG4gICAgICAgIGlmKGF3YWl0aW5nQ29ubmVjdGlvbk9uUGFnZVNob3cgPT09IHRoaXMuY29ubmVjdENsb2NrKXtcbiAgICAgICAgICBhd2FpdGluZ0Nvbm5lY3Rpb25PblBhZ2VTaG93ID0gbnVsbFxuICAgICAgICAgIHRoaXMuY29ubmVjdCgpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICAgIHRoaXMuaGVhcnRiZWF0SW50ZXJ2YWxNcyA9IG9wdHMuaGVhcnRiZWF0SW50ZXJ2YWxNcyB8fCAzMDAwMFxuICAgIHRoaXMucmVqb2luQWZ0ZXJNcyA9ICh0cmllcykgPT4ge1xuICAgICAgaWYob3B0cy5yZWpvaW5BZnRlck1zKXtcbiAgICAgICAgcmV0dXJuIG9wdHMucmVqb2luQWZ0ZXJNcyh0cmllcylcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBbMTAwMCwgMjAwMCwgNTAwMF1bdHJpZXMgLSAxXSB8fCAxMDAwMFxuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnJlY29ubmVjdEFmdGVyTXMgPSAodHJpZXMpID0+IHtcbiAgICAgIGlmKG9wdHMucmVjb25uZWN0QWZ0ZXJNcyl7XG4gICAgICAgIHJldHVybiBvcHRzLnJlY29ubmVjdEFmdGVyTXModHJpZXMpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gWzEwLCA1MCwgMTAwLCAxNTAsIDIwMCwgMjUwLCA1MDAsIDEwMDAsIDIwMDBdW3RyaWVzIC0gMV0gfHwgNTAwMFxuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmxvZ2dlciA9IG9wdHMubG9nZ2VyIHx8IG51bGxcbiAgICB0aGlzLmxvbmdwb2xsZXJUaW1lb3V0ID0gb3B0cy5sb25ncG9sbGVyVGltZW91dCB8fCAyMDAwMFxuICAgIHRoaXMucGFyYW1zID0gY2xvc3VyZShvcHRzLnBhcmFtcyB8fCB7fSlcbiAgICB0aGlzLmVuZFBvaW50ID0gYCR7ZW5kUG9pbnR9LyR7VFJBTlNQT1JUUy53ZWJzb2NrZXR9YFxuICAgIHRoaXMudnNuID0gb3B0cy52c24gfHwgREVGQVVMVF9WU05cbiAgICB0aGlzLmhlYXJ0YmVhdFRpbWVvdXRUaW1lciA9IG51bGxcbiAgICB0aGlzLmhlYXJ0YmVhdFRpbWVyID0gbnVsbFxuICAgIHRoaXMucGVuZGluZ0hlYXJ0YmVhdFJlZiA9IG51bGxcbiAgICB0aGlzLnJlY29ubmVjdFRpbWVyID0gbmV3IFRpbWVyKCgpID0+IHtcbiAgICAgIHRoaXMudGVhcmRvd24oKCkgPT4gdGhpcy5jb25uZWN0KCkpXG4gICAgfSwgdGhpcy5yZWNvbm5lY3RBZnRlck1zKVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIExvbmdQb2xsIHRyYW5zcG9ydCByZWZlcmVuY2VcbiAgICovXG4gIGdldExvbmdQb2xsVHJhbnNwb3J0KCl7IHJldHVybiBMb25nUG9sbCB9XG5cbiAgLyoqXG4gICAqIERpc2Nvbm5lY3RzIGFuZCByZXBsYWNlcyB0aGUgYWN0aXZlIHRyYW5zcG9ydFxuICAgKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBuZXdUcmFuc3BvcnQgLSBUaGUgbmV3IHRyYW5zcG9ydCBjbGFzcyB0byBpbnN0YW50aWF0ZVxuICAgKlxuICAgKi9cbiAgcmVwbGFjZVRyYW5zcG9ydChuZXdUcmFuc3BvcnQpe1xuICAgIHRoaXMuY29ubmVjdENsb2NrKytcbiAgICB0aGlzLmNsb3NlV2FzQ2xlYW4gPSB0cnVlXG4gICAgdGhpcy5yZWNvbm5lY3RUaW1lci5yZXNldCgpXG4gICAgdGhpcy5zZW5kQnVmZmVyID0gW11cbiAgICBpZih0aGlzLmNvbm4pe1xuICAgICAgdGhpcy5jb25uLmNsb3NlKClcbiAgICAgIHRoaXMuY29ubiA9IG51bGxcbiAgICB9XG4gICAgdGhpcy50cmFuc3BvcnQgPSBuZXdUcmFuc3BvcnRcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBzb2NrZXQgcHJvdG9jb2xcbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ31cbiAgICovXG4gIHByb3RvY29sKCl7IHJldHVybiBsb2NhdGlvbi5wcm90b2NvbC5tYXRjaCgvXmh0dHBzLykgPyBcIndzc1wiIDogXCJ3c1wiIH1cblxuICAvKipcbiAgICogVGhlIGZ1bGx5IHF1YWxpZmllZCBzb2NrZXQgdXJsXG4gICAqXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAqL1xuICBlbmRQb2ludFVSTCgpe1xuICAgIGxldCB1cmkgPSBBamF4LmFwcGVuZFBhcmFtcyhcbiAgICAgIEFqYXguYXBwZW5kUGFyYW1zKHRoaXMuZW5kUG9pbnQsIHRoaXMucGFyYW1zKCkpLCB7dnNuOiB0aGlzLnZzbn0pXG4gICAgaWYodXJpLmNoYXJBdCgwKSAhPT0gXCIvXCIpeyByZXR1cm4gdXJpIH1cbiAgICBpZih1cmkuY2hhckF0KDEpID09PSBcIi9cIil7IHJldHVybiBgJHt0aGlzLnByb3RvY29sKCl9OiR7dXJpfWAgfVxuXG4gICAgcmV0dXJuIGAke3RoaXMucHJvdG9jb2woKX06Ly8ke2xvY2F0aW9uLmhvc3R9JHt1cml9YFxuICB9XG5cbiAgLyoqXG4gICAqIERpc2Nvbm5lY3RzIHRoZSBzb2NrZXRcbiAgICpcbiAgICogU2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9DbG9zZUV2ZW50I1N0YXR1c19jb2RlcyBmb3IgdmFsaWQgc3RhdHVzIGNvZGVzLlxuICAgKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayAtIE9wdGlvbmFsIGNhbGxiYWNrIHdoaWNoIGlzIGNhbGxlZCBhZnRlciBzb2NrZXQgaXMgZGlzY29ubmVjdGVkLlxuICAgKiBAcGFyYW0ge2ludGVnZXJ9IGNvZGUgLSBBIHN0YXR1cyBjb2RlIGZvciBkaXNjb25uZWN0aW9uIChPcHRpb25hbCkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZWFzb24gLSBBIHRleHR1YWwgZGVzY3JpcHRpb24gb2YgdGhlIHJlYXNvbiB0byBkaXNjb25uZWN0LiAoT3B0aW9uYWwpXG4gICAqL1xuICBkaXNjb25uZWN0KGNhbGxiYWNrLCBjb2RlLCByZWFzb24pe1xuICAgIHRoaXMuY29ubmVjdENsb2NrKytcbiAgICB0aGlzLmNsb3NlV2FzQ2xlYW4gPSB0cnVlXG4gICAgdGhpcy5yZWNvbm5lY3RUaW1lci5yZXNldCgpXG4gICAgdGhpcy50ZWFyZG93bihjYWxsYmFjaywgY29kZSwgcmVhc29uKVxuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgLSBUaGUgcGFyYW1zIHRvIHNlbmQgd2hlbiBjb25uZWN0aW5nLCBmb3IgZXhhbXBsZSBge3VzZXJfaWQ6IHVzZXJUb2tlbn1gXG4gICAqXG4gICAqIFBhc3NpbmcgcGFyYW1zIHRvIGNvbm5lY3QgaXMgZGVwcmVjYXRlZDsgcGFzcyB0aGVtIGluIHRoZSBTb2NrZXQgY29uc3RydWN0b3IgaW5zdGVhZDpcbiAgICogYG5ldyBTb2NrZXQoXCIvc29ja2V0XCIsIHtwYXJhbXM6IHt1c2VyX2lkOiB1c2VyVG9rZW59fSlgLlxuICAgKi9cbiAgY29ubmVjdChwYXJhbXMpe1xuICAgIGlmKHBhcmFtcyl7XG4gICAgICBjb25zb2xlICYmIGNvbnNvbGUubG9nKFwicGFzc2luZyBwYXJhbXMgdG8gY29ubmVjdCBpcyBkZXByZWNhdGVkLiBJbnN0ZWFkIHBhc3MgOnBhcmFtcyB0byB0aGUgU29ja2V0IGNvbnN0cnVjdG9yXCIpXG4gICAgICB0aGlzLnBhcmFtcyA9IGNsb3N1cmUocGFyYW1zKVxuICAgIH1cbiAgICBpZih0aGlzLmNvbm4peyByZXR1cm4gfVxuXG4gICAgdGhpcy5jb25uZWN0Q2xvY2srK1xuICAgIHRoaXMuY2xvc2VXYXNDbGVhbiA9IGZhbHNlXG4gICAgdGhpcy5jb25uID0gbmV3IHRoaXMudHJhbnNwb3J0KHRoaXMuZW5kUG9pbnRVUkwoKSlcbiAgICB0aGlzLmNvbm4uYmluYXJ5VHlwZSA9IHRoaXMuYmluYXJ5VHlwZVxuICAgIHRoaXMuY29ubi50aW1lb3V0ID0gdGhpcy5sb25ncG9sbGVyVGltZW91dFxuICAgIHRoaXMuY29ubi5vbm9wZW4gPSAoKSA9PiB0aGlzLm9uQ29ubk9wZW4oKVxuICAgIHRoaXMuY29ubi5vbmVycm9yID0gZXJyb3IgPT4gdGhpcy5vbkNvbm5FcnJvcihlcnJvcilcbiAgICB0aGlzLmNvbm4ub25tZXNzYWdlID0gZXZlbnQgPT4gdGhpcy5vbkNvbm5NZXNzYWdlKGV2ZW50KVxuICAgIHRoaXMuY29ubi5vbmNsb3NlID0gZXZlbnQgPT4gdGhpcy5vbkNvbm5DbG9zZShldmVudClcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2dzIHRoZSBtZXNzYWdlLiBPdmVycmlkZSBgdGhpcy5sb2dnZXJgIGZvciBzcGVjaWFsaXplZCBsb2dnaW5nLiBub29wcyBieSBkZWZhdWx0XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBraW5kXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtc2dcbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGFcbiAgICovXG4gIGxvZyhraW5kLCBtc2csIGRhdGEpeyB0aGlzLmxvZ2dlcihraW5kLCBtc2csIGRhdGEpIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0cnVlIGlmIGEgbG9nZ2VyIGhhcyBiZWVuIHNldCBvbiB0aGlzIHNvY2tldC5cbiAgICovXG4gIGhhc0xvZ2dlcigpeyByZXR1cm4gdGhpcy5sb2dnZXIgIT09IG51bGwgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgY2FsbGJhY2tzIGZvciBjb25uZWN0aW9uIG9wZW4gZXZlbnRzXG4gICAqXG4gICAqIEBleGFtcGxlIHNvY2tldC5vbk9wZW4oZnVuY3Rpb24oKXsgY29uc29sZS5pbmZvKFwidGhlIHNvY2tldCB3YXMgb3BlbmVkXCIpIH0pXG4gICAqXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBvbk9wZW4oY2FsbGJhY2spe1xuICAgIGxldCByZWYgPSB0aGlzLm1ha2VSZWYoKVxuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3Mub3Blbi5wdXNoKFtyZWYsIGNhbGxiYWNrXSlcbiAgICByZXR1cm4gcmVmXG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGNhbGxiYWNrcyBmb3IgY29ubmVjdGlvbiBjbG9zZSBldmVudHNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIG9uQ2xvc2UoY2FsbGJhY2spe1xuICAgIGxldCByZWYgPSB0aGlzLm1ha2VSZWYoKVxuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3MuY2xvc2UucHVzaChbcmVmLCBjYWxsYmFja10pXG4gICAgcmV0dXJuIHJlZlxuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyBjYWxsYmFja3MgZm9yIGNvbm5lY3Rpb24gZXJyb3IgZXZlbnRzXG4gICAqXG4gICAqIEBleGFtcGxlIHNvY2tldC5vbkVycm9yKGZ1bmN0aW9uKGVycm9yKXsgYWxlcnQoXCJBbiBlcnJvciBvY2N1cnJlZFwiKSB9KVxuICAgKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgb25FcnJvcihjYWxsYmFjayl7XG4gICAgbGV0IHJlZiA9IHRoaXMubWFrZVJlZigpXG4gICAgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcy5lcnJvci5wdXNoKFtyZWYsIGNhbGxiYWNrXSlcbiAgICByZXR1cm4gcmVmXG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGNhbGxiYWNrcyBmb3IgY29ubmVjdGlvbiBtZXNzYWdlIGV2ZW50c1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgb25NZXNzYWdlKGNhbGxiYWNrKXtcbiAgICBsZXQgcmVmID0gdGhpcy5tYWtlUmVmKClcbiAgICB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzLm1lc3NhZ2UucHVzaChbcmVmLCBjYWxsYmFja10pXG4gICAgcmV0dXJuIHJlZlxuICB9XG5cbiAgLyoqXG4gICAqIFBpbmdzIHRoZSBzZXJ2ZXIgYW5kIGludm9rZXMgdGhlIGNhbGxiYWNrIHdpdGggdGhlIFJUVCBpbiBtaWxsaXNlY29uZHNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICpcbiAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBwaW5nIHdhcyBwdXNoZWQgb3IgZmFsc2UgaWYgdW5hYmxlIHRvIGJlIHB1c2hlZC5cbiAgICovXG4gIHBpbmcoY2FsbGJhY2spe1xuICAgIGlmKCF0aGlzLmlzQ29ubmVjdGVkKCkpeyByZXR1cm4gZmFsc2UgfVxuICAgIGxldCByZWYgPSB0aGlzLm1ha2VSZWYoKVxuICAgIGxldCBzdGFydFRpbWUgPSBEYXRlLm5vdygpXG4gICAgdGhpcy5wdXNoKHt0b3BpYzogXCJwaG9lbml4XCIsIGV2ZW50OiBcImhlYXJ0YmVhdFwiLCBwYXlsb2FkOiB7fSwgcmVmOiByZWZ9KVxuICAgIGxldCBvbk1zZ1JlZiA9IHRoaXMub25NZXNzYWdlKG1zZyA9PiB7XG4gICAgICBpZihtc2cucmVmID09PSByZWYpe1xuICAgICAgICB0aGlzLm9mZihbb25Nc2dSZWZdKVxuICAgICAgICBjYWxsYmFjayhEYXRlLm5vdygpIC0gc3RhcnRUaW1lKVxuICAgICAgfVxuICAgIH0pXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuICBjbGVhckhlYXJ0YmVhdHMoKXtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5oZWFydGJlYXRUaW1lcilcbiAgICBjbGVhclRpbWVvdXQodGhpcy5oZWFydGJlYXRUaW1lb3V0VGltZXIpXG4gIH1cblxuICBvbkNvbm5PcGVuKCl7XG4gICAgaWYodGhpcy5oYXNMb2dnZXIoKSkgdGhpcy5sb2coXCJ0cmFuc3BvcnRcIiwgYGNvbm5lY3RlZCB0byAke3RoaXMuZW5kUG9pbnRVUkwoKX1gKVxuICAgIHRoaXMuY2xvc2VXYXNDbGVhbiA9IGZhbHNlXG4gICAgdGhpcy5lc3RhYmxpc2hlZENvbm5lY3Rpb25zKytcbiAgICB0aGlzLmZsdXNoU2VuZEJ1ZmZlcigpXG4gICAgdGhpcy5yZWNvbm5lY3RUaW1lci5yZXNldCgpXG4gICAgdGhpcy5yZXNldEhlYXJ0YmVhdCgpXG4gICAgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcy5vcGVuLmZvckVhY2goKFssIGNhbGxiYWNrXSkgPT4gY2FsbGJhY2soKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuICBoZWFydGJlYXRUaW1lb3V0KCl7XG4gICAgaWYodGhpcy5wZW5kaW5nSGVhcnRiZWF0UmVmKXtcbiAgICAgIHRoaXMucGVuZGluZ0hlYXJ0YmVhdFJlZiA9IG51bGxcbiAgICAgIGlmKHRoaXMuaGFzTG9nZ2VyKCkpeyB0aGlzLmxvZyhcInRyYW5zcG9ydFwiLCBcImhlYXJ0YmVhdCB0aW1lb3V0LiBBdHRlbXB0aW5nIHRvIHJlLWVzdGFibGlzaCBjb25uZWN0aW9uXCIpIH1cbiAgICAgIHRoaXMudHJpZ2dlckNoYW5FcnJvcigpXG4gICAgICB0aGlzLmNsb3NlV2FzQ2xlYW4gPSBmYWxzZVxuICAgICAgdGhpcy50ZWFyZG93bigoKSA9PiB0aGlzLnJlY29ubmVjdFRpbWVyLnNjaGVkdWxlVGltZW91dCgpLCBXU19DTE9TRV9OT1JNQUwsIFwiaGVhcnRiZWF0IHRpbWVvdXRcIilcbiAgICB9XG4gIH1cblxuICByZXNldEhlYXJ0YmVhdCgpe1xuICAgIGlmKHRoaXMuY29ubiAmJiB0aGlzLmNvbm4uc2tpcEhlYXJ0YmVhdCl7IHJldHVybiB9XG4gICAgdGhpcy5wZW5kaW5nSGVhcnRiZWF0UmVmID0gbnVsbFxuICAgIHRoaXMuY2xlYXJIZWFydGJlYXRzKClcbiAgICB0aGlzLmhlYXJ0YmVhdFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB0aGlzLnNlbmRIZWFydGJlYXQoKSwgdGhpcy5oZWFydGJlYXRJbnRlcnZhbE1zKVxuICB9XG5cbiAgdGVhcmRvd24oY2FsbGJhY2ssIGNvZGUsIHJlYXNvbil7XG4gICAgaWYoIXRoaXMuY29ubil7XG4gICAgICByZXR1cm4gY2FsbGJhY2sgJiYgY2FsbGJhY2soKVxuICAgIH1cblxuICAgIHRoaXMud2FpdEZvckJ1ZmZlckRvbmUoKCkgPT4ge1xuICAgICAgaWYodGhpcy5jb25uKXtcbiAgICAgICAgaWYoY29kZSl7IHRoaXMuY29ubi5jbG9zZShjb2RlLCByZWFzb24gfHwgXCJcIikgfSBlbHNlIHsgdGhpcy5jb25uLmNsb3NlKCkgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLndhaXRGb3JTb2NrZXRDbG9zZWQoKCkgPT4ge1xuICAgICAgICBpZih0aGlzLmNvbm4pe1xuICAgICAgICAgIHRoaXMuY29ubi5vbm9wZW4gPSBmdW5jdGlvbiAoKXsgfSAvLyBub29wXG4gICAgICAgICAgdGhpcy5jb25uLm9uZXJyb3IgPSBmdW5jdGlvbiAoKXsgfSAvLyBub29wXG4gICAgICAgICAgdGhpcy5jb25uLm9ubWVzc2FnZSA9IGZ1bmN0aW9uICgpeyB9IC8vIG5vb3BcbiAgICAgICAgICB0aGlzLmNvbm4ub25jbG9zZSA9IGZ1bmN0aW9uICgpeyB9IC8vIG5vb3BcbiAgICAgICAgICB0aGlzLmNvbm4gPSBudWxsXG4gICAgICAgIH1cblxuICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjaygpXG4gICAgICB9KVxuICAgIH0pXG4gIH1cblxuICB3YWl0Rm9yQnVmZmVyRG9uZShjYWxsYmFjaywgdHJpZXMgPSAxKXtcbiAgICBpZih0cmllcyA9PT0gNSB8fCAhdGhpcy5jb25uIHx8ICF0aGlzLmNvbm4uYnVmZmVyZWRBbW91bnQpe1xuICAgICAgY2FsbGJhY2soKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLndhaXRGb3JCdWZmZXJEb25lKGNhbGxiYWNrLCB0cmllcyArIDEpXG4gICAgfSwgMTUwICogdHJpZXMpXG4gIH1cblxuICB3YWl0Rm9yU29ja2V0Q2xvc2VkKGNhbGxiYWNrLCB0cmllcyA9IDEpe1xuICAgIGlmKHRyaWVzID09PSA1IHx8ICF0aGlzLmNvbm4gfHwgdGhpcy5jb25uLnJlYWR5U3RhdGUgPT09IFNPQ0tFVF9TVEFURVMuY2xvc2VkKXtcbiAgICAgIGNhbGxiYWNrKClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy53YWl0Rm9yU29ja2V0Q2xvc2VkKGNhbGxiYWNrLCB0cmllcyArIDEpXG4gICAgfSwgMTUwICogdHJpZXMpXG4gIH1cblxuICBvbkNvbm5DbG9zZShldmVudCl7XG4gICAgbGV0IGNsb3NlQ29kZSA9IGV2ZW50ICYmIGV2ZW50LmNvZGVcbiAgICBpZih0aGlzLmhhc0xvZ2dlcigpKSB0aGlzLmxvZyhcInRyYW5zcG9ydFwiLCBcImNsb3NlXCIsIGV2ZW50KVxuICAgIHRoaXMudHJpZ2dlckNoYW5FcnJvcigpXG4gICAgdGhpcy5jbGVhckhlYXJ0YmVhdHMoKVxuICAgIGlmKCF0aGlzLmNsb3NlV2FzQ2xlYW4gJiYgY2xvc2VDb2RlICE9PSAxMDAwKXtcbiAgICAgIHRoaXMucmVjb25uZWN0VGltZXIuc2NoZWR1bGVUaW1lb3V0KClcbiAgICB9XG4gICAgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcy5jbG9zZS5mb3JFYWNoKChbLCBjYWxsYmFja10pID0+IGNhbGxiYWNrKGV2ZW50KSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgb25Db25uRXJyb3IoZXJyb3Ipe1xuICAgIGlmKHRoaXMuaGFzTG9nZ2VyKCkpIHRoaXMubG9nKFwidHJhbnNwb3J0XCIsIGVycm9yKVxuICAgIGxldCB0cmFuc3BvcnRCZWZvcmUgPSB0aGlzLnRyYW5zcG9ydFxuICAgIGxldCBlc3RhYmxpc2hlZEJlZm9yZSA9IHRoaXMuZXN0YWJsaXNoZWRDb25uZWN0aW9uc1xuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3MuZXJyb3IuZm9yRWFjaCgoWywgY2FsbGJhY2tdKSA9PiB7XG4gICAgICBjYWxsYmFjayhlcnJvciwgdHJhbnNwb3J0QmVmb3JlLCBlc3RhYmxpc2hlZEJlZm9yZSlcbiAgICB9KVxuICAgIGlmKHRyYW5zcG9ydEJlZm9yZSA9PT0gdGhpcy50cmFuc3BvcnQgfHwgZXN0YWJsaXNoZWRCZWZvcmUgPiAwKXtcbiAgICAgIHRoaXMudHJpZ2dlckNoYW5FcnJvcigpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICB0cmlnZ2VyQ2hhbkVycm9yKCl7XG4gICAgdGhpcy5jaGFubmVscy5mb3JFYWNoKGNoYW5uZWwgPT4ge1xuICAgICAgaWYoIShjaGFubmVsLmlzRXJyb3JlZCgpIHx8IGNoYW5uZWwuaXNMZWF2aW5nKCkgfHwgY2hhbm5lbC5pc0Nsb3NlZCgpKSl7XG4gICAgICAgIGNoYW5uZWwudHJpZ2dlcihDSEFOTkVMX0VWRU5UUy5lcnJvcilcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAqL1xuICBjb25uZWN0aW9uU3RhdGUoKXtcbiAgICBzd2l0Y2godGhpcy5jb25uICYmIHRoaXMuY29ubi5yZWFkeVN0YXRlKXtcbiAgICAgIGNhc2UgU09DS0VUX1NUQVRFUy5jb25uZWN0aW5nOiByZXR1cm4gXCJjb25uZWN0aW5nXCJcbiAgICAgIGNhc2UgU09DS0VUX1NUQVRFUy5vcGVuOiByZXR1cm4gXCJvcGVuXCJcbiAgICAgIGNhc2UgU09DS0VUX1NUQVRFUy5jbG9zaW5nOiByZXR1cm4gXCJjbG9zaW5nXCJcbiAgICAgIGRlZmF1bHQ6IHJldHVybiBcImNsb3NlZFwiXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgKi9cbiAgaXNDb25uZWN0ZWQoKXsgcmV0dXJuIHRoaXMuY29ubmVjdGlvblN0YXRlKCkgPT09IFwib3BlblwiIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICpcbiAgICogQHBhcmFtIHtDaGFubmVsfVxuICAgKi9cbiAgcmVtb3ZlKGNoYW5uZWwpe1xuICAgIHRoaXMub2ZmKGNoYW5uZWwuc3RhdGVDaGFuZ2VSZWZzKVxuICAgIHRoaXMuY2hhbm5lbHMgPSB0aGlzLmNoYW5uZWxzLmZpbHRlcihjID0+IGMuam9pblJlZigpICE9PSBjaGFubmVsLmpvaW5SZWYoKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGBvbk9wZW5gLCBgb25DbG9zZWAsIGBvbkVycm9yLGAgYW5kIGBvbk1lc3NhZ2VgIHJlZ2lzdHJhdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSB7cmVmc30gLSBsaXN0IG9mIHJlZnMgcmV0dXJuZWQgYnkgY2FsbHMgdG9cbiAgICogICAgICAgICAgICAgICAgIGBvbk9wZW5gLCBgb25DbG9zZWAsIGBvbkVycm9yLGAgYW5kIGBvbk1lc3NhZ2VgXG4gICAqL1xuICBvZmYocmVmcyl7XG4gICAgZm9yKGxldCBrZXkgaW4gdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcyl7XG4gICAgICB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzW2tleV0gPSB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzW2tleV0uZmlsdGVyKChbcmVmXSkgPT4ge1xuICAgICAgICByZXR1cm4gcmVmcy5pbmRleE9mKHJlZikgPT09IC0xXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWF0ZXMgYSBuZXcgY2hhbm5lbCBmb3IgdGhlIGdpdmVuIHRvcGljXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0b3BpY1xuICAgKiBAcGFyYW0ge09iamVjdH0gY2hhblBhcmFtcyAtIFBhcmFtZXRlcnMgZm9yIHRoZSBjaGFubmVsXG4gICAqIEByZXR1cm5zIHtDaGFubmVsfVxuICAgKi9cbiAgY2hhbm5lbCh0b3BpYywgY2hhblBhcmFtcyA9IHt9KXtcbiAgICBsZXQgY2hhbiA9IG5ldyBDaGFubmVsKHRvcGljLCBjaGFuUGFyYW1zLCB0aGlzKVxuICAgIHRoaXMuY2hhbm5lbHMucHVzaChjaGFuKVxuICAgIHJldHVybiBjaGFuXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGFcbiAgICovXG4gIHB1c2goZGF0YSl7XG4gICAgaWYodGhpcy5oYXNMb2dnZXIoKSl7XG4gICAgICBsZXQge3RvcGljLCBldmVudCwgcGF5bG9hZCwgcmVmLCBqb2luX3JlZn0gPSBkYXRhXG4gICAgICB0aGlzLmxvZyhcInB1c2hcIiwgYCR7dG9waWN9ICR7ZXZlbnR9ICgke2pvaW5fcmVmfSwgJHtyZWZ9KWAsIHBheWxvYWQpXG4gICAgfVxuXG4gICAgaWYodGhpcy5pc0Nvbm5lY3RlZCgpKXtcbiAgICAgIHRoaXMuZW5jb2RlKGRhdGEsIHJlc3VsdCA9PiB0aGlzLmNvbm4uc2VuZChyZXN1bHQpKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNlbmRCdWZmZXIucHVzaCgoKSA9PiB0aGlzLmVuY29kZShkYXRhLCByZXN1bHQgPT4gdGhpcy5jb25uLnNlbmQocmVzdWx0KSkpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgbmV4dCBtZXNzYWdlIHJlZiwgYWNjb3VudGluZyBmb3Igb3ZlcmZsb3dzXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAqL1xuICBtYWtlUmVmKCl7XG4gICAgbGV0IG5ld1JlZiA9IHRoaXMucmVmICsgMVxuICAgIGlmKG5ld1JlZiA9PT0gdGhpcy5yZWYpeyB0aGlzLnJlZiA9IDAgfSBlbHNlIHsgdGhpcy5yZWYgPSBuZXdSZWYgfVxuXG4gICAgcmV0dXJuIHRoaXMucmVmLnRvU3RyaW5nKClcbiAgfVxuXG4gIHNlbmRIZWFydGJlYXQoKXtcbiAgICBpZih0aGlzLnBlbmRpbmdIZWFydGJlYXRSZWYgJiYgIXRoaXMuaXNDb25uZWN0ZWQoKSl7IHJldHVybiB9XG4gICAgdGhpcy5wZW5kaW5nSGVhcnRiZWF0UmVmID0gdGhpcy5tYWtlUmVmKClcbiAgICB0aGlzLnB1c2goe3RvcGljOiBcInBob2VuaXhcIiwgZXZlbnQ6IFwiaGVhcnRiZWF0XCIsIHBheWxvYWQ6IHt9LCByZWY6IHRoaXMucGVuZGluZ0hlYXJ0YmVhdFJlZn0pXG4gICAgdGhpcy5oZWFydGJlYXRUaW1lb3V0VGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHRoaXMuaGVhcnRiZWF0VGltZW91dCgpLCB0aGlzLmhlYXJ0YmVhdEludGVydmFsTXMpXG4gIH1cblxuICBmbHVzaFNlbmRCdWZmZXIoKXtcbiAgICBpZih0aGlzLmlzQ29ubmVjdGVkKCkgJiYgdGhpcy5zZW5kQnVmZmVyLmxlbmd0aCA+IDApe1xuICAgICAgdGhpcy5zZW5kQnVmZmVyLmZvckVhY2goY2FsbGJhY2sgPT4gY2FsbGJhY2soKSlcbiAgICAgIHRoaXMuc2VuZEJ1ZmZlciA9IFtdXG4gICAgfVxuICB9XG5cbiAgb25Db25uTWVzc2FnZShyYXdNZXNzYWdlKXtcbiAgICB0aGlzLmRlY29kZShyYXdNZXNzYWdlLmRhdGEsIG1zZyA9PiB7XG4gICAgICBsZXQge3RvcGljLCBldmVudCwgcGF5bG9hZCwgcmVmLCBqb2luX3JlZn0gPSBtc2dcbiAgICAgIGlmKHJlZiAmJiByZWYgPT09IHRoaXMucGVuZGluZ0hlYXJ0YmVhdFJlZil7XG4gICAgICAgIHRoaXMuY2xlYXJIZWFydGJlYXRzKClcbiAgICAgICAgdGhpcy5wZW5kaW5nSGVhcnRiZWF0UmVmID0gbnVsbFxuICAgICAgICB0aGlzLmhlYXJ0YmVhdFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB0aGlzLnNlbmRIZWFydGJlYXQoKSwgdGhpcy5oZWFydGJlYXRJbnRlcnZhbE1zKVxuICAgICAgfVxuXG4gICAgICBpZih0aGlzLmhhc0xvZ2dlcigpKSB0aGlzLmxvZyhcInJlY2VpdmVcIiwgYCR7cGF5bG9hZC5zdGF0dXMgfHwgXCJcIn0gJHt0b3BpY30gJHtldmVudH0gJHtyZWYgJiYgXCIoXCIgKyByZWYgKyBcIilcIiB8fCBcIlwifWAsIHBheWxvYWQpXG5cbiAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCB0aGlzLmNoYW5uZWxzLmxlbmd0aDsgaSsrKXtcbiAgICAgICAgY29uc3QgY2hhbm5lbCA9IHRoaXMuY2hhbm5lbHNbaV1cbiAgICAgICAgaWYoIWNoYW5uZWwuaXNNZW1iZXIodG9waWMsIGV2ZW50LCBwYXlsb2FkLCBqb2luX3JlZikpeyBjb250aW51ZSB9XG4gICAgICAgIGNoYW5uZWwudHJpZ2dlcihldmVudCwgcGF5bG9hZCwgcmVmLCBqb2luX3JlZilcbiAgICAgIH1cblxuICAgICAgZm9yKGxldCBpID0gMDsgaSA8IHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3MubWVzc2FnZS5sZW5ndGg7IGkrKyl7XG4gICAgICAgIGxldCBbLCBjYWxsYmFja10gPSB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzLm1lc3NhZ2VbaV1cbiAgICAgICAgY2FsbGJhY2sobXNnKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICBsZWF2ZU9wZW5Ub3BpYyh0b3BpYyl7XG4gICAgbGV0IGR1cENoYW5uZWwgPSB0aGlzLmNoYW5uZWxzLmZpbmQoYyA9PiBjLnRvcGljID09PSB0b3BpYyAmJiAoYy5pc0pvaW5lZCgpIHx8IGMuaXNKb2luaW5nKCkpKVxuICAgIGlmKGR1cENoYW5uZWwpe1xuICAgICAgaWYodGhpcy5oYXNMb2dnZXIoKSkgdGhpcy5sb2coXCJ0cmFuc3BvcnRcIiwgYGxlYXZpbmcgZHVwbGljYXRlIHRvcGljIFwiJHt0b3BpY31cImApXG4gICAgICBkdXBDaGFubmVsLmxlYXZlKClcbiAgICB9XG4gIH1cbn1cbiIsICJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBpbml0KCkge1xuICBjb25zdCBjYW52YXNFbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjZ2hvc3RcIik7XG5cbiAgaWYgKCFjYW52YXNFbCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJib2R5XCIpLmNsYXNzTGlzdC5hZGQoXCJzcG9va3lcIik7XG5cbiAgY29uc3QgbW91c2VUaHJlc2hvbGQgPSAwLjE7XG4gIGNvbnN0IGRldmljZVBpeGVsUmF0aW8gPSBNYXRoLm1pbih3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbywgMik7XG5cbiAgY29uc3QgbW91c2UgPSB7XG4gICAgeDogMC4zICogd2luZG93LmlubmVyV2lkdGgsXG4gICAgeTogMC4zICogd2luZG93LmlubmVySGVpZ2h0LFxuICAgIHRYOiAwLjI1ICogd2luZG93LmlubmVyV2lkdGgsXG4gICAgdFk6IDAuNDUgKiB3aW5kb3cuaW5uZXJIZWlnaHQsXG4gICAgbW92aW5nOiBmYWxzZSxcbiAgICBjb250cm9sc1BhZGRpbmc6IDAsXG4gIH07XG5cbiAgY29uc3QgcGFyYW1zID0ge1xuICAgIHNpemU6IDAuMDcsXG4gICAgdGFpbDoge1xuICAgICAgZG90c051bWJlcjogMjUsXG4gICAgICBzcHJpbmc6IDEuNCxcbiAgICAgIGZyaWN0aW9uOiAwLjMsXG4gICAgICBtYXhHcmF2aXR5OiA1MCxcbiAgICAgIGdyYXZpdHk6IDM1LFxuICAgIH0sXG4gICAgc21pbGU6IDEsXG4gICAgbWFpbkNvbG9yOiBbMC45OCwgMC45NiwgMC45Nl0sXG4gICAgYm9yZGVyQ29sb3I6IFswLjIsIDAuNSwgMC43XSxcbiAgICBpc0ZsYXRDb2xvcjogZmFsc2UsXG4gIH07XG5cbiAgY29uc3QgdGV4dHVyZUVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgY29uc3QgdGV4dHVyZUN0eCA9IHRleHR1cmVFbC5nZXRDb250ZXh0KFwiMmRcIik7XG4gIGNvbnN0IHBvaW50ZXJUcmFpbCA9IG5ldyBBcnJheShwYXJhbXMudGFpbC5kb3RzTnVtYmVyKTtcbiAgbGV0IGRvdFNpemUgPSAoaSkgPT5cbiAgICBwYXJhbXMuc2l6ZSAqXG4gICAgd2luZG93LmlubmVySGVpZ2h0ICpcbiAgICAoMSAtIDAuMiAqIE1hdGgucG93KCgzICogaSkgLyBwYXJhbXMudGFpbC5kb3RzTnVtYmVyIC0gMSwgMikpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmFtcy50YWlsLmRvdHNOdW1iZXI7IGkrKykge1xuICAgIHBvaW50ZXJUcmFpbFtpXSA9IHtcbiAgICAgIHg6IG1vdXNlLngsXG4gICAgICB5OiBtb3VzZS55LFxuICAgICAgdng6IDAsXG4gICAgICB2eTogMCxcbiAgICAgIG9wYWNpdHk6IDAuMDQgKyAwLjMgKiBNYXRoLnBvdygxIC0gaSAvIHBhcmFtcy50YWlsLmRvdHNOdW1iZXIsIDQpLFxuICAgICAgYm9yZGVyZWQ6IDAuNiAqIE1hdGgucG93KDEgLSBpIC8gcG9pbnRlclRyYWlsLmxlbmd0aCwgMSksXG4gICAgICByOiBkb3RTaXplKGkpLFxuICAgIH07XG4gIH1cblxuICBsZXQgdW5pZm9ybXM7XG4gIGNvbnN0IGdsID0gaW5pdFNoYWRlcigpO1xuXG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicmVzaXplXCIsIHJlc2l6ZUNhbnZhcyk7XG4gIHJlc2l6ZUNhbnZhcygpO1xuICByZW5kZXIoKTtcblxuICAvLyBBcnJnaFxuICBzZXRJbnRlcnZhbChyZXNpemVDYW52YXMsIDUwMCk7XG5cbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIiwgKGUpID0+IHtcbiAgICB1cGRhdGVNb3VzZVBvc2l0aW9uKGUucGFnZVgsIGUucGFnZVkpO1xuICB9KTtcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIiwgKGUpID0+IHtcbiAgICB1cGRhdGVNb3VzZVBvc2l0aW9uKGUudGFyZ2V0VG91Y2hlc1swXS5wYWdlWCwgZS50YXJnZXRUb3VjaGVzWzBdLnBhZ2VZKTtcbiAgfSk7XG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcbiAgICB1cGRhdGVNb3VzZVBvc2l0aW9uKGUucGFnZVgsIGUucGFnZVkpO1xuICB9KTtcblxuICBsZXQgbW92aW5nVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IChtb3VzZS5tb3ZpbmcgPSBmYWxzZSksIDMwMCk7XG5cbiAgZnVuY3Rpb24gdXBkYXRlTW91c2VQb3NpdGlvbihlWCwgZVkpIHtcbiAgICBtb3VzZS5tb3ZpbmcgPSB0cnVlO1xuICAgIGlmIChtb3VzZS5jb250cm9sc1BhZGRpbmcgPCAwKSB7XG4gICAgICBtb3VzZS5tb3ZpbmcgPSBmYWxzZTtcbiAgICB9XG4gICAgY2xlYXJUaW1lb3V0KG1vdmluZ1RpbWVyKTtcbiAgICBtb3ZpbmdUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgbW91c2UubW92aW5nID0gZmFsc2U7XG4gICAgfSwgMzAwKTtcblxuICAgIG1vdXNlLnRYID0gZVg7XG5cbiAgICBjb25zdCBzaXplID0gcGFyYW1zLnNpemUgKiB3aW5kb3cuaW5uZXJIZWlnaHQ7XG4gICAgZVkgLT0gMC42ICogc2l6ZTtcbiAgICBtb3VzZS50WSA9IGVZID4gc2l6ZSA/IGVZIDogc2l6ZTtcbiAgICBtb3VzZS50WSAtPSBtb3VzZS5jb250cm9sc1BhZGRpbmc7XG4gIH1cblxuICBmdW5jdGlvbiBpbml0U2hhZGVyKCkge1xuICAgIGNvbnN0IHZzU291cmNlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJ2ZXJ0U2hhZGVyXCIpLmlubmVySFRNTDtcbiAgICBjb25zdCBmc1NvdXJjZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiZnJhZ1NoYWRlclwiKS5pbm5lckhUTUw7XG5cbiAgICBjb25zdCBnbCA9XG4gICAgICBjYW52YXNFbC5nZXRDb250ZXh0KFwid2ViZ2xcIikgfHwgY2FudmFzRWwuZ2V0Q29udGV4dChcImV4cGVyaW1lbnRhbC13ZWJnbFwiKTtcblxuICAgIGlmICghZ2wpIHtcbiAgICAgIGFsZXJ0KFwiV2ViR0wgaXMgbm90IHN1cHBvcnRlZCBieSB5b3VyIGJyb3dzZXIuXCIpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNyZWF0ZVNoYWRlcihnbCwgc291cmNlQ29kZSwgdHlwZSkge1xuICAgICAgY29uc3Qgc2hhZGVyID0gZ2wuY3JlYXRlU2hhZGVyKHR5cGUpO1xuICAgICAgZ2wuc2hhZGVyU291cmNlKHNoYWRlciwgc291cmNlQ29kZSk7XG4gICAgICBnbC5jb21waWxlU2hhZGVyKHNoYWRlcik7XG5cbiAgICAgIGlmICghZ2wuZ2V0U2hhZGVyUGFyYW1ldGVyKHNoYWRlciwgZ2wuQ09NUElMRV9TVEFUVVMpKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgXCJBbiBlcnJvciBvY2N1cnJlZCBjb21waWxpbmcgdGhlIHNoYWRlcnM6IFwiICtcbiAgICAgICAgICBnbC5nZXRTaGFkZXJJbmZvTG9nKHNoYWRlciksXG4gICAgICAgICk7XG4gICAgICAgIGdsLmRlbGV0ZVNoYWRlcihzaGFkZXIpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHNoYWRlcjtcbiAgICB9XG5cbiAgICBjb25zdCB2ZXJ0ZXhTaGFkZXIgPSBjcmVhdGVTaGFkZXIoZ2wsIHZzU291cmNlLCBnbC5WRVJURVhfU0hBREVSKTtcbiAgICBjb25zdCBmcmFnbWVudFNoYWRlciA9IGNyZWF0ZVNoYWRlcihnbCwgZnNTb3VyY2UsIGdsLkZSQUdNRU5UX1NIQURFUik7XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVTaGFkZXJQcm9ncmFtKGdsLCB2ZXJ0ZXhTaGFkZXIsIGZyYWdtZW50U2hhZGVyKSB7XG4gICAgICBjb25zdCBwcm9ncmFtID0gZ2wuY3JlYXRlUHJvZ3JhbSgpO1xuICAgICAgZ2wuYXR0YWNoU2hhZGVyKHByb2dyYW0sIHZlcnRleFNoYWRlcik7XG4gICAgICBnbC5hdHRhY2hTaGFkZXIocHJvZ3JhbSwgZnJhZ21lbnRTaGFkZXIpO1xuICAgICAgZ2wubGlua1Byb2dyYW0ocHJvZ3JhbSk7XG5cbiAgICAgIGlmICghZ2wuZ2V0UHJvZ3JhbVBhcmFtZXRlcihwcm9ncmFtLCBnbC5MSU5LX1NUQVRVUykpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICBcIlVuYWJsZSB0byBpbml0aWFsaXplIHRoZSBzaGFkZXIgcHJvZ3JhbTogXCIgK1xuICAgICAgICAgIGdsLmdldFByb2dyYW1JbmZvTG9nKHByb2dyYW0pLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHByb2dyYW07XG4gICAgfVxuXG4gICAgY29uc3Qgc2hhZGVyUHJvZ3JhbSA9IGNyZWF0ZVNoYWRlclByb2dyYW0oZ2wsIHZlcnRleFNoYWRlciwgZnJhZ21lbnRTaGFkZXIpO1xuICAgIHVuaWZvcm1zID0gZ2V0VW5pZm9ybXMoc2hhZGVyUHJvZ3JhbSk7XG5cbiAgICBmdW5jdGlvbiBnZXRVbmlmb3Jtcyhwcm9ncmFtKSB7XG4gICAgICBsZXQgdW5pZm9ybXMgPSBbXTtcbiAgICAgIGxldCB1bmlmb3JtQ291bnQgPSBnbC5nZXRQcm9ncmFtUGFyYW1ldGVyKHByb2dyYW0sIGdsLkFDVElWRV9VTklGT1JNUyk7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHVuaWZvcm1Db3VudDsgaSsrKSB7XG4gICAgICAgIGxldCB1bmlmb3JtTmFtZSA9IGdsLmdldEFjdGl2ZVVuaWZvcm0ocHJvZ3JhbSwgaSkubmFtZTtcbiAgICAgICAgdW5pZm9ybXNbdW5pZm9ybU5hbWVdID0gZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKHByb2dyYW0sIHVuaWZvcm1OYW1lKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB1bmlmb3JtcztcbiAgICB9XG5cbiAgICBjb25zdCB2ZXJ0aWNlcyA9IG5ldyBGbG9hdDMyQXJyYXkoWy0xLCAtMSwgMSwgLTEsIC0xLCAxLCAxLCAxXSk7XG5cbiAgICBjb25zdCB2ZXJ0ZXhCdWZmZXIgPSBnbC5jcmVhdGVCdWZmZXIoKTtcbiAgICBnbC5iaW5kQnVmZmVyKGdsLkFSUkFZX0JVRkZFUiwgdmVydGV4QnVmZmVyKTtcbiAgICBnbC5idWZmZXJEYXRhKGdsLkFSUkFZX0JVRkZFUiwgdmVydGljZXMsIGdsLlNUQVRJQ19EUkFXKTtcblxuICAgIGdsLnVzZVByb2dyYW0oc2hhZGVyUHJvZ3JhbSk7XG5cbiAgICBjb25zdCBwb3NpdGlvbkxvY2F0aW9uID0gZ2wuZ2V0QXR0cmliTG9jYXRpb24oc2hhZGVyUHJvZ3JhbSwgXCJhX3Bvc2l0aW9uXCIpO1xuICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHBvc2l0aW9uTG9jYXRpb24pO1xuXG4gICAgZ2wuYmluZEJ1ZmZlcihnbC5BUlJBWV9CVUZGRVIsIHZlcnRleEJ1ZmZlcik7XG4gICAgZ2wudmVydGV4QXR0cmliUG9pbnRlcihwb3NpdGlvbkxvY2F0aW9uLCAyLCBnbC5GTE9BVCwgZmFsc2UsIDAsIDApO1xuXG4gICAgY29uc3QgY2FudmFzVGV4dHVyZSA9IGdsLmNyZWF0ZVRleHR1cmUoKTtcbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCBjYW52YXNUZXh0dXJlKTtcbiAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfTUlOX0ZJTFRFUiwgZ2wuTElORUFSKTtcbiAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfTUFHX0ZJTFRFUiwgZ2wuTElORUFSKTtcbiAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfV1JBUF9TLCBnbC5DTEFNUF9UT19FREdFKTtcbiAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfV1JBUF9ULCBnbC5DTEFNUF9UT19FREdFKTtcbiAgICBnbC50ZXhJbWFnZTJEKFxuICAgICAgZ2wuVEVYVFVSRV8yRCxcbiAgICAgIDAsXG4gICAgICBnbC5SR0JBLFxuICAgICAgZ2wuUkdCQSxcbiAgICAgIGdsLlVOU0lHTkVEX0JZVEUsXG4gICAgICB0ZXh0dXJlRWwsXG4gICAgKTtcbiAgICBnbC51bmlmb3JtMWkodW5pZm9ybXMudV90ZXh0dXJlLCAwKTtcblxuICAgIGdsLnVuaWZvcm0xZih1bmlmb3Jtcy51X3NpemUsIHBhcmFtcy5zaXplKTtcbiAgICBnbC51bmlmb3JtM2YoXG4gICAgICB1bmlmb3Jtcy51X21haW5fY29sb3IsXG4gICAgICBwYXJhbXMubWFpbkNvbG9yWzBdLFxuICAgICAgcGFyYW1zLm1haW5Db2xvclsxXSxcbiAgICAgIHBhcmFtcy5tYWluQ29sb3JbMl0sXG4gICAgKTtcbiAgICBnbC51bmlmb3JtM2YoXG4gICAgICB1bmlmb3Jtcy51X2JvcmRlcl9jb2xvcixcbiAgICAgIHBhcmFtcy5ib3JkZXJDb2xvclswXSxcbiAgICAgIHBhcmFtcy5ib3JkZXJDb2xvclsxXSxcbiAgICAgIHBhcmFtcy5ib3JkZXJDb2xvclsyXSxcbiAgICApO1xuXG4gICAgcmV0dXJuIGdsO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlVGV4dHVyZSgpIHtcbiAgICB0ZXh0dXJlQ3R4LmZpbGxTdHlsZSA9IFwiYmxhY2tcIjtcbiAgICB0ZXh0dXJlQ3R4LmZpbGxSZWN0KDAsIDAsIHRleHR1cmVFbC53aWR0aCwgdGV4dHVyZUVsLmhlaWdodCk7XG5cbiAgICBwb2ludGVyVHJhaWwuZm9yRWFjaCgocCwgcElkeCkgPT4ge1xuICAgICAgaWYgKHBJZHggPT09IDApIHtcbiAgICAgICAgcC54ID0gbW91c2UueDtcbiAgICAgICAgcC55ID0gbW91c2UueTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHAudnggKz0gKHBvaW50ZXJUcmFpbFtwSWR4IC0gMV0ueCAtIHAueCkgKiBwYXJhbXMudGFpbC5zcHJpbmc7XG4gICAgICAgIHAudnggKj0gcGFyYW1zLnRhaWwuZnJpY3Rpb247XG5cbiAgICAgICAgcC52eSArPSAocG9pbnRlclRyYWlsW3BJZHggLSAxXS55IC0gcC55KSAqIHBhcmFtcy50YWlsLnNwcmluZztcbiAgICAgICAgcC52eSAqPSBwYXJhbXMudGFpbC5mcmljdGlvbjtcbiAgICAgICAgcC52eSArPSBwYXJhbXMudGFpbC5ncmF2aXR5O1xuXG4gICAgICAgIHAueCArPSBwLnZ4O1xuICAgICAgICBwLnkgKz0gcC52eTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZ3JkID0gdGV4dHVyZUN0eC5jcmVhdGVSYWRpYWxHcmFkaWVudChcbiAgICAgICAgcC54LFxuICAgICAgICBwLnksXG4gICAgICAgIHAuciAqIHAuYm9yZGVyZWQsXG4gICAgICAgIHAueCxcbiAgICAgICAgcC55LFxuICAgICAgICBwLnIsXG4gICAgICApO1xuICAgICAgZ3JkLmFkZENvbG9yU3RvcCgwLCBcInJnYmEoMjU1LCAyNTUsIDI1NSwgXCIgKyBwLm9wYWNpdHkgKyBcIilcIik7XG4gICAgICBncmQuYWRkQ29sb3JTdG9wKDEsIFwicmdiYSgyNTUsIDI1NSwgMjU1LCAwKVwiKTtcblxuICAgICAgdGV4dHVyZUN0eC5iZWdpblBhdGgoKTtcbiAgICAgIHRleHR1cmVDdHguZmlsbFN0eWxlID0gZ3JkO1xuICAgICAgdGV4dHVyZUN0eC5hcmMocC54LCBwLnksIHAuciwgMCwgTWF0aC5QSSAqIDIpO1xuICAgICAgdGV4dHVyZUN0eC5maWxsKCk7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgY29uc3QgY3VycmVudFRpbWUgPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICBnbC51bmlmb3JtMWYodW5pZm9ybXMudV90aW1lLCBjdXJyZW50VGltZSk7XG5cbiAgICBnbC5jbGVhckNvbG9yKDAuMCwgMC4wLCAwLjAsIDEuMCk7XG4gICAgZ2wuY2xlYXIoZ2wuQ09MT1JfQlVGRkVSX0JJVCk7XG4gICAgZ2wuZHJhd0FycmF5cyhnbC5UUklBTkdMRV9TVFJJUCwgMCwgNCk7XG5cbiAgICBpZiAobW91c2UubW92aW5nKSB7XG4gICAgICBwYXJhbXMuc21pbGUgLT0gMC4wNTtcbiAgICAgIHBhcmFtcy5zbWlsZSA9IE1hdGgubWF4KHBhcmFtcy5zbWlsZSwgLTAuMSk7XG4gICAgICBwYXJhbXMudGFpbC5ncmF2aXR5IC09IDEwICogcGFyYW1zLnNpemU7XG4gICAgICBwYXJhbXMudGFpbC5ncmF2aXR5ID0gTWF0aC5tYXgocGFyYW1zLnRhaWwuZ3Jhdml0eSwgMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhcmFtcy5zbWlsZSArPSAwLjAxO1xuICAgICAgcGFyYW1zLnNtaWxlID0gTWF0aC5taW4ocGFyYW1zLnNtaWxlLCAxKTtcbiAgICAgIGlmIChwYXJhbXMudGFpbC5ncmF2aXR5ID4gMzAgKiBwYXJhbXMuc2l6ZSkge1xuICAgICAgICBwYXJhbXMudGFpbC5ncmF2aXR5ID1cbiAgICAgICAgICAoMzAgKyA5ICogKDEgKyBNYXRoLnNpbigwLjAwMiAqIGN1cnJlbnRUaW1lKSkpICogcGFyYW1zLnNpemU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYXJhbXMudGFpbC5ncmF2aXR5ICs9IHBhcmFtcy5zaXplO1xuICAgICAgfVxuICAgIH1cblxuICAgIG1vdXNlLnggKz0gKG1vdXNlLnRYIC0gbW91c2UueCkgKiBtb3VzZVRocmVzaG9sZDtcbiAgICBtb3VzZS55ICs9IChtb3VzZS50WSAtIG1vdXNlLnkpICogbW91c2VUaHJlc2hvbGQ7XG5cbiAgICBnbC51bmlmb3JtMWYodW5pZm9ybXMudV9zbWlsZSwgcGFyYW1zLnNtaWxlKTtcbiAgICBnbC51bmlmb3JtMmYoXG4gICAgICB1bmlmb3Jtcy51X3BvaW50ZXIsXG4gICAgICBtb3VzZS54IC8gd2luZG93LmlubmVyV2lkdGgsXG4gICAgICAxIC0gbW91c2UueSAvIHdpbmRvdy5pbm5lckhlaWdodCxcbiAgICApO1xuICAgIGdsLnVuaWZvcm0yZihcbiAgICAgIHVuaWZvcm1zLnVfdGFyZ2V0X3BvaW50ZXIsXG4gICAgICBtb3VzZS50WCAvIHdpbmRvdy5pbm5lcldpZHRoLFxuICAgICAgMSAtIG1vdXNlLnRZIC8gd2luZG93LmlubmVySGVpZ2h0LFxuICAgICk7XG5cbiAgICB1cGRhdGVUZXh0dXJlKCk7XG5cbiAgICBnbC50ZXhJbWFnZTJEKFxuICAgICAgZ2wuVEVYVFVSRV8yRCxcbiAgICAgIDAsXG4gICAgICBnbC5SR0JBLFxuICAgICAgZ2wuUkdCQSxcbiAgICAgIGdsLlVOU0lHTkVEX0JZVEUsXG4gICAgICB0ZXh0dXJlRWwsXG4gICAgKTtcbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUocmVuZGVyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc2l6ZUNhbnZhcygpIHtcbiAgICBjYW52YXNFbC53aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoICogZGV2aWNlUGl4ZWxSYXRpbztcbiAgICBjYW52YXNFbC5oZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHQgKiBkZXZpY2VQaXhlbFJhdGlvO1xuICAgIHRleHR1cmVFbC53aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuICAgIHRleHR1cmVFbC5oZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHQ7XG4gICAgZ2wudmlld3BvcnQoMCwgMCwgY2FudmFzRWwud2lkdGgsIGNhbnZhc0VsLmhlaWdodCk7XG4gICAgZ2wudW5pZm9ybTFmKHVuaWZvcm1zLnVfcmF0aW8sIGNhbnZhc0VsLndpZHRoIC8gY2FudmFzRWwuaGVpZ2h0KTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmFtcy50YWlsLmRvdHNOdW1iZXI7IGkrKykge1xuICAgICAgcG9pbnRlclRyYWlsW2ldLnIgPSBkb3RTaXplKGkpO1xuICAgIH1cbiAgfVxufVxuIiwgIi8vIGNhbnZhcy1jb25mZXR0aSB2MS42LjAgYnVpbHQgb24gMjAyMi0xMC0yNFQyMToyNjo0MS42MTlaXG52YXIgbW9kdWxlID0ge307XG5cbi8vIHNvdXJjZSBjb250ZW50XG4oZnVuY3Rpb24gbWFpbihnbG9iYWwsIG1vZHVsZSwgaXNXb3JrZXIsIHdvcmtlclNpemUpIHtcbiAgdmFyIGNhblVzZVdvcmtlciA9ICEhKFxuICAgIGdsb2JhbC5Xb3JrZXIgJiZcbiAgICBnbG9iYWwuQmxvYiAmJlxuICAgIGdsb2JhbC5Qcm9taXNlICYmXG4gICAgZ2xvYmFsLk9mZnNjcmVlbkNhbnZhcyAmJlxuICAgIGdsb2JhbC5PZmZzY3JlZW5DYW52YXNSZW5kZXJpbmdDb250ZXh0MkQgJiZcbiAgICBnbG9iYWwuSFRNTENhbnZhc0VsZW1lbnQgJiZcbiAgICBnbG9iYWwuSFRNTENhbnZhc0VsZW1lbnQucHJvdG90eXBlLnRyYW5zZmVyQ29udHJvbFRvT2Zmc2NyZWVuICYmXG4gICAgZ2xvYmFsLlVSTCAmJlxuICAgIGdsb2JhbC5VUkwuY3JlYXRlT2JqZWN0VVJMKTtcblxuICBmdW5jdGlvbiBub29wKCkge31cblxuICAvLyBjcmVhdGUgYSBwcm9taXNlIGlmIGl0IGV4aXN0cywgb3RoZXJ3aXNlLCBqdXN0XG4gIC8vIGNhbGwgdGhlIGZ1bmN0aW9uIGRpcmVjdGx5XG4gIGZ1bmN0aW9uIHByb21pc2UoZnVuYykge1xuICAgIHZhciBNb2R1bGVQcm9taXNlID0gbW9kdWxlLmV4cG9ydHMuUHJvbWlzZTtcbiAgICB2YXIgUHJvbSA9IE1vZHVsZVByb21pc2UgIT09IHZvaWQgMCA/IE1vZHVsZVByb21pc2UgOiBnbG9iYWwuUHJvbWlzZTtcblxuICAgIGlmICh0eXBlb2YgUHJvbSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIG5ldyBQcm9tKGZ1bmMpO1xuICAgIH1cblxuICAgIGZ1bmMobm9vcCwgbm9vcCk7XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZhciByYWYgPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBUSU1FID0gTWF0aC5mbG9vcigxMDAwIC8gNjApO1xuICAgIHZhciBmcmFtZSwgY2FuY2VsO1xuICAgIHZhciBmcmFtZXMgPSB7fTtcbiAgICB2YXIgbGFzdEZyYW1lVGltZSA9IDA7XG5cbiAgICBpZiAodHlwZW9mIHJlcXVlc3RBbmltYXRpb25GcmFtZSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgY2FuY2VsQW5pbWF0aW9uRnJhbWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGZyYW1lID0gZnVuY3Rpb24gKGNiKSB7XG4gICAgICAgIHZhciBpZCA9IE1hdGgucmFuZG9tKCk7XG5cbiAgICAgICAgZnJhbWVzW2lkXSA9IHJlcXVlc3RBbmltYXRpb25GcmFtZShmdW5jdGlvbiBvbkZyYW1lKHRpbWUpIHtcbiAgICAgICAgICBpZiAobGFzdEZyYW1lVGltZSA9PT0gdGltZSB8fCBsYXN0RnJhbWVUaW1lICsgVElNRSAtIDEgPCB0aW1lKSB7XG4gICAgICAgICAgICBsYXN0RnJhbWVUaW1lID0gdGltZTtcbiAgICAgICAgICAgIGRlbGV0ZSBmcmFtZXNbaWRdO1xuXG4gICAgICAgICAgICBjYigpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmcmFtZXNbaWRdID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKG9uRnJhbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIGlkO1xuICAgICAgfTtcbiAgICAgIGNhbmNlbCA9IGZ1bmN0aW9uIChpZCkge1xuICAgICAgICBpZiAoZnJhbWVzW2lkXSkge1xuICAgICAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKGZyYW1lc1tpZF0pO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBmcmFtZSA9IGZ1bmN0aW9uIChjYikge1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChjYiwgVElNRSk7XG4gICAgICB9O1xuICAgICAgY2FuY2VsID0gZnVuY3Rpb24gKHRpbWVyKSB7XG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4geyBmcmFtZTogZnJhbWUsIGNhbmNlbDogY2FuY2VsIH07XG4gIH0oKSk7XG5cbiAgdmFyIGdldFdvcmtlciA9IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHdvcmtlcjtcbiAgICB2YXIgcHJvbTtcbiAgICB2YXIgcmVzb2x2ZXMgPSB7fTtcblxuICAgIGZ1bmN0aW9uIGRlY29yYXRlKHdvcmtlcikge1xuICAgICAgZnVuY3Rpb24gZXhlY3V0ZShvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgICB3b3JrZXIucG9zdE1lc3NhZ2UoeyBvcHRpb25zOiBvcHRpb25zIHx8IHt9LCBjYWxsYmFjazogY2FsbGJhY2sgfSk7XG4gICAgICB9XG4gICAgICB3b3JrZXIuaW5pdCA9IGZ1bmN0aW9uIGluaXRXb3JrZXIoY2FudmFzKSB7XG4gICAgICAgIHZhciBvZmZzY3JlZW4gPSBjYW52YXMudHJhbnNmZXJDb250cm9sVG9PZmZzY3JlZW4oKTtcbiAgICAgICAgd29ya2VyLnBvc3RNZXNzYWdlKHsgY2FudmFzOiBvZmZzY3JlZW4gfSwgW29mZnNjcmVlbl0pO1xuICAgICAgfTtcblxuICAgICAgd29ya2VyLmZpcmUgPSBmdW5jdGlvbiBmaXJlV29ya2VyKG9wdGlvbnMsIHNpemUsIGRvbmUpIHtcbiAgICAgICAgaWYgKHByb20pIHtcbiAgICAgICAgICBleGVjdXRlKG9wdGlvbnMsIG51bGwpO1xuICAgICAgICAgIHJldHVybiBwcm9tO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGlkID0gTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMik7XG5cbiAgICAgICAgcHJvbSA9IHByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgICBmdW5jdGlvbiB3b3JrZXJEb25lKG1zZykge1xuICAgICAgICAgICAgaWYgKG1zZy5kYXRhLmNhbGxiYWNrICE9PSBpZCkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRlbGV0ZSByZXNvbHZlc1tpZF07XG4gICAgICAgICAgICB3b3JrZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHdvcmtlckRvbmUpO1xuXG4gICAgICAgICAgICBwcm9tID0gbnVsbDtcbiAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB3b3JrZXIuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHdvcmtlckRvbmUpO1xuICAgICAgICAgIGV4ZWN1dGUob3B0aW9ucywgaWQpO1xuXG4gICAgICAgICAgcmVzb2x2ZXNbaWRdID0gd29ya2VyRG9uZS5iaW5kKG51bGwsIHsgZGF0YTogeyBjYWxsYmFjazogaWQgfX0pO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gcHJvbTtcbiAgICAgIH07XG5cbiAgICAgIHdvcmtlci5yZXNldCA9IGZ1bmN0aW9uIHJlc2V0V29ya2VyKCkge1xuICAgICAgICB3b3JrZXIucG9zdE1lc3NhZ2UoeyByZXNldDogdHJ1ZSB9KTtcblxuICAgICAgICBmb3IgKHZhciBpZCBpbiByZXNvbHZlcykge1xuICAgICAgICAgIHJlc29sdmVzW2lkXSgpO1xuICAgICAgICAgIGRlbGV0ZSByZXNvbHZlc1tpZF07XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmICh3b3JrZXIpIHtcbiAgICAgICAgcmV0dXJuIHdvcmtlcjtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpc1dvcmtlciAmJiBjYW5Vc2VXb3JrZXIpIHtcbiAgICAgICAgdmFyIGNvZGUgPSBbXG4gICAgICAgICAgJ3ZhciBDT05GRVRUSSwgU0laRSA9IHt9LCBtb2R1bGUgPSB7fTsnLFxuICAgICAgICAgICcoJyArIG1haW4udG9TdHJpbmcoKSArICcpKHRoaXMsIG1vZHVsZSwgdHJ1ZSwgU0laRSk7JyxcbiAgICAgICAgICAnb25tZXNzYWdlID0gZnVuY3Rpb24obXNnKSB7JyxcbiAgICAgICAgICAnICBpZiAobXNnLmRhdGEub3B0aW9ucykgeycsXG4gICAgICAgICAgJyAgICBDT05GRVRUSShtc2cuZGF0YS5vcHRpb25zKS50aGVuKGZ1bmN0aW9uICgpIHsnLFxuICAgICAgICAgICcgICAgICBpZiAobXNnLmRhdGEuY2FsbGJhY2spIHsnLFxuICAgICAgICAgICcgICAgICAgIHBvc3RNZXNzYWdlKHsgY2FsbGJhY2s6IG1zZy5kYXRhLmNhbGxiYWNrIH0pOycsXG4gICAgICAgICAgJyAgICAgIH0nLFxuICAgICAgICAgICcgICAgfSk7JyxcbiAgICAgICAgICAnICB9IGVsc2UgaWYgKG1zZy5kYXRhLnJlc2V0KSB7JyxcbiAgICAgICAgICAnICAgIENPTkZFVFRJICYmIENPTkZFVFRJLnJlc2V0KCk7JyxcbiAgICAgICAgICAnICB9IGVsc2UgaWYgKG1zZy5kYXRhLnJlc2l6ZSkgeycsXG4gICAgICAgICAgJyAgICBTSVpFLndpZHRoID0gbXNnLmRhdGEucmVzaXplLndpZHRoOycsXG4gICAgICAgICAgJyAgICBTSVpFLmhlaWdodCA9IG1zZy5kYXRhLnJlc2l6ZS5oZWlnaHQ7JyxcbiAgICAgICAgICAnICB9IGVsc2UgaWYgKG1zZy5kYXRhLmNhbnZhcykgeycsXG4gICAgICAgICAgJyAgICBTSVpFLndpZHRoID0gbXNnLmRhdGEuY2FudmFzLndpZHRoOycsXG4gICAgICAgICAgJyAgICBTSVpFLmhlaWdodCA9IG1zZy5kYXRhLmNhbnZhcy5oZWlnaHQ7JyxcbiAgICAgICAgICAnICAgIENPTkZFVFRJID0gbW9kdWxlLmV4cG9ydHMuY3JlYXRlKG1zZy5kYXRhLmNhbnZhcyk7JyxcbiAgICAgICAgICAnICB9JyxcbiAgICAgICAgICAnfScsXG4gICAgICAgIF0uam9pbignXFxuJyk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgd29ya2VyID0gbmV3IFdvcmtlcihVUkwuY3JlYXRlT2JqZWN0VVJMKG5ldyBCbG9iKFtjb2RlXSkpKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgdHlwZW9mIGNvbnNvbGUgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgY29uc29sZS53YXJuID09PSAnZnVuY3Rpb24nID8gY29uc29sZS53YXJuKCdcdUQ4M0NcdURGOEEgQ291bGQgbm90IGxvYWQgd29ya2VyJywgZSkgOiBudWxsO1xuXG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBkZWNvcmF0ZSh3b3JrZXIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gd29ya2VyO1xuICAgIH07XG4gIH0pKCk7XG5cbiAgdmFyIGRlZmF1bHRzID0ge1xuICAgIHBhcnRpY2xlQ291bnQ6IDUwLFxuICAgIGFuZ2xlOiA5MCxcbiAgICBzcHJlYWQ6IDQ1LFxuICAgIHN0YXJ0VmVsb2NpdHk6IDQ1LFxuICAgIGRlY2F5OiAwLjksXG4gICAgZ3Jhdml0eTogMSxcbiAgICBkcmlmdDogMCxcbiAgICB0aWNrczogMjAwLFxuICAgIHg6IDAuNSxcbiAgICB5OiAwLjUsXG4gICAgc2hhcGVzOiBbJ3NxdWFyZScsICdjaXJjbGUnXSxcbiAgICB6SW5kZXg6IDEwMCxcbiAgICBjb2xvcnM6IFtcbiAgICAgICcjMjZjY2ZmJyxcbiAgICAgICcjYTI1YWZkJyxcbiAgICAgICcjZmY1ZTdlJyxcbiAgICAgICcjODhmZjVhJyxcbiAgICAgICcjZmNmZjQyJyxcbiAgICAgICcjZmZhNjJkJyxcbiAgICAgICcjZmYzNmZmJ1xuICAgIF0sXG4gICAgLy8gcHJvYmFibHkgc2hvdWxkIGJlIHRydWUsIGJ1dCBiYWNrLWNvbXBhdFxuICAgIGRpc2FibGVGb3JSZWR1Y2VkTW90aW9uOiBmYWxzZSxcbiAgICBzY2FsYXI6IDFcbiAgfTtcblxuICBmdW5jdGlvbiBjb252ZXJ0KHZhbCwgdHJhbnNmb3JtKSB7XG4gICAgcmV0dXJuIHRyYW5zZm9ybSA/IHRyYW5zZm9ybSh2YWwpIDogdmFsO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNPayh2YWwpIHtcbiAgICByZXR1cm4gISh2YWwgPT09IG51bGwgfHwgdmFsID09PSB1bmRlZmluZWQpO1xuICB9XG5cbiAgZnVuY3Rpb24gcHJvcChvcHRpb25zLCBuYW1lLCB0cmFuc2Zvcm0pIHtcbiAgICByZXR1cm4gY29udmVydChcbiAgICAgIG9wdGlvbnMgJiYgaXNPayhvcHRpb25zW25hbWVdKSA/IG9wdGlvbnNbbmFtZV0gOiBkZWZhdWx0c1tuYW1lXSxcbiAgICAgIHRyYW5zZm9ybVxuICAgICk7XG4gIH1cblxuICBmdW5jdGlvbiBvbmx5UG9zaXRpdmVJbnQobnVtYmVyKXtcbiAgICByZXR1cm4gbnVtYmVyIDwgMCA/IDAgOiBNYXRoLmZsb29yKG51bWJlcik7XG4gIH1cblxuICBmdW5jdGlvbiByYW5kb21JbnQobWluLCBtYXgpIHtcbiAgICAvLyBbbWluLCBtYXgpXG4gICAgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIChtYXggLSBtaW4pKSArIG1pbjtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRvRGVjaW1hbChzdHIpIHtcbiAgICByZXR1cm4gcGFyc2VJbnQoc3RyLCAxNik7XG4gIH1cblxuICBmdW5jdGlvbiBjb2xvcnNUb1JnYihjb2xvcnMpIHtcbiAgICByZXR1cm4gY29sb3JzLm1hcChoZXhUb1JnYik7XG4gIH1cblxuICBmdW5jdGlvbiBoZXhUb1JnYihzdHIpIHtcbiAgICB2YXIgdmFsID0gU3RyaW5nKHN0cikucmVwbGFjZSgvW14wLTlhLWZdL2dpLCAnJyk7XG5cbiAgICBpZiAodmFsLmxlbmd0aCA8IDYpIHtcbiAgICAgICAgdmFsID0gdmFsWzBdK3ZhbFswXSt2YWxbMV0rdmFsWzFdK3ZhbFsyXSt2YWxbMl07XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHI6IHRvRGVjaW1hbCh2YWwuc3Vic3RyaW5nKDAsMikpLFxuICAgICAgZzogdG9EZWNpbWFsKHZhbC5zdWJzdHJpbmcoMiw0KSksXG4gICAgICBiOiB0b0RlY2ltYWwodmFsLnN1YnN0cmluZyg0LDYpKVxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBnZXRPcmlnaW4ob3B0aW9ucykge1xuICAgIHZhciBvcmlnaW4gPSBwcm9wKG9wdGlvbnMsICdvcmlnaW4nLCBPYmplY3QpO1xuICAgIG9yaWdpbi54ID0gcHJvcChvcmlnaW4sICd4JywgTnVtYmVyKTtcbiAgICBvcmlnaW4ueSA9IHByb3Aob3JpZ2luLCAneScsIE51bWJlcik7XG5cbiAgICByZXR1cm4gb3JpZ2luO1xuICB9XG5cbiAgZnVuY3Rpb24gc2V0Q2FudmFzV2luZG93U2l6ZShjYW52YXMpIHtcbiAgICBjYW52YXMud2lkdGggPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGg7XG4gICAgY2FudmFzLmhlaWdodCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQ7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRDYW52YXNSZWN0U2l6ZShjYW52YXMpIHtcbiAgICB2YXIgcmVjdCA9IGNhbnZhcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjYW52YXMud2lkdGggPSByZWN0LndpZHRoO1xuICAgIGNhbnZhcy5oZWlnaHQgPSByZWN0LmhlaWdodDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldENhbnZhcyh6SW5kZXgpIHtcbiAgICB2YXIgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG5cbiAgICBjYW52YXMuc3R5bGUucG9zaXRpb24gPSAnZml4ZWQnO1xuICAgIGNhbnZhcy5zdHlsZS50b3AgPSAnMHB4JztcbiAgICBjYW52YXMuc3R5bGUubGVmdCA9ICcwcHgnO1xuICAgIGNhbnZhcy5zdHlsZS5wb2ludGVyRXZlbnRzID0gJ25vbmUnO1xuICAgIGNhbnZhcy5zdHlsZS56SW5kZXggPSB6SW5kZXg7XG5cbiAgICByZXR1cm4gY2FudmFzO1xuICB9XG5cbiAgZnVuY3Rpb24gZWxsaXBzZShjb250ZXh0LCB4LCB5LCByYWRpdXNYLCByYWRpdXNZLCByb3RhdGlvbiwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIGFudGlDbG9ja3dpc2UpIHtcbiAgICBjb250ZXh0LnNhdmUoKTtcbiAgICBjb250ZXh0LnRyYW5zbGF0ZSh4LCB5KTtcbiAgICBjb250ZXh0LnJvdGF0ZShyb3RhdGlvbik7XG4gICAgY29udGV4dC5zY2FsZShyYWRpdXNYLCByYWRpdXNZKTtcbiAgICBjb250ZXh0LmFyYygwLCAwLCAxLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSwgYW50aUNsb2Nrd2lzZSk7XG4gICAgY29udGV4dC5yZXN0b3JlKCk7XG4gIH1cblxuICBmdW5jdGlvbiByYW5kb21QaHlzaWNzKG9wdHMpIHtcbiAgICB2YXIgcmFkQW5nbGUgPSBvcHRzLmFuZ2xlICogKE1hdGguUEkgLyAxODApO1xuICAgIHZhciByYWRTcHJlYWQgPSBvcHRzLnNwcmVhZCAqIChNYXRoLlBJIC8gMTgwKTtcblxuICAgIHJldHVybiB7XG4gICAgICB4OiBvcHRzLngsXG4gICAgICB5OiBvcHRzLnksXG4gICAgICB3b2JibGU6IE1hdGgucmFuZG9tKCkgKiAxMCxcbiAgICAgIHdvYmJsZVNwZWVkOiBNYXRoLm1pbigwLjExLCBNYXRoLnJhbmRvbSgpICogMC4xICsgMC4wNSksXG4gICAgICB2ZWxvY2l0eTogKG9wdHMuc3RhcnRWZWxvY2l0eSAqIDAuNSkgKyAoTWF0aC5yYW5kb20oKSAqIG9wdHMuc3RhcnRWZWxvY2l0eSksXG4gICAgICBhbmdsZTJEOiAtcmFkQW5nbGUgKyAoKDAuNSAqIHJhZFNwcmVhZCkgLSAoTWF0aC5yYW5kb20oKSAqIHJhZFNwcmVhZCkpLFxuICAgICAgdGlsdEFuZ2xlOiAoTWF0aC5yYW5kb20oKSAqICgwLjc1IC0gMC4yNSkgKyAwLjI1KSAqIE1hdGguUEksXG4gICAgICBjb2xvcjogb3B0cy5jb2xvcixcbiAgICAgIHNoYXBlOiBvcHRzLnNoYXBlLFxuICAgICAgdGljazogMCxcbiAgICAgIHRvdGFsVGlja3M6IG9wdHMudGlja3MsXG4gICAgICBkZWNheTogb3B0cy5kZWNheSxcbiAgICAgIGRyaWZ0OiBvcHRzLmRyaWZ0LFxuICAgICAgcmFuZG9tOiBNYXRoLnJhbmRvbSgpICsgMixcbiAgICAgIHRpbHRTaW46IDAsXG4gICAgICB0aWx0Q29zOiAwLFxuICAgICAgd29iYmxlWDogMCxcbiAgICAgIHdvYmJsZVk6IDAsXG4gICAgICBncmF2aXR5OiBvcHRzLmdyYXZpdHkgKiAzLFxuICAgICAgb3ZhbFNjYWxhcjogMC42LFxuICAgICAgc2NhbGFyOiBvcHRzLnNjYWxhclxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVGZXR0aShjb250ZXh0LCBmZXR0aSkge1xuICAgIGZldHRpLnggKz0gTWF0aC5jb3MoZmV0dGkuYW5nbGUyRCkgKiBmZXR0aS52ZWxvY2l0eSArIGZldHRpLmRyaWZ0O1xuICAgIGZldHRpLnkgKz0gTWF0aC5zaW4oZmV0dGkuYW5nbGUyRCkgKiBmZXR0aS52ZWxvY2l0eSArIGZldHRpLmdyYXZpdHk7XG4gICAgZmV0dGkud29iYmxlICs9IGZldHRpLndvYmJsZVNwZWVkO1xuICAgIGZldHRpLnZlbG9jaXR5ICo9IGZldHRpLmRlY2F5O1xuICAgIGZldHRpLnRpbHRBbmdsZSArPSAwLjE7XG4gICAgZmV0dGkudGlsdFNpbiA9IE1hdGguc2luKGZldHRpLnRpbHRBbmdsZSk7XG4gICAgZmV0dGkudGlsdENvcyA9IE1hdGguY29zKGZldHRpLnRpbHRBbmdsZSk7XG4gICAgZmV0dGkucmFuZG9tID0gTWF0aC5yYW5kb20oKSArIDI7XG4gICAgZmV0dGkud29iYmxlWCA9IGZldHRpLnggKyAoKDEwICogZmV0dGkuc2NhbGFyKSAqIE1hdGguY29zKGZldHRpLndvYmJsZSkpO1xuICAgIGZldHRpLndvYmJsZVkgPSBmZXR0aS55ICsgKCgxMCAqIGZldHRpLnNjYWxhcikgKiBNYXRoLnNpbihmZXR0aS53b2JibGUpKTtcblxuICAgIHZhciBwcm9ncmVzcyA9IChmZXR0aS50aWNrKyspIC8gZmV0dGkudG90YWxUaWNrcztcblxuICAgIHZhciB4MSA9IGZldHRpLnggKyAoZmV0dGkucmFuZG9tICogZmV0dGkudGlsdENvcyk7XG4gICAgdmFyIHkxID0gZmV0dGkueSArIChmZXR0aS5yYW5kb20gKiBmZXR0aS50aWx0U2luKTtcbiAgICB2YXIgeDIgPSBmZXR0aS53b2JibGVYICsgKGZldHRpLnJhbmRvbSAqIGZldHRpLnRpbHRDb3MpO1xuICAgIHZhciB5MiA9IGZldHRpLndvYmJsZVkgKyAoZmV0dGkucmFuZG9tICogZmV0dGkudGlsdFNpbik7XG5cbiAgICBjb250ZXh0LmZpbGxTdHlsZSA9ICdyZ2JhKCcgKyBmZXR0aS5jb2xvci5yICsgJywgJyArIGZldHRpLmNvbG9yLmcgKyAnLCAnICsgZmV0dGkuY29sb3IuYiArICcsICcgKyAoMSAtIHByb2dyZXNzKSArICcpJztcbiAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuXG4gICAgaWYgKGZldHRpLnNoYXBlID09PSAnY2lyY2xlJykge1xuICAgICAgY29udGV4dC5lbGxpcHNlID9cbiAgICAgICAgY29udGV4dC5lbGxpcHNlKGZldHRpLngsIGZldHRpLnksIE1hdGguYWJzKHgyIC0geDEpICogZmV0dGkub3ZhbFNjYWxhciwgTWF0aC5hYnMoeTIgLSB5MSkgKiBmZXR0aS5vdmFsU2NhbGFyLCBNYXRoLlBJIC8gMTAgKiBmZXR0aS53b2JibGUsIDAsIDIgKiBNYXRoLlBJKSA6XG4gICAgICAgIGVsbGlwc2UoY29udGV4dCwgZmV0dGkueCwgZmV0dGkueSwgTWF0aC5hYnMoeDIgLSB4MSkgKiBmZXR0aS5vdmFsU2NhbGFyLCBNYXRoLmFicyh5MiAtIHkxKSAqIGZldHRpLm92YWxTY2FsYXIsIE1hdGguUEkgLyAxMCAqIGZldHRpLndvYmJsZSwgMCwgMiAqIE1hdGguUEkpO1xuICAgIH0gZWxzZSBpZiAoZmV0dGkuc2hhcGUgPT09ICdzdGFyJykge1xuICAgICAgdmFyIHJvdCA9IE1hdGguUEkgLyAyICogMztcbiAgICAgIHZhciBpbm5lclJhZGl1cyA9IDQgKiBmZXR0aS5zY2FsYXI7XG4gICAgICB2YXIgb3V0ZXJSYWRpdXMgPSA4ICogZmV0dGkuc2NhbGFyO1xuICAgICAgdmFyIHggPSBmZXR0aS54O1xuICAgICAgdmFyIHkgPSBmZXR0aS55O1xuICAgICAgdmFyIHNwaWtlcyA9IDU7XG4gICAgICB2YXIgc3RlcCA9IE1hdGguUEkgLyBzcGlrZXM7XG5cbiAgICAgIHdoaWxlIChzcGlrZXMtLSkge1xuICAgICAgICB4ID0gZmV0dGkueCArIE1hdGguY29zKHJvdCkgKiBvdXRlclJhZGl1cztcbiAgICAgICAgeSA9IGZldHRpLnkgKyBNYXRoLnNpbihyb3QpICogb3V0ZXJSYWRpdXM7XG4gICAgICAgIGNvbnRleHQubGluZVRvKHgsIHkpO1xuICAgICAgICByb3QgKz0gc3RlcDtcblxuICAgICAgICB4ID0gZmV0dGkueCArIE1hdGguY29zKHJvdCkgKiBpbm5lclJhZGl1cztcbiAgICAgICAgeSA9IGZldHRpLnkgKyBNYXRoLnNpbihyb3QpICogaW5uZXJSYWRpdXM7XG4gICAgICAgIGNvbnRleHQubGluZVRvKHgsIHkpO1xuICAgICAgICByb3QgKz0gc3RlcDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29udGV4dC5tb3ZlVG8oTWF0aC5mbG9vcihmZXR0aS54KSwgTWF0aC5mbG9vcihmZXR0aS55KSk7XG4gICAgICBjb250ZXh0LmxpbmVUbyhNYXRoLmZsb29yKGZldHRpLndvYmJsZVgpLCBNYXRoLmZsb29yKHkxKSk7XG4gICAgICBjb250ZXh0LmxpbmVUbyhNYXRoLmZsb29yKHgyKSwgTWF0aC5mbG9vcih5MikpO1xuICAgICAgY29udGV4dC5saW5lVG8oTWF0aC5mbG9vcih4MSksIE1hdGguZmxvb3IoZmV0dGkud29iYmxlWSkpO1xuICAgIH1cblxuICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgY29udGV4dC5maWxsKCk7XG5cbiAgICByZXR1cm4gZmV0dGkudGljayA8IGZldHRpLnRvdGFsVGlja3M7XG4gIH1cblxuICBmdW5jdGlvbiBhbmltYXRlKGNhbnZhcywgZmV0dGlzLCByZXNpemVyLCBzaXplLCBkb25lKSB7XG4gICAgdmFyIGFuaW1hdGluZ0ZldHRpcyA9IGZldHRpcy5zbGljZSgpO1xuICAgIHZhciBjb250ZXh0ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgdmFyIGFuaW1hdGlvbkZyYW1lO1xuICAgIHZhciBkZXN0cm95O1xuXG4gICAgdmFyIHByb20gPSBwcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgICBmdW5jdGlvbiBvbkRvbmUoKSB7XG4gICAgICAgIGFuaW1hdGlvbkZyYW1lID0gZGVzdHJveSA9IG51bGw7XG5cbiAgICAgICAgY29udGV4dC5jbGVhclJlY3QoMCwgMCwgc2l6ZS53aWR0aCwgc2l6ZS5oZWlnaHQpO1xuXG4gICAgICAgIGRvbmUoKTtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiB1cGRhdGUoKSB7XG4gICAgICAgIGlmIChpc1dvcmtlciAmJiAhKHNpemUud2lkdGggPT09IHdvcmtlclNpemUud2lkdGggJiYgc2l6ZS5oZWlnaHQgPT09IHdvcmtlclNpemUuaGVpZ2h0KSkge1xuICAgICAgICAgIHNpemUud2lkdGggPSBjYW52YXMud2lkdGggPSB3b3JrZXJTaXplLndpZHRoO1xuICAgICAgICAgIHNpemUuaGVpZ2h0ID0gY2FudmFzLmhlaWdodCA9IHdvcmtlclNpemUuaGVpZ2h0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFzaXplLndpZHRoICYmICFzaXplLmhlaWdodCkge1xuICAgICAgICAgIHJlc2l6ZXIoY2FudmFzKTtcbiAgICAgICAgICBzaXplLndpZHRoID0gY2FudmFzLndpZHRoO1xuICAgICAgICAgIHNpemUuaGVpZ2h0ID0gY2FudmFzLmhlaWdodDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRleHQuY2xlYXJSZWN0KDAsIDAsIHNpemUud2lkdGgsIHNpemUuaGVpZ2h0KTtcblxuICAgICAgICBhbmltYXRpbmdGZXR0aXMgPSBhbmltYXRpbmdGZXR0aXMuZmlsdGVyKGZ1bmN0aW9uIChmZXR0aSkge1xuICAgICAgICAgIHJldHVybiB1cGRhdGVGZXR0aShjb250ZXh0LCBmZXR0aSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChhbmltYXRpbmdGZXR0aXMubGVuZ3RoKSB7XG4gICAgICAgICAgYW5pbWF0aW9uRnJhbWUgPSByYWYuZnJhbWUodXBkYXRlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvbkRvbmUoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBhbmltYXRpb25GcmFtZSA9IHJhZi5mcmFtZSh1cGRhdGUpO1xuICAgICAgZGVzdHJveSA9IG9uRG9uZTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBhZGRGZXR0aXM6IGZ1bmN0aW9uIChmZXR0aXMpIHtcbiAgICAgICAgYW5pbWF0aW5nRmV0dGlzID0gYW5pbWF0aW5nRmV0dGlzLmNvbmNhdChmZXR0aXMpO1xuXG4gICAgICAgIHJldHVybiBwcm9tO1xuICAgICAgfSxcbiAgICAgIGNhbnZhczogY2FudmFzLFxuICAgICAgcHJvbWlzZTogcHJvbSxcbiAgICAgIHJlc2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChhbmltYXRpb25GcmFtZSkge1xuICAgICAgICAgIHJhZi5jYW5jZWwoYW5pbWF0aW9uRnJhbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRlc3Ryb3kpIHtcbiAgICAgICAgICBkZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gY29uZmV0dGlDYW5ub24oY2FudmFzLCBnbG9iYWxPcHRzKSB7XG4gICAgdmFyIGlzTGliQ2FudmFzID0gIWNhbnZhcztcbiAgICB2YXIgYWxsb3dSZXNpemUgPSAhIXByb3AoZ2xvYmFsT3B0cyB8fCB7fSwgJ3Jlc2l6ZScpO1xuICAgIHZhciBnbG9iYWxEaXNhYmxlRm9yUmVkdWNlZE1vdGlvbiA9IHByb3AoZ2xvYmFsT3B0cywgJ2Rpc2FibGVGb3JSZWR1Y2VkTW90aW9uJywgQm9vbGVhbik7XG4gICAgdmFyIHNob3VsZFVzZVdvcmtlciA9IGNhblVzZVdvcmtlciAmJiAhIXByb3AoZ2xvYmFsT3B0cyB8fCB7fSwgJ3VzZVdvcmtlcicpO1xuICAgIHZhciB3b3JrZXIgPSBzaG91bGRVc2VXb3JrZXIgPyBnZXRXb3JrZXIoKSA6IG51bGw7XG4gICAgdmFyIHJlc2l6ZXIgPSBpc0xpYkNhbnZhcyA/IHNldENhbnZhc1dpbmRvd1NpemUgOiBzZXRDYW52YXNSZWN0U2l6ZTtcbiAgICB2YXIgaW5pdGlhbGl6ZWQgPSAoY2FudmFzICYmIHdvcmtlcikgPyAhIWNhbnZhcy5fX2NvbmZldHRpX2luaXRpYWxpemVkIDogZmFsc2U7XG4gICAgdmFyIHByZWZlckxlc3NNb3Rpb24gPSB0eXBlb2YgbWF0Y2hNZWRpYSA9PT0gJ2Z1bmN0aW9uJyAmJiBtYXRjaE1lZGlhKCcocHJlZmVycy1yZWR1Y2VkLW1vdGlvbiknKS5tYXRjaGVzO1xuICAgIHZhciBhbmltYXRpb25PYmo7XG5cbiAgICBmdW5jdGlvbiBmaXJlTG9jYWwob3B0aW9ucywgc2l6ZSwgZG9uZSkge1xuICAgICAgdmFyIHBhcnRpY2xlQ291bnQgPSBwcm9wKG9wdGlvbnMsICdwYXJ0aWNsZUNvdW50Jywgb25seVBvc2l0aXZlSW50KTtcbiAgICAgIHZhciBhbmdsZSA9IHByb3Aob3B0aW9ucywgJ2FuZ2xlJywgTnVtYmVyKTtcbiAgICAgIHZhciBzcHJlYWQgPSBwcm9wKG9wdGlvbnMsICdzcHJlYWQnLCBOdW1iZXIpO1xuICAgICAgdmFyIHN0YXJ0VmVsb2NpdHkgPSBwcm9wKG9wdGlvbnMsICdzdGFydFZlbG9jaXR5JywgTnVtYmVyKTtcbiAgICAgIHZhciBkZWNheSA9IHByb3Aob3B0aW9ucywgJ2RlY2F5JywgTnVtYmVyKTtcbiAgICAgIHZhciBncmF2aXR5ID0gcHJvcChvcHRpb25zLCAnZ3Jhdml0eScsIE51bWJlcik7XG4gICAgICB2YXIgZHJpZnQgPSBwcm9wKG9wdGlvbnMsICdkcmlmdCcsIE51bWJlcik7XG4gICAgICB2YXIgY29sb3JzID0gcHJvcChvcHRpb25zLCAnY29sb3JzJywgY29sb3JzVG9SZ2IpO1xuICAgICAgdmFyIHRpY2tzID0gcHJvcChvcHRpb25zLCAndGlja3MnLCBOdW1iZXIpO1xuICAgICAgdmFyIHNoYXBlcyA9IHByb3Aob3B0aW9ucywgJ3NoYXBlcycpO1xuICAgICAgdmFyIHNjYWxhciA9IHByb3Aob3B0aW9ucywgJ3NjYWxhcicpO1xuICAgICAgdmFyIG9yaWdpbiA9IGdldE9yaWdpbihvcHRpb25zKTtcblxuICAgICAgdmFyIHRlbXAgPSBwYXJ0aWNsZUNvdW50O1xuICAgICAgdmFyIGZldHRpcyA9IFtdO1xuXG4gICAgICB2YXIgc3RhcnRYID0gY2FudmFzLndpZHRoICogb3JpZ2luLng7XG4gICAgICB2YXIgc3RhcnRZID0gY2FudmFzLmhlaWdodCAqIG9yaWdpbi55O1xuXG4gICAgICB3aGlsZSAodGVtcC0tKSB7XG4gICAgICAgIGZldHRpcy5wdXNoKFxuICAgICAgICAgIHJhbmRvbVBoeXNpY3Moe1xuICAgICAgICAgICAgeDogc3RhcnRYLFxuICAgICAgICAgICAgeTogc3RhcnRZLFxuICAgICAgICAgICAgYW5nbGU6IGFuZ2xlLFxuICAgICAgICAgICAgc3ByZWFkOiBzcHJlYWQsXG4gICAgICAgICAgICBzdGFydFZlbG9jaXR5OiBzdGFydFZlbG9jaXR5LFxuICAgICAgICAgICAgY29sb3I6IGNvbG9yc1t0ZW1wICUgY29sb3JzLmxlbmd0aF0sXG4gICAgICAgICAgICBzaGFwZTogc2hhcGVzW3JhbmRvbUludCgwLCBzaGFwZXMubGVuZ3RoKV0sXG4gICAgICAgICAgICB0aWNrczogdGlja3MsXG4gICAgICAgICAgICBkZWNheTogZGVjYXksXG4gICAgICAgICAgICBncmF2aXR5OiBncmF2aXR5LFxuICAgICAgICAgICAgZHJpZnQ6IGRyaWZ0LFxuICAgICAgICAgICAgc2NhbGFyOiBzY2FsYXJcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBpZiB3ZSBoYXZlIGEgcHJldmlvdXMgY2FudmFzIGFscmVhZHkgYW5pbWF0aW5nLFxuICAgICAgLy8gYWRkIHRvIGl0XG4gICAgICBpZiAoYW5pbWF0aW9uT2JqKSB7XG4gICAgICAgIHJldHVybiBhbmltYXRpb25PYmouYWRkRmV0dGlzKGZldHRpcyk7XG4gICAgICB9XG5cbiAgICAgIGFuaW1hdGlvbk9iaiA9IGFuaW1hdGUoY2FudmFzLCBmZXR0aXMsIHJlc2l6ZXIsIHNpemUgLCBkb25lKTtcblxuICAgICAgcmV0dXJuIGFuaW1hdGlvbk9iai5wcm9taXNlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZpcmUob3B0aW9ucykge1xuICAgICAgdmFyIGRpc2FibGVGb3JSZWR1Y2VkTW90aW9uID0gZ2xvYmFsRGlzYWJsZUZvclJlZHVjZWRNb3Rpb24gfHwgcHJvcChvcHRpb25zLCAnZGlzYWJsZUZvclJlZHVjZWRNb3Rpb24nLCBCb29sZWFuKTtcbiAgICAgIHZhciB6SW5kZXggPSBwcm9wKG9wdGlvbnMsICd6SW5kZXgnLCBOdW1iZXIpO1xuXG4gICAgICBpZiAoZGlzYWJsZUZvclJlZHVjZWRNb3Rpb24gJiYgcHJlZmVyTGVzc01vdGlvbikge1xuICAgICAgICByZXR1cm4gcHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0xpYkNhbnZhcyAmJiBhbmltYXRpb25PYmopIHtcbiAgICAgICAgLy8gdXNlIGV4aXN0aW5nIGNhbnZhcyBmcm9tIGluLXByb2dyZXNzIGFuaW1hdGlvblxuICAgICAgICBjYW52YXMgPSBhbmltYXRpb25PYmouY2FudmFzO1xuICAgICAgfSBlbHNlIGlmIChpc0xpYkNhbnZhcyAmJiAhY2FudmFzKSB7XG4gICAgICAgIC8vIGNyZWF0ZSBhbmQgaW5pdGlhbGl6ZSBhIG5ldyBjYW52YXNcbiAgICAgICAgY2FudmFzID0gZ2V0Q2FudmFzKHpJbmRleCk7XG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoY2FudmFzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFsbG93UmVzaXplICYmICFpbml0aWFsaXplZCkge1xuICAgICAgICAvLyBpbml0aWFsaXplIHRoZSBzaXplIG9mIGEgdXNlci1zdXBwbGllZCBjYW52YXNcbiAgICAgICAgcmVzaXplcihjYW52YXMpO1xuICAgICAgfVxuXG4gICAgICB2YXIgc2l6ZSA9IHtcbiAgICAgICAgd2lkdGg6IGNhbnZhcy53aWR0aCxcbiAgICAgICAgaGVpZ2h0OiBjYW52YXMuaGVpZ2h0XG4gICAgICB9O1xuXG4gICAgICBpZiAod29ya2VyICYmICFpbml0aWFsaXplZCkge1xuICAgICAgICB3b3JrZXIuaW5pdChjYW52YXMpO1xuICAgICAgfVxuXG4gICAgICBpbml0aWFsaXplZCA9IHRydWU7XG5cbiAgICAgIGlmICh3b3JrZXIpIHtcbiAgICAgICAgY2FudmFzLl9fY29uZmV0dGlfaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBvblJlc2l6ZSgpIHtcbiAgICAgICAgaWYgKHdvcmtlcikge1xuICAgICAgICAgIC8vIFRPRE8gdGhpcyByZWFsbHkgc2hvdWxkbid0IGJlIGltbWVkaWF0ZSwgYmVjYXVzZSBpdCBpcyBleHBlbnNpdmVcbiAgICAgICAgICB2YXIgb2JqID0ge1xuICAgICAgICAgICAgZ2V0Qm91bmRpbmdDbGllbnRSZWN0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIGlmICghaXNMaWJDYW52YXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY2FudmFzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIHJlc2l6ZXIob2JqKTtcblxuICAgICAgICAgIHdvcmtlci5wb3N0TWVzc2FnZSh7XG4gICAgICAgICAgICByZXNpemU6IHtcbiAgICAgICAgICAgICAgd2lkdGg6IG9iai53aWR0aCxcbiAgICAgICAgICAgICAgaGVpZ2h0OiBvYmouaGVpZ2h0XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZG9uJ3QgYWN0dWFsbHkgcXVlcnkgdGhlIHNpemUgaGVyZSwgc2luY2UgdGhpc1xuICAgICAgICAvLyBjYW4gZXhlY3V0ZSBmcmVxdWVudGx5IGFuZCByYXBpZGx5XG4gICAgICAgIHNpemUud2lkdGggPSBzaXplLmhlaWdodCA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGRvbmUoKSB7XG4gICAgICAgIGFuaW1hdGlvbk9iaiA9IG51bGw7XG5cbiAgICAgICAgaWYgKGFsbG93UmVzaXplKSB7XG4gICAgICAgICAgZ2xvYmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIG9uUmVzaXplKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0xpYkNhbnZhcyAmJiBjYW52YXMpIHtcbiAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGNhbnZhcyk7XG4gICAgICAgICAgY2FudmFzID0gbnVsbDtcbiAgICAgICAgICBpbml0aWFsaXplZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChhbGxvd1Jlc2l6ZSkge1xuICAgICAgICBnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgb25SZXNpemUsIGZhbHNlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHdvcmtlcikge1xuICAgICAgICByZXR1cm4gd29ya2VyLmZpcmUob3B0aW9ucywgc2l6ZSwgZG9uZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmaXJlTG9jYWwob3B0aW9ucywgc2l6ZSwgZG9uZSk7XG4gICAgfVxuXG4gICAgZmlyZS5yZXNldCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmICh3b3JrZXIpIHtcbiAgICAgICAgd29ya2VyLnJlc2V0KCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChhbmltYXRpb25PYmopIHtcbiAgICAgICAgYW5pbWF0aW9uT2JqLnJlc2V0KCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBmaXJlO1xuICB9XG5cbiAgLy8gTWFrZSBkZWZhdWx0IGV4cG9ydCBsYXp5IHRvIGRlZmVyIHdvcmtlciBjcmVhdGlvbiB1bnRpbCBjYWxsZWQuXG4gIHZhciBkZWZhdWx0RmlyZTtcbiAgZnVuY3Rpb24gZ2V0RGVmYXVsdEZpcmUoKSB7XG4gICAgaWYgKCFkZWZhdWx0RmlyZSkge1xuICAgICAgZGVmYXVsdEZpcmUgPSBjb25mZXR0aUNhbm5vbihudWxsLCB7IHVzZVdvcmtlcjogdHJ1ZSwgcmVzaXplOiB0cnVlIH0pO1xuICAgIH1cbiAgICByZXR1cm4gZGVmYXVsdEZpcmU7XG4gIH1cblxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBnZXREZWZhdWx0RmlyZSgpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH07XG4gIG1vZHVsZS5leHBvcnRzLnJlc2V0ID0gZnVuY3Rpb24oKSB7XG4gICAgZ2V0RGVmYXVsdEZpcmUoKS5yZXNldCgpO1xuICB9O1xuICBtb2R1bGUuZXhwb3J0cy5jcmVhdGUgPSBjb25mZXR0aUNhbm5vbjtcbn0oKGZ1bmN0aW9uICgpIHtcbiAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuIHdpbmRvdztcbiAgfVxuXG4gIGlmICh0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gc2VsZjtcbiAgfVxuXG4gIHJldHVybiB0aGlzIHx8IHt9O1xufSkoKSwgbW9kdWxlLCBmYWxzZSkpO1xuXG4vLyBlbmQgc291cmNlIGNvbnRlbnRcblxuZXhwb3J0IGRlZmF1bHQgbW9kdWxlLmV4cG9ydHM7XG5leHBvcnQgdmFyIGNyZWF0ZSA9IG1vZHVsZS5leHBvcnRzLmNyZWF0ZTtcbiIsICJpbXBvcnQgeyBTb2NrZXQgfSBmcm9tIFwicGhvZW5peFwiO1xuaW1wb3J0IGNvbmZldHRpIGZyb20gXCJjYW52YXMtY29uZmV0dGlcIjtcblxuZnVuY3Rpb24gY29ubmVjdCgpIHtcbiAgaWYgKCF3aW5kb3cudXNlclRva2VuLmxlbmd0aCkge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCBzb2NrZXQgPSBuZXcgU29ja2V0KFwiL3NvY2tldFwiLCB7IHBhcmFtczogeyB0b2tlbjogd2luZG93LnVzZXJUb2tlbiB9IH0pO1xuXG4gIHNvY2tldC5jb25uZWN0KCk7XG5cbiAgY29uc3QgY2hhbm5lbCA9IHNvY2tldC5jaGFubmVsKFwibm90aWZpY2F0aW9uczoqXCIsIHt9KTtcblxuICBjaGFubmVsXG4gICAgLmpvaW4oKVxuICAgIC5yZWNlaXZlKFwiZXJyb3JcIiwgKHJlc3ApID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKFwiVW5hYmxlIHRvIGpvaW4gbm90aWZpY2F0aW9ucyBjaGFubmVsXCIsIHJlc3ApO1xuICAgIH0pXG4gICAgLnJlY2VpdmUoXCJva1wiLCAoKSA9PiBjb25zb2xlLmxvZyhcIkNvbm5lY3RlZFwiKSk7XG5cbiAgY2hhbm5lbC5vbihcImxpa2VcIiwgc2hvd05vdGlmaWNhdGlvbik7XG4gIGNoYW5uZWwub24oXCJlcnJvclwiLCB1cGRhdGVFcnJvcik7XG4gIGNoYW5uZWwub24oXCJwbGF5X3N0YXRlXCIsIHVwZGF0ZVBsYXlzdGF0ZSk7XG59XG5cbmNvbnN0IGNvbmZldHRpcyA9IHtcbiAgbGlrZTogY29uZmV0dGksXG4gIHN1cGVyX2xpa2U6IGJpZ0NvbmZldHRpLFxuICBidXJuOiAoKSA9PiB7fSxcbn07XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxuICBcInBoeDpwb2ludC1naXZlblwiLFxuICAoeyBkZXRhaWw6IHsgcmVhc29uIH0gfSkgPT4ge1xuICAgIC8vIFBvaW50IGdpdmVuIEJZIHRoaXMgc2Vzc2lvblxuICAgIGNvbmZldHRpc1tyZWFzb25dKCk7XG4gIH0sXG4gIGZhbHNlLFxuKTtcblxuZnVuY3Rpb24gc2hvd05vdGlmaWNhdGlvbih7XG4gIHRyYWNrOiB7IGFydGlzdCwgbmFtZSwgaW1nIH0sXG4gIGZyb206IHsgZmlyc3RfbmFtZSB9LFxuICByZWFzb24sXG59KSB7XG4gIGNvbnN0IHRpdGxlcyA9IHtcbiAgICBsaWtlOiBgXHVEODNEXHVERTBEICR7Zmlyc3RfbmFtZX0gbGlrZWQgJHtuYW1lfWAsXG4gICAgc3VwZXJfbGlrZTogYFx1RDgzRVx1REQyOSAke2ZpcnN0X25hbWV9IFNVUEVSTElLRUQgJHtuYW1lfSFgLFxuICAgIGJ1cm46IGBcdUQ4M0RcdUREMjUgT2ggZGVhciAke25hbWV9YCxcbiAgfTtcbiAgY29uc3QgbXNnVGl0bGUgPSB0aXRsZXNbcmVhc29uXTtcbiAgLy8gUG9pbnQgcmVjZWl2ZWRcbiAgY29uZmV0dGlzW3JlYXNvbl0oKTtcbiAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICBpbWFnZTogaW1nLFxuICAgIGljb246IGltZyxcbiAgICBib2R5OiBgJHtuYW1lfSBcdTIwMTMgJHthcnRpc3R9YCxcbiAgfTtcbiAgaWYgKCEoXCJOb3RpZmljYXRpb25cIiBpbiB3aW5kb3cpKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChOb3RpZmljYXRpb24ucGVybWlzc2lvbiA9PT0gXCJncmFudGVkXCIpIHtcbiAgICBuZXcgTm90aWZpY2F0aW9uKG1zZ1RpdGxlLCBvcHRpb25zKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXF1ZXN0Tm90aWZpY2F0aW9uUGVybWlzc2lvbigpIHtcbiAgaWYgKCEoXCJOb3RpZmljYXRpb25cIiBpbiB3aW5kb3cpKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIE5vdGlmaWNhdGlvbi5yZXF1ZXN0UGVybWlzc2lvbigpO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVFcnJvcih7IGVycm9yX2NvZGUgfSkge1xuICBpZiAoZXJyb3JfY29kZSkge1xuICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZChcImVycm9yXCIpO1xuICB9IGVsc2Uge1xuICAgIGNvbnNvbGUubG9nKFwiUmVtb3ZlIGVycm9yXCIsIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0KTtcbiAgICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoXCJlcnJvclwiKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB1cGRhdGVQbGF5c3RhdGUoeyBzdGF0ZSB9KSB7XG4gIC8vIFVwZGF0ZSB0aGlzIGZsYWcgZm9yIHRoZSBmYXZpY29uIHdvcmtlciB0byBwaWNrIHVwXG4gIHdpbmRvdy5wbGF5U3RhdGUgPSBzdGF0ZTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKCkge1xuICByZXF1ZXN0Tm90aWZpY2F0aW9uUGVybWlzc2lvbigpO1xuICBjb25uZWN0KCk7XG59XG5cbnZhciBkdXJhdGlvbiA9IDEwICogMTAwMDtcbnZhciBlbmQgPSBEYXRlLm5vdygpICsgZHVyYXRpb247XG5cbmZ1bmN0aW9uIGJpZ0NvbmZldHRpKCkge1xuICAvLyBsYXVuY2ggYSBmZXcgY29uZmV0dGkgZnJvbSB0aGUgbGVmdCBlZGdlXG4gIGNvbmZldHRpKHtcbiAgICBwYXJ0aWNsZUNvdW50OiA3LFxuICAgIGFuZ2xlOiA2MCxcbiAgICBzcHJlYWQ6IDU1LFxuICAgIG9yaWdpbjogeyB4OiAwIH0sXG4gIH0pO1xuICAvLyBhbmQgbGF1bmNoIGEgZmV3IGZyb20gdGhlIHJpZ2h0IGVkZ2VcbiAgY29uZmV0dGkoe1xuICAgIHBhcnRpY2xlQ291bnQ6IDcsXG4gICAgYW5nbGU6IDEyMCxcbiAgICBzcHJlYWQ6IDU1LFxuICAgIG9yaWdpbjogeyB4OiAxIH0sXG4gIH0pO1xuXG4gIC8vIGtlZXAgZ29pbmcgdW50aWwgd2UgYXJlIG91dCBvZiB0aW1lXG4gIGlmIChEYXRlLm5vdygpIDwgZW5kKSB7XG4gICAgc2V0VGltZW91dChiaWdDb25mZXR0aSwgMTApO1xuICB9XG59XG4iLCAiLy8gSW1wb3J0IGRlcGVuZGVuY2llc1xuLy9cbmltcG9ydCBcInBob2VuaXhfaHRtbFwiO1xuaW1wb3J0IHsgTGl2ZVNvY2tldCB9IGZyb20gXCJwaG9lbml4X2xpdmVfdmlld1wiO1xuaW1wb3J0IHsgU29ja2V0IH0gZnJvbSBcInBob2VuaXhcIjtcblxuaW1wb3J0IGluaXRHaG9zdCBmcm9tIFwiLi9naG9zdFwiO1xuaW1wb3J0IG5vdGlmaWNhdGlvbnMgZnJvbSBcIi4vbm90aWZpY2F0aW9uc1wiO1xuXG5jb25zdCBjc3JmVG9rZW4gPSBkb2N1bWVudFxuICAucXVlcnlTZWxlY3RvcihcIm1ldGFbbmFtZT0nY3NyZi10b2tlbiddXCIpXG4gIC5nZXRBdHRyaWJ1dGUoXCJjb250ZW50XCIpO1xuY29uc3QgbGl2ZVNvY2tldCA9IG5ldyBMaXZlU29ja2V0KFwiL2xpdmVcIiwgU29ja2V0LCB7XG4gIHBhcmFtczogeyBfY3NyZl90b2tlbjogY3NyZlRva2VuIH0sXG59KTtcbmxpdmVTb2NrZXQuY29ubmVjdCgpO1xuXG4vLyBMb2FkIHRoZSBnaG9zdCB1cCBhZnRlciBsaXZlIHZpZXcgY29ubmVjdHNcbmNvbnN0IHNvY2tldCA9IGxpdmVTb2NrZXQuZ2V0U29ja2V0KCk7XG5zb2NrZXQub25PcGVuKCgpID0+IHtcbiAgc2V0VGltZW91dChpbml0R2hvc3QsIDEwMDApO1xufSk7XG5cbmNvbnN0IGlzVG9kYXkgPSAobW9udGgsIGRheSkgPT4ge1xuICBjb25zdCB0b2RheSA9IG5ldyBEYXRlKClcbiAgcmV0dXJuIGRheSA9PSB0b2RheS5nZXREYXRlKCkgJiYgbW9udGggPT0gdG9kYXkuZ2V0TW9udGgoKSArIDFcbn1cblxuY29uc3QgUEFERFkgPSBbMywgMThdXG5cbmlmIChpc1RvZGF5KC4uLlBBRERZKSkge1xuICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiYm9keVwiKS5jbGFzc0xpc3QuYWRkKFwicGFkZHlcIik7XG59XG5cbmNvbnN0IHNlYXJjaElucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzZWFyY2hcIik7XG5cbmlmIChzZWFyY2hJbnB1dCkge1xuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICBcImxvYWRcIixcbiAgICAoX2V2dCkgPT4ge1xuICAgICAgc2VhcmNoSW5wdXQuZm9jdXMoKTtcbiAgICB9LFxuICAgIGZhbHNlLFxuICApO1xuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICBcImtleXVwXCIsXG4gICAgKGV2dCkgPT4ge1xuICAgICAgaWYgKGV2dC5rZXkgPT09IFwiZlwiKSB7XG4gICAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBzZWFyY2hJbnB1dC5mb2N1cygpO1xuICAgICAgfVxuICAgIH0sXG4gICAgZmFsc2UsXG4gICk7XG59XG5cbm5vdGlmaWNhdGlvbnMoKTtcbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUVBLEVBQUMsWUFBVztBQUNWLFFBQUksZ0JBQWdCO0FBRXBCLGdDQUE0QjtBQUMxQixVQUFJLE9BQU8sT0FBTyxnQkFBZ0I7QUFBWSxlQUFPLE9BQU87QUFFNUQsNEJBQXFCLE9BQU8sUUFBUTtBQUNsQyxpQkFBUyxVQUFVLEVBQUMsU0FBUyxPQUFPLFlBQVksT0FBTyxRQUFRO0FBQy9ELFlBQUksTUFBTSxTQUFTLFlBQVk7QUFDL0IsWUFBSSxnQkFBZ0IsT0FBTyxPQUFPLFNBQVMsT0FBTyxZQUFZLE9BQU87QUFDckUsZUFBTztBQUFBO0FBRVQsbUJBQVksWUFBWSxPQUFPLE1BQU07QUFDckMsYUFBTztBQUFBO0FBR1QsOEJBQTBCLE1BQU0sT0FBTztBQUNyQyxVQUFJLFFBQVEsU0FBUyxjQUFjO0FBQ25DLFlBQU0sT0FBTztBQUNiLFlBQU0sT0FBTztBQUNiLFlBQU0sUUFBUTtBQUNkLGFBQU87QUFBQTtBQUdULHlCQUFxQixTQUFTLG1CQUFtQjtBQUMvQyxVQUFJLEtBQUssUUFBUSxhQUFhLFlBQzFCLFNBQVMsaUJBQWlCLFdBQVcsUUFBUSxhQUFhLGlCQUMxRCxPQUFPLGlCQUFpQixlQUFlLFFBQVEsYUFBYSxlQUM1RCxPQUFPLFNB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
+//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vZGVwcy9waG9lbml4X2h0bWwvcHJpdi9zdGF0aWMvcGhvZW5peF9odG1sLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L2NvbnN0YW50cy5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy9lbnRyeV91cGxvYWRlci5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy91dGlscy5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy9icm93c2VyLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L2RvbS5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy91cGxvYWRfZW50cnkuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvanMvcGhvZW5peF9saXZlX3ZpZXcvbGl2ZV91cGxvYWRlci5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy9hcmlhLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L2hvb2tzLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L2VsZW1lbnRfcmVmLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L2RvbV9wb3N0X21vcnBoX3Jlc3RvcmVyLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvbm9kZV9tb2R1bGVzL21vcnBoZG9tL2Rpc3QvbW9ycGhkb20tZXNtLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L2RvbV9wYXRjaC5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy9yZW5kZXJlZC5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy9qcy5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy9qc19jb21tYW5kcy50cyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy92aWV3X2hvb2sudHMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvanMvcGhvZW5peF9saXZlX3ZpZXcvdmlldy5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy9saXZlX3NvY2tldC5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy9pbmRleC50cyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXgvYXNzZXRzL2pzL3Bob2VuaXgvdXRpbHMuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4L2Fzc2V0cy9qcy9waG9lbml4L2NvbnN0YW50cy5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXgvYXNzZXRzL2pzL3Bob2VuaXgvcHVzaC5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXgvYXNzZXRzL2pzL3Bob2VuaXgvdGltZXIuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4L2Fzc2V0cy9qcy9waG9lbml4L2NoYW5uZWwuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4L2Fzc2V0cy9qcy9waG9lbml4L2FqYXguanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4L2Fzc2V0cy9qcy9waG9lbml4L2xvbmdwb2xsLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peC9hc3NldHMvanMvcGhvZW5peC9wcmVzZW5jZS5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXgvYXNzZXRzL2pzL3Bob2VuaXgvc2VyaWFsaXplci5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXgvYXNzZXRzL2pzL3Bob2VuaXgvc29ja2V0LmpzIiwgIi4uLy4uLy4uL2Fzc2V0cy9qcy9naG9zdC5qcyIsICIuLi8uLi8uLi9hc3NldHMvbm9kZV9tb2R1bGVzL2NhbnZhcy1jb25mZXR0aS9kaXN0L2NvbmZldHRpLm1vZHVsZS5tanMiLCAiLi4vLi4vLi4vYXNzZXRzL2pzL25vdGlmaWNhdGlvbnMuanMiLCAiLi4vLi4vLi4vYXNzZXRzL2pzL2FwcC5qcyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiXCJ1c2Ugc3RyaWN0XCI7XG5cbihmdW5jdGlvbigpIHtcbiAgdmFyIFBvbHlmaWxsRXZlbnQgPSBldmVudENvbnN0cnVjdG9yKCk7XG5cbiAgZnVuY3Rpb24gZXZlbnRDb25zdHJ1Y3RvcigpIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdy5DdXN0b21FdmVudCA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gd2luZG93LkN1c3RvbUV2ZW50O1xuICAgIC8vIElFPD05IFN1cHBvcnRcbiAgICBmdW5jdGlvbiBDdXN0b21FdmVudChldmVudCwgcGFyYW1zKSB7XG4gICAgICBwYXJhbXMgPSBwYXJhbXMgfHwge2J1YmJsZXM6IGZhbHNlLCBjYW5jZWxhYmxlOiBmYWxzZSwgZGV0YWlsOiB1bmRlZmluZWR9O1xuICAgICAgdmFyIGV2dCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdDdXN0b21FdmVudCcpO1xuICAgICAgZXZ0LmluaXRDdXN0b21FdmVudChldmVudCwgcGFyYW1zLmJ1YmJsZXMsIHBhcmFtcy5jYW5jZWxhYmxlLCBwYXJhbXMuZGV0YWlsKTtcbiAgICAgIHJldHVybiBldnQ7XG4gICAgfVxuICAgIEN1c3RvbUV2ZW50LnByb3RvdHlwZSA9IHdpbmRvdy5FdmVudC5wcm90b3R5cGU7XG4gICAgcmV0dXJuIEN1c3RvbUV2ZW50O1xuICB9XG5cbiAgZnVuY3Rpb24gYnVpbGRIaWRkZW5JbnB1dChuYW1lLCB2YWx1ZSkge1xuICAgIHZhciBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbnB1dFwiKTtcbiAgICBpbnB1dC50eXBlID0gXCJoaWRkZW5cIjtcbiAgICBpbnB1dC5uYW1lID0gbmFtZTtcbiAgICBpbnB1dC52YWx1ZSA9IHZhbHVlO1xuICAgIHJldHVybiBpbnB1dDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZUNsaWNrKGVsZW1lbnQsIHRhcmdldE1vZGlmaWVyS2V5KSB7XG4gICAgdmFyIHRvID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJkYXRhLXRvXCIpLFxuICAgICAgICBtZXRob2QgPSBidWlsZEhpZGRlbklucHV0KFwiX21ldGhvZFwiLCBlbGVtZW50LmdldEF0dHJpYnV0ZShcImRhdGEtbWV0aG9kXCIpKSxcbiAgICAgICAgY3NyZiA9IGJ1aWxkSGlkZGVuSW5wdXQoXCJfY3NyZl90b2tlblwiLCBlbGVtZW50LmdldEF0dHJpYnV0ZShcImRhdGEtY3NyZlwiKSksXG4gICAgICAgIGZvcm0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZm9ybVwiKSxcbiAgICAgICAgc3VibWl0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImlucHV0XCIpLFxuICAgICAgICB0YXJnZXQgPSBlbGVtZW50LmdldEF0dHJpYnV0ZShcInRhcmdldFwiKTtcblxuICAgIGZvcm0ubWV0aG9kID0gKGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGF0YS1tZXRob2RcIikgPT09IFwiZ2V0XCIpID8gXCJnZXRcIiA6IFwicG9zdFwiO1xuICAgIGZvcm0uYWN0aW9uID0gdG87XG4gICAgZm9ybS5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XG5cbiAgICBpZiAodGFyZ2V0KSBmb3JtLnRhcmdldCA9IHRhcmdldDtcbiAgICBlbHNlIGlmICh0YXJnZXRNb2RpZmllcktleSkgZm9ybS50YXJnZXQgPSBcIl9ibGFua1wiO1xuXG4gICAgZm9ybS5hcHBlbmRDaGlsZChjc3JmKTtcbiAgICBmb3JtLmFwcGVuZENoaWxkKG1ldGhvZCk7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChmb3JtKTtcblxuICAgIC8vIEluc2VydCBhIGJ1dHRvbiBhbmQgY2xpY2sgaXQgaW5zdGVhZCBvZiB1c2luZyBgZm9ybS5zdWJtaXRgXG4gICAgLy8gYmVjYXVzZSB0aGUgYHN1Ym1pdGAgZnVuY3Rpb24gZG9lcyBub3QgZW1pdCBhIGBzdWJtaXRgIGV2ZW50LlxuICAgIHN1Ym1pdC50eXBlID0gXCJzdWJtaXRcIjtcbiAgICBmb3JtLmFwcGVuZENoaWxkKHN1Ym1pdCk7XG4gICAgc3VibWl0LmNsaWNrKCk7XG4gIH1cblxuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgZWxlbWVudCA9IGUudGFyZ2V0O1xuICAgIGlmIChlLmRlZmF1bHRQcmV2ZW50ZWQpIHJldHVybjtcblxuICAgIHdoaWxlIChlbGVtZW50ICYmIGVsZW1lbnQuZ2V0QXR0cmlidXRlKSB7XG4gICAgICB2YXIgcGhvZW5peExpbmtFdmVudCA9IG5ldyBQb2x5ZmlsbEV2ZW50KCdwaG9lbml4LmxpbmsuY2xpY2snLCB7XG4gICAgICAgIFwiYnViYmxlc1wiOiB0cnVlLCBcImNhbmNlbGFibGVcIjogdHJ1ZVxuICAgICAgfSk7XG5cbiAgICAgIGlmICghZWxlbWVudC5kaXNwYXRjaEV2ZW50KHBob2VuaXhMaW5rRXZlbnQpKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJkYXRhLW1ldGhvZFwiKSkge1xuICAgICAgICBoYW5kbGVDbGljayhlbGVtZW50LCBlLm1ldGFLZXkgfHwgZS5zaGlmdEtleSk7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWxlbWVudCA9IGVsZW1lbnQucGFyZW50Tm9kZTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIGZhbHNlKTtcblxuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncGhvZW5peC5saW5rLmNsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICB2YXIgbWVzc2FnZSA9IGUudGFyZ2V0LmdldEF0dHJpYnV0ZShcImRhdGEtY29uZmlybVwiKTtcbiAgICBpZihtZXNzYWdlICYmICF3aW5kb3cuY29uZmlybShtZXNzYWdlKSkge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfSwgZmFsc2UpO1xufSkoKTtcbiIsICJleHBvcnQgY29uc3QgQ09OU0VDVVRJVkVfUkVMT0FEUyA9IFwiY29uc2VjdXRpdmUtcmVsb2Fkc1wiO1xuZXhwb3J0IGNvbnN0IE1BWF9SRUxPQURTID0gMTA7XG5leHBvcnQgY29uc3QgUkVMT0FEX0pJVFRFUl9NSU4gPSA1MDAwO1xuZXhwb3J0IGNvbnN0IFJFTE9BRF9KSVRURVJfTUFYID0gMTAwMDA7XG5leHBvcnQgY29uc3QgRkFJTFNBRkVfSklUVEVSID0gMzAwMDA7XG5leHBvcnQgY29uc3QgUEhYX0VWRU5UX0NMQVNTRVMgPSBbXG4gIFwicGh4LWNsaWNrLWxvYWRpbmdcIixcbiAgXCJwaHgtY2hhbmdlLWxvYWRpbmdcIixcbiAgXCJwaHgtc3VibWl0LWxvYWRpbmdcIixcbiAgXCJwaHgta2V5ZG93bi1sb2FkaW5nXCIsXG4gIFwicGh4LWtleXVwLWxvYWRpbmdcIixcbiAgXCJwaHgtYmx1ci1sb2FkaW5nXCIsXG4gIFwicGh4LWZvY3VzLWxvYWRpbmdcIixcbiAgXCJwaHgtaG9vay1sb2FkaW5nXCIsXG5dO1xuZXhwb3J0IGNvbnN0IFBIWF9DT01QT05FTlQgPSBcImRhdGEtcGh4LWNvbXBvbmVudFwiO1xuZXhwb3J0IGNvbnN0IFBIWF9WSUVXX1JFRiA9IFwiZGF0YS1waHgtdmlld1wiO1xuZXhwb3J0IGNvbnN0IFBIWF9MSVZFX0xJTksgPSBcImRhdGEtcGh4LWxpbmtcIjtcbmV4cG9ydCBjb25zdCBQSFhfVFJBQ0tfU1RBVElDID0gXCJ0cmFjay1zdGF0aWNcIjtcbmV4cG9ydCBjb25zdCBQSFhfTElOS19TVEFURSA9IFwiZGF0YS1waHgtbGluay1zdGF0ZVwiO1xuZXhwb3J0IGNvbnN0IFBIWF9SRUZfTE9BRElORyA9IFwiZGF0YS1waHgtcmVmLWxvYWRpbmdcIjtcbmV4cG9ydCBjb25zdCBQSFhfUkVGX1NSQyA9IFwiZGF0YS1waHgtcmVmLXNyY1wiO1xuZXhwb3J0IGNvbnN0IFBIWF9SRUZfTE9DSyA9IFwiZGF0YS1waHgtcmVmLWxvY2tcIjtcbmV4cG9ydCBjb25zdCBQSFhfUEVORElOR19SRUZTID0gXCJwaHgtcGVuZGluZy1yZWZzXCI7XG5leHBvcnQgY29uc3QgUEhYX1RSQUNLX1VQTE9BRFMgPSBcInRyYWNrLXVwbG9hZHNcIjtcbmV4cG9ydCBjb25zdCBQSFhfVVBMT0FEX1JFRiA9IFwiZGF0YS1waHgtdXBsb2FkLXJlZlwiO1xuZXhwb3J0IGNvbnN0IFBIWF9QUkVGTElHSFRFRF9SRUZTID0gXCJkYXRhLXBoeC1wcmVmbGlnaHRlZC1yZWZzXCI7XG5leHBvcnQgY29uc3QgUEhYX0RPTkVfUkVGUyA9IFwiZGF0YS1waHgtZG9uZS1yZWZzXCI7XG5leHBvcnQgY29uc3QgUEhYX0RST1BfVEFSR0VUID0gXCJkcm9wLXRhcmdldFwiO1xuZXhwb3J0IGNvbnN0IFBIWF9BQ1RJVkVfRU5UUllfUkVGUyA9IFwiZGF0YS1waHgtYWN0aXZlLXJlZnNcIjtcbmV4cG9ydCBjb25zdCBQSFhfTElWRV9GSUxFX1VQREFURUQgPSBcInBoeDpsaXZlLWZpbGU6dXBkYXRlZFwiO1xuZXhwb3J0IGNvbnN0IFBIWF9TS0lQID0gXCJkYXRhLXBoeC1za2lwXCI7XG5leHBvcnQgY29uc3QgUEhYX01BR0lDX0lEID0gXCJkYXRhLXBoeC1pZFwiO1xuZXhwb3J0IGNvbnN0IFBIWF9QUlVORSA9IFwiZGF0YS1waHgtcHJ1bmVcIjtcbmV4cG9ydCBjb25zdCBQSFhfQ09OTkVDVEVEX0NMQVNTID0gXCJwaHgtY29ubmVjdGVkXCI7XG5leHBvcnQgY29uc3QgUEhYX0xPQURJTkdfQ0xBU1MgPSBcInBoeC1sb2FkaW5nXCI7XG5leHBvcnQgY29uc3QgUEhYX0VSUk9SX0NMQVNTID0gXCJwaHgtZXJyb3JcIjtcbmV4cG9ydCBjb25zdCBQSFhfQ0xJRU5UX0VSUk9SX0NMQVNTID0gXCJwaHgtY2xpZW50LWVycm9yXCI7XG5leHBvcnQgY29uc3QgUEhYX1NFUlZFUl9FUlJPUl9DTEFTUyA9IFwicGh4LXNlcnZlci1lcnJvclwiO1xuZXhwb3J0IGNvbnN0IFBIWF9QQVJFTlRfSUQgPSBcImRhdGEtcGh4LXBhcmVudC1pZFwiO1xuZXhwb3J0IGNvbnN0IFBIWF9NQUlOID0gXCJkYXRhLXBoeC1tYWluXCI7XG5leHBvcnQgY29uc3QgUEhYX1JPT1RfSUQgPSBcImRhdGEtcGh4LXJvb3QtaWRcIjtcbmV4cG9ydCBjb25zdCBQSFhfVklFV1BPUlRfVE9QID0gXCJ2aWV3cG9ydC10b3BcIjtcbmV4cG9ydCBjb25zdCBQSFhfVklFV1BPUlRfQk9UVE9NID0gXCJ2aWV3cG9ydC1ib3R0b21cIjtcbmV4cG9ydCBjb25zdCBQSFhfVFJJR0dFUl9BQ1RJT04gPSBcInRyaWdnZXItYWN0aW9uXCI7XG5leHBvcnQgY29uc3QgUEhYX0hBU19GT0NVU0VEID0gXCJwaHgtaGFzLWZvY3VzZWRcIjtcbmV4cG9ydCBjb25zdCBGT0NVU0FCTEVfSU5QVVRTID0gW1xuICBcInRleHRcIixcbiAgXCJ0ZXh0YXJlYVwiLFxuICBcIm51bWJlclwiLFxuICBcImVtYWlsXCIsXG4gIFwicGFzc3dvcmRcIixcbiAgXCJzZWFyY2hcIixcbiAgXCJ0ZWxcIixcbiAgXCJ1cmxcIixcbiAgXCJkYXRlXCIsXG4gIFwidGltZVwiLFxuICBcImRhdGV0aW1lLWxvY2FsXCIsXG4gIFwiY29sb3JcIixcbiAgXCJyYW5nZVwiLFxuXTtcbmV4cG9ydCBjb25zdCBDSEVDS0FCTEVfSU5QVVRTID0gW1wiY2hlY2tib3hcIiwgXCJyYWRpb1wiXTtcbmV4cG9ydCBjb25zdCBQSFhfSEFTX1NVQk1JVFRFRCA9IFwicGh4LWhhcy1zdWJtaXR0ZWRcIjtcbmV4cG9ydCBjb25zdCBQSFhfU0VTU0lPTiA9IFwiZGF0YS1waHgtc2Vzc2lvblwiO1xuZXhwb3J0IGNvbnN0IFBIWF9WSUVXX1NFTEVDVE9SID0gYFske1BIWF9TRVNTSU9OfV1gO1xuZXhwb3J0IGNvbnN0IFBIWF9TVElDS1kgPSBcImRhdGEtcGh4LXN0aWNreVwiO1xuZXhwb3J0IGNvbnN0IFBIWF9TVEFUSUMgPSBcImRhdGEtcGh4LXN0YXRpY1wiO1xuZXhwb3J0IGNvbnN0IFBIWF9SRUFET05MWSA9IFwiZGF0YS1waHgtcmVhZG9ubHlcIjtcbmV4cG9ydCBjb25zdCBQSFhfRElTQUJMRUQgPSBcImRhdGEtcGh4LWRpc2FibGVkXCI7XG5leHBvcnQgY29uc3QgUEhYX0RJU0FCTEVfV0lUSCA9IFwiZGlzYWJsZS13aXRoXCI7XG5leHBvcnQgY29uc3QgUEhYX0RJU0FCTEVfV0lUSF9SRVNUT1JFID0gXCJkYXRhLXBoeC1kaXNhYmxlLXdpdGgtcmVzdG9yZVwiO1xuZXhwb3J0IGNvbnN0IFBIWF9IT09LID0gXCJob29rXCI7XG5leHBvcnQgY29uc3QgUEhYX0RFQk9VTkNFID0gXCJkZWJvdW5jZVwiO1xuZXhwb3J0IGNvbnN0IFBIWF9USFJPVFRMRSA9IFwidGhyb3R0bGVcIjtcbmV4cG9ydCBjb25zdCBQSFhfVVBEQVRFID0gXCJ1cGRhdGVcIjtcbmV4cG9ydCBjb25zdCBQSFhfU1RSRUFNID0gXCJzdHJlYW1cIjtcbmV4cG9ydCBjb25zdCBQSFhfU1RSRUFNX1JFRiA9IFwiZGF0YS1waHgtc3RyZWFtXCI7XG5leHBvcnQgY29uc3QgUEhYX1BPUlRBTCA9IFwiZGF0YS1waHgtcG9ydGFsXCI7XG5leHBvcnQgY29uc3QgUEhYX1RFTEVQT1JURURfUkVGID0gXCJkYXRhLXBoeC10ZWxlcG9ydGVkXCI7XG5leHBvcnQgY29uc3QgUEhYX1RFTEVQT1JURURfU1JDID0gXCJkYXRhLXBoeC10ZWxlcG9ydGVkLXNyY1wiO1xuZXhwb3J0IGNvbnN0IFBIWF9SVU5USU1FX0hPT0sgPSBcImRhdGEtcGh4LXJ1bnRpbWUtaG9va1wiO1xuZXhwb3J0IGNvbnN0IFBIWF9MVl9QSUQgPSBcImRhdGEtcGh4LXBpZFwiO1xuZXhwb3J0IGNvbnN0IFBIWF9LRVkgPSBcImtleVwiO1xuZXhwb3J0IGNvbnN0IFBIWF9QUklWQVRFID0gXCJwaHhQcml2YXRlXCI7XG5leHBvcnQgY29uc3QgUEhYX0FVVE9fUkVDT1ZFUiA9IFwiYXV0by1yZWNvdmVyXCI7XG5leHBvcnQgY29uc3QgUEhYX0xWX0RFQlVHID0gXCJwaHg6bGl2ZS1zb2NrZXQ6ZGVidWdcIjtcbmV4cG9ydCBjb25zdCBQSFhfTFZfUFJPRklMRSA9IFwicGh4OmxpdmUtc29ja2V0OnByb2ZpbGluZ1wiO1xuZXhwb3J0IGNvbnN0IFBIWF9MVl9MQVRFTkNZX1NJTSA9IFwicGh4OmxpdmUtc29ja2V0OmxhdGVuY3ktc2ltXCI7XG5leHBvcnQgY29uc3QgUEhYX0xWX0hJU1RPUllfUE9TSVRJT04gPSBcInBoeDpuYXYtaGlzdG9yeS1wb3NpdGlvblwiO1xuZXhwb3J0IGNvbnN0IFBIWF9QUk9HUkVTUyA9IFwicHJvZ3Jlc3NcIjtcbmV4cG9ydCBjb25zdCBQSFhfTU9VTlRFRCA9IFwibW91bnRlZFwiO1xuZXhwb3J0IGNvbnN0IFBIWF9SRUxPQURfU1RBVFVTID0gXCJfX3Bob2VuaXhfcmVsb2FkX3N0YXR1c19fXCI7XG5leHBvcnQgY29uc3QgTE9BREVSX1RJTUVPVVQgPSAxO1xuZXhwb3J0IGNvbnN0IE1BWF9DSElMRF9KT0lOX0FUVEVNUFRTID0gMztcbmV4cG9ydCBjb25zdCBCRUZPUkVfVU5MT0FEX0xPQURFUl9USU1FT1VUID0gMjAwO1xuZXhwb3J0IGNvbnN0IERJU0NPTk5FQ1RFRF9USU1FT1VUID0gNTAwO1xuZXhwb3J0IGNvbnN0IEJJTkRJTkdfUFJFRklYID0gXCJwaHgtXCI7XG5leHBvcnQgY29uc3QgUFVTSF9USU1FT1VUID0gMzAwMDA7XG5leHBvcnQgY29uc3QgTElOS19IRUFERVIgPSBcIngtcmVxdWVzdGVkLXdpdGhcIjtcbmV4cG9ydCBjb25zdCBSRVNQT05TRV9VUkxfSEVBREVSID0gXCJ4LXJlc3BvbnNlLXVybFwiO1xuZXhwb3J0IGNvbnN0IERFQk9VTkNFX1RSSUdHRVIgPSBcImRlYm91bmNlLXRyaWdnZXJcIjtcbmV4cG9ydCBjb25zdCBUSFJPVFRMRUQgPSBcInRocm90dGxlZFwiO1xuZXhwb3J0IGNvbnN0IERFQk9VTkNFX1BSRVZfS0VZID0gXCJkZWJvdW5jZS1wcmV2LWtleVwiO1xuZXhwb3J0IGNvbnN0IERFRkFVTFRTID0ge1xuICBkZWJvdW5jZTogMzAwLFxuICB0aHJvdHRsZTogMzAwLFxufTtcbmV4cG9ydCBjb25zdCBQSFhfUEVORElOR19BVFRSUyA9IFtQSFhfUkVGX0xPQURJTkcsIFBIWF9SRUZfU1JDLCBQSFhfUkVGX0xPQ0tdO1xuLy8gUmVuZGVyZWRcbmV4cG9ydCBjb25zdCBTVEFUSUMgPSBcInNcIjtcbmV4cG9ydCBjb25zdCBST09UID0gXCJyXCI7XG5leHBvcnQgY29uc3QgQ09NUE9ORU5UUyA9IFwiY1wiO1xuZXhwb3J0IGNvbnN0IEtFWUVEID0gXCJrXCI7XG5leHBvcnQgY29uc3QgS0VZRURfQ09VTlQgPSBcImtjXCI7XG5leHBvcnQgY29uc3QgRVZFTlRTID0gXCJlXCI7XG5leHBvcnQgY29uc3QgUkVQTFkgPSBcInJcIjtcbmV4cG9ydCBjb25zdCBUSVRMRSA9IFwidFwiO1xuZXhwb3J0IGNvbnN0IFRFTVBMQVRFUyA9IFwicFwiO1xuZXhwb3J0IGNvbnN0IFNUUkVBTSA9IFwic3RyZWFtXCI7XG4iLCAiaW1wb3J0IHsgbG9nRXJyb3IgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBFbnRyeVVwbG9hZGVyIHtcbiAgY29uc3RydWN0b3IoZW50cnksIGNvbmZpZywgbGl2ZVNvY2tldCkge1xuICAgIGNvbnN0IHsgY2h1bmtfc2l6ZSwgY2h1bmtfdGltZW91dCB9ID0gY29uZmlnO1xuICAgIHRoaXMubGl2ZVNvY2tldCA9IGxpdmVTb2NrZXQ7XG4gICAgdGhpcy5lbnRyeSA9IGVudHJ5O1xuICAgIHRoaXMub2Zmc2V0ID0gMDtcbiAgICB0aGlzLmNodW5rU2l6ZSA9IGNodW5rX3NpemU7XG4gICAgdGhpcy5jaHVua1RpbWVvdXQgPSBjaHVua190aW1lb3V0O1xuICAgIHRoaXMuY2h1bmtUaW1lciA9IG51bGw7XG4gICAgdGhpcy5lcnJvcmVkID0gZmFsc2U7XG4gICAgdGhpcy51cGxvYWRDaGFubmVsID0gbGl2ZVNvY2tldC5jaGFubmVsKGBsdnU6JHtlbnRyeS5yZWZ9YCwge1xuICAgICAgdG9rZW46IGVudHJ5Lm1ldGFkYXRhKCksXG4gICAgfSk7XG4gIH1cblxuICBlcnJvcihyZWFzb24pIHtcbiAgICBpZiAodGhpcy5lcnJvcmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMudXBsb2FkQ2hhbm5lbC5sZWF2ZSgpO1xuICAgIHRoaXMuZXJyb3JlZCA9IHRydWU7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuY2h1bmtUaW1lcik7XG4gICAgdGhpcy5lbnRyeS5lcnJvcihyZWFzb24pO1xuICB9XG5cbiAgdXBsb2FkKCkge1xuICAgIHRoaXMudXBsb2FkQ2hhbm5lbC5vbkVycm9yKChyZWFzb24pID0+IHRoaXMuZXJyb3IocmVhc29uKSk7XG4gICAgdGhpcy51cGxvYWRDaGFubmVsXG4gICAgICAuam9pbigpXG4gICAgICAucmVjZWl2ZShcIm9rXCIsIChfZGF0YSkgPT4gdGhpcy5yZWFkTmV4dENodW5rKCkpXG4gICAgICAucmVjZWl2ZShcImVycm9yXCIsIChyZWFzb24pID0+IHRoaXMuZXJyb3IocmVhc29uKSk7XG4gIH1cblxuICBpc0RvbmUoKSB7XG4gICAgcmV0dXJuIHRoaXMub2Zmc2V0ID49IHRoaXMuZW50cnkuZmlsZS5zaXplO1xuICB9XG5cbiAgcmVhZE5leHRDaHVuaygpIHtcbiAgICBjb25zdCByZWFkZXIgPSBuZXcgd2luZG93LkZpbGVSZWFkZXIoKTtcbiAgICBjb25zdCBibG9iID0gdGhpcy5lbnRyeS5maWxlLnNsaWNlKFxuICAgICAgdGhpcy5vZmZzZXQsXG4gICAgICB0aGlzLmNodW5rU2l6ZSArIHRoaXMub2Zmc2V0LFxuICAgICk7XG4gICAgcmVhZGVyLm9ubG9hZCA9IChlKSA9PiB7XG4gICAgICBpZiAoZS50YXJnZXQuZXJyb3IgPT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5vZmZzZXQgKz0gLyoqIEB0eXBlIHtBcnJheUJ1ZmZlcn0gKi8gKGUudGFyZ2V0LnJlc3VsdCkuYnl0ZUxlbmd0aDtcbiAgICAgICAgdGhpcy5wdXNoQ2h1bmsoLyoqIEB0eXBlIHtBcnJheUJ1ZmZlcn0gKi8gKGUudGFyZ2V0LnJlc3VsdCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGxvZ0Vycm9yKFwiUmVhZCBlcnJvcjogXCIgKyBlLnRhcmdldC5lcnJvcik7XG4gICAgICB9XG4gICAgfTtcbiAgICByZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoYmxvYik7XG4gIH1cblxuICBwdXNoQ2h1bmsoY2h1bmspIHtcbiAgICBpZiAoIXRoaXMudXBsb2FkQ2hhbm5lbC5pc0pvaW5lZCgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMudXBsb2FkQ2hhbm5lbFxuICAgICAgLnB1c2goXCJjaHVua1wiLCBjaHVuaywgdGhpcy5jaHVua1RpbWVvdXQpXG4gICAgICAucmVjZWl2ZShcIm9rXCIsICgpID0+IHtcbiAgICAgICAgdGhpcy5lbnRyeS5wcm9ncmVzcygodGhpcy5vZmZzZXQgLyB0aGlzLmVudHJ5LmZpbGUuc2l6ZSkgKiAxMDApO1xuICAgICAgICBpZiAoIXRoaXMuaXNEb25lKCkpIHtcbiAgICAgICAgICB0aGlzLmNodW5rVGltZXIgPSBzZXRUaW1lb3V0KFxuICAgICAgICAgICAgKCkgPT4gdGhpcy5yZWFkTmV4dENodW5rKCksXG4gICAgICAgICAgICB0aGlzLmxpdmVTb2NrZXQuZ2V0TGF0ZW5jeVNpbSgpIHx8IDAsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIC5yZWNlaXZlKFwiZXJyb3JcIiwgKHsgcmVhc29uIH0pID0+IHRoaXMuZXJyb3IocmVhc29uKSk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBQSFhfVklFV19TRUxFQ1RPUiB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuXG5pbXBvcnQgRW50cnlVcGxvYWRlciBmcm9tIFwiLi9lbnRyeV91cGxvYWRlclwiO1xuXG5leHBvcnQgY29uc3QgbG9nRXJyb3IgPSAobXNnLCBvYmopID0+IGNvbnNvbGUuZXJyb3IgJiYgY29uc29sZS5lcnJvcihtc2csIG9iaik7XG5cbmV4cG9ydCBjb25zdCBpc0NpZCA9IChjaWQpID0+IHtcbiAgY29uc3QgdHlwZSA9IHR5cGVvZiBjaWQ7XG4gIHJldHVybiB0eXBlID09PSBcIm51bWJlclwiIHx8ICh0eXBlID09PSBcInN0cmluZ1wiICYmIC9eKDB8WzEtOV1cXGQqKSQvLnRlc3QoY2lkKSk7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZGV0ZWN0RHVwbGljYXRlSWRzKCkge1xuICBjb25zdCBpZHMgPSBuZXcgU2V0KCk7XG4gIGNvbnN0IGVsZW1zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIipbaWRdXCIpO1xuICBmb3IgKGxldCBpID0gMCwgbGVuID0gZWxlbXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBpZiAoaWRzLmhhcyhlbGVtc1tpXS5pZCkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgIGBNdWx0aXBsZSBJRHMgZGV0ZWN0ZWQ6ICR7ZWxlbXNbaV0uaWR9LiBFbnN1cmUgdW5pcXVlIGVsZW1lbnQgaWRzLmAsXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZHMuYWRkKGVsZW1zW2ldLmlkKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRldGVjdEludmFsaWRTdHJlYW1JbnNlcnRzKGluc2VydHMpIHtcbiAgY29uc3QgZXJyb3JzID0gbmV3IFNldCgpO1xuICBPYmplY3Qua2V5cyhpbnNlcnRzKS5mb3JFYWNoKChpZCkgPT4ge1xuICAgIGNvbnN0IHN0cmVhbUVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpO1xuICAgIGlmIChcbiAgICAgIHN0cmVhbUVsICYmXG4gICAgICBzdHJlYW1FbC5wYXJlbnRFbGVtZW50ICYmXG4gICAgICBzdHJlYW1FbC5wYXJlbnRFbGVtZW50LmdldEF0dHJpYnV0ZShcInBoeC11cGRhdGVcIikgIT09IFwic3RyZWFtXCJcbiAgICApIHtcbiAgICAgIGVycm9ycy5hZGQoXG4gICAgICAgIGBUaGUgc3RyZWFtIGNvbnRhaW5lciB3aXRoIGlkIFwiJHtzdHJlYW1FbC5wYXJlbnRFbGVtZW50LmlkfVwiIGlzIG1pc3NpbmcgdGhlIHBoeC11cGRhdGU9XCJzdHJlYW1cIiBhdHRyaWJ1dGUuIEVuc3VyZSBpdCBpcyBzZXQgZm9yIHN0cmVhbXMgdG8gd29yayBwcm9wZXJseS5gLFxuICAgICAgKTtcbiAgICB9XG4gIH0pO1xuICBlcnJvcnMuZm9yRWFjaCgoZXJyb3IpID0+IGNvbnNvbGUuZXJyb3IoZXJyb3IpKTtcbn1cblxuZXhwb3J0IGNvbnN0IGRlYnVnID0gKHZpZXcsIGtpbmQsIG1zZywgb2JqKSA9PiB7XG4gIGlmICh2aWV3LmxpdmVTb2NrZXQuaXNEZWJ1Z0VuYWJsZWQoKSkge1xuICAgIGNvbnNvbGUubG9nKGAke3ZpZXcuaWR9ICR7a2luZH06ICR7bXNnfSAtIGAsIG9iaik7XG4gIH1cbn07XG5cbi8vIHdyYXBzIHZhbHVlIGluIGNsb3N1cmUgb3IgcmV0dXJucyBjbG9zdXJlXG5leHBvcnQgY29uc3QgY2xvc3VyZSA9ICh2YWwpID0+XG4gIHR5cGVvZiB2YWwgPT09IFwiZnVuY3Rpb25cIlxuICAgID8gdmFsXG4gICAgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgICB9O1xuXG5leHBvcnQgY29uc3QgY2xvbmUgPSAob2JqKSA9PiB7XG4gIHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG9iaikpO1xufTtcblxuZXhwb3J0IGNvbnN0IGNsb3Nlc3RQaHhCaW5kaW5nID0gKGVsLCBiaW5kaW5nLCBib3JkZXJFbCkgPT4ge1xuICBkbyB7XG4gICAgaWYgKGVsLm1hdGNoZXMoYFske2JpbmRpbmd9XWApICYmICFlbC5kaXNhYmxlZCkge1xuICAgICAgcmV0dXJuIGVsO1xuICAgIH1cbiAgICBlbCA9IGVsLnBhcmVudEVsZW1lbnQgfHwgZWwucGFyZW50Tm9kZTtcbiAgfSB3aGlsZSAoXG4gICAgZWwgIT09IG51bGwgJiZcbiAgICBlbC5ub2RlVHlwZSA9PT0gMSAmJlxuICAgICEoKGJvcmRlckVsICYmIGJvcmRlckVsLmlzU2FtZU5vZGUoZWwpKSB8fCBlbC5tYXRjaGVzKFBIWF9WSUVXX1NFTEVDVE9SKSlcbiAgKTtcbiAgcmV0dXJuIG51bGw7XG59O1xuXG5leHBvcnQgY29uc3QgaXNPYmplY3QgPSAob2JqKSA9PiB7XG4gIHJldHVybiBvYmogIT09IG51bGwgJiYgdHlwZW9mIG9iaiA9PT0gXCJvYmplY3RcIiAmJiAhKG9iaiBpbnN0YW5jZW9mIEFycmF5KTtcbn07XG5cbmV4cG9ydCBjb25zdCBpc0VxdWFsT2JqID0gKG9iajEsIG9iajIpID0+XG4gIEpTT04uc3RyaW5naWZ5KG9iajEpID09PSBKU09OLnN0cmluZ2lmeShvYmoyKTtcblxuZXhwb3J0IGNvbnN0IGlzRW1wdHkgPSAob2JqKSA9PiB7XG4gIGZvciAoY29uc3QgeCBpbiBvYmopIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5leHBvcnQgY29uc3QgbWF5YmUgPSAoZWwsIGNhbGxiYWNrKSA9PiBlbCAmJiBjYWxsYmFjayhlbCk7XG5cbmV4cG9ydCBjb25zdCBjaGFubmVsVXBsb2FkZXIgPSBmdW5jdGlvbiAoZW50cmllcywgb25FcnJvciwgcmVzcCwgbGl2ZVNvY2tldCkge1xuICBlbnRyaWVzLmZvckVhY2goKGVudHJ5KSA9PiB7XG4gICAgY29uc3QgZW50cnlVcGxvYWRlciA9IG5ldyBFbnRyeVVwbG9hZGVyKGVudHJ5LCByZXNwLmNvbmZpZywgbGl2ZVNvY2tldCk7XG4gICAgZW50cnlVcGxvYWRlci51cGxvYWQoKTtcbiAgfSk7XG59O1xuIiwgImNvbnN0IEJyb3dzZXIgPSB7XG4gIGNhblB1c2hTdGF0ZSgpIHtcbiAgICByZXR1cm4gdHlwZW9mIGhpc3RvcnkucHVzaFN0YXRlICE9PSBcInVuZGVmaW5lZFwiO1xuICB9LFxuXG4gIGRyb3BMb2NhbChsb2NhbFN0b3JhZ2UsIG5hbWVzcGFjZSwgc3Via2V5KSB7XG4gICAgcmV0dXJuIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKHRoaXMubG9jYWxLZXkobmFtZXNwYWNlLCBzdWJrZXkpKTtcbiAgfSxcblxuICB1cGRhdGVMb2NhbChsb2NhbFN0b3JhZ2UsIG5hbWVzcGFjZSwgc3Via2V5LCBpbml0aWFsLCBmdW5jKSB7XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMuZ2V0TG9jYWwobG9jYWxTdG9yYWdlLCBuYW1lc3BhY2UsIHN1YmtleSk7XG4gICAgY29uc3Qga2V5ID0gdGhpcy5sb2NhbEtleShuYW1lc3BhY2UsIHN1YmtleSk7XG4gICAgY29uc3QgbmV3VmFsID0gY3VycmVudCA9PT0gbnVsbCA/IGluaXRpYWwgOiBmdW5jKGN1cnJlbnQpO1xuICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKGtleSwgSlNPTi5zdHJpbmdpZnkobmV3VmFsKSk7XG4gICAgcmV0dXJuIG5ld1ZhbDtcbiAgfSxcblxuICBnZXRMb2NhbChsb2NhbFN0b3JhZ2UsIG5hbWVzcGFjZSwgc3Via2V5KSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLmdldEl0ZW0odGhpcy5sb2NhbEtleShuYW1lc3BhY2UsIHN1YmtleSkpKTtcbiAgfSxcblxuICB1cGRhdGVDdXJyZW50U3RhdGUoY2FsbGJhY2spIHtcbiAgICBpZiAoIXRoaXMuY2FuUHVzaFN0YXRlKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaGlzdG9yeS5yZXBsYWNlU3RhdGUoXG4gICAgICBjYWxsYmFjayhoaXN0b3J5LnN0YXRlIHx8IHt9KSxcbiAgICAgIFwiXCIsXG4gICAgICB3aW5kb3cubG9jYXRpb24uaHJlZixcbiAgICApO1xuICB9LFxuXG4gIHB1c2hTdGF0ZShraW5kLCBtZXRhLCB0bykge1xuICAgIGlmICh0aGlzLmNhblB1c2hTdGF0ZSgpKSB7XG4gICAgICBpZiAodG8gIT09IHdpbmRvdy5sb2NhdGlvbi5ocmVmKSB7XG4gICAgICAgIGlmIChtZXRhLnR5cGUgPT0gXCJyZWRpcmVjdFwiICYmIG1ldGEuc2Nyb2xsKSB7XG4gICAgICAgICAgLy8gSWYgd2UncmUgcmVkaXJlY3Rpbmcgc3RvcmUgdGhlIGN1cnJlbnQgc2Nyb2xsWSBmb3IgdGhlIGN1cnJlbnQgaGlzdG9yeSBzdGF0ZS5cbiAgICAgICAgICBjb25zdCBjdXJyZW50U3RhdGUgPSBoaXN0b3J5LnN0YXRlIHx8IHt9O1xuICAgICAgICAgIGN1cnJlbnRTdGF0ZS5zY3JvbGwgPSBtZXRhLnNjcm9sbDtcbiAgICAgICAgICBoaXN0b3J5LnJlcGxhY2VTdGF0ZShjdXJyZW50U3RhdGUsIFwiXCIsIHdpbmRvdy5sb2NhdGlvbi5ocmVmKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRlbGV0ZSBtZXRhLnNjcm9sbDsgLy8gT25seSBzdG9yZSB0aGUgc2Nyb2xsIGluIHRoZSByZWRpcmVjdCBjYXNlLlxuICAgICAgICBoaXN0b3J5W2tpbmQgKyBcIlN0YXRlXCJdKG1ldGEsIFwiXCIsIHRvIHx8IG51bGwpOyAvLyBJRSB3aWxsIGNvZXJjZSB1bmRlZmluZWQgdG8gc3RyaW5nXG5cbiAgICAgICAgLy8gd2hlbiB1c2luZyBuYXZpZ2F0ZSwgd2UnZCBjYWxsIHB1c2hTdGF0ZSBpbW1lZGlhdGVseSBiZWZvcmUgcGF0Y2hpbmcgdGhlIERPTSxcbiAgICAgICAgLy8ganVtcGluZyBiYWNrIHRvIHRoZSB0b3Agb2YgdGhlIHBhZ2UsIGVmZmVjdGl2ZWx5IGlnbm9yaW5nIHRoZSBzY3JvbGxJbnRvVmlldztcbiAgICAgICAgLy8gdGhlcmVmb3JlIHdlIHdhaXQgZm9yIHRoZSBuZXh0IGZyYW1lIChhZnRlciB0aGUgRE9NIHBhdGNoKSBhbmQgb25seSB0aGVuIHRyeVxuICAgICAgICAvLyB0byBzY3JvbGwgdG8gdGhlIGhhc2hFbFxuICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICBjb25zdCBoYXNoRWwgPSB0aGlzLmdldEhhc2hUYXJnZXRFbCh3aW5kb3cubG9jYXRpb24uaGFzaCk7XG5cbiAgICAgICAgICBpZiAoaGFzaEVsKSB7XG4gICAgICAgICAgICBoYXNoRWwuc2Nyb2xsSW50b1ZpZXcoKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKG1ldGEudHlwZSA9PT0gXCJyZWRpcmVjdFwiKSB7XG4gICAgICAgICAgICB3aW5kb3cuc2Nyb2xsKDAsIDApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmVkaXJlY3QodG8pO1xuICAgIH1cbiAgfSxcblxuICBzZXRDb29raWUobmFtZSwgdmFsdWUsIG1heEFnZVNlY29uZHMpIHtcbiAgICBjb25zdCBleHBpcmVzID1cbiAgICAgIHR5cGVvZiBtYXhBZ2VTZWNvbmRzID09PSBcIm51bWJlclwiID8gYCBtYXgtYWdlPSR7bWF4QWdlU2Vjb25kc307YCA6IFwiXCI7XG4gICAgZG9jdW1lbnQuY29va2llID0gYCR7bmFtZX09JHt2YWx1ZX07JHtleHBpcmVzfSBwYXRoPS9gO1xuICB9LFxuXG4gIGdldENvb2tpZShuYW1lKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmNvb2tpZS5yZXBsYWNlKFxuICAgICAgbmV3IFJlZ0V4cChgKD86KD86XnwuKjtcXHMqKSR7bmFtZX1cXHMqXFw9XFxzKihbXjtdKikuKiQpfF4uKiRgKSxcbiAgICAgIFwiJDFcIixcbiAgICApO1xuICB9LFxuXG4gIGRlbGV0ZUNvb2tpZShuYW1lKSB7XG4gICAgZG9jdW1lbnQuY29va2llID0gYCR7bmFtZX09OyBtYXgtYWdlPS0xOyBwYXRoPS9gO1xuICB9LFxuXG4gIHJlZGlyZWN0KFxuICAgIHRvVVJMLFxuICAgIGZsYXNoLFxuICAgIG5hdmlnYXRlID0gKHVybCkgPT4ge1xuICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSB1cmw7XG4gICAgfSxcbiAgKSB7XG4gICAgaWYgKGZsYXNoKSB7XG4gICAgICB0aGlzLnNldENvb2tpZShcIl9fcGhvZW5peF9mbGFzaF9fXCIsIGZsYXNoLCA2MCk7XG4gICAgfVxuICAgIG5hdmlnYXRlKHRvVVJMKTtcbiAgfSxcblxuICBsb2NhbEtleShuYW1lc3BhY2UsIHN1YmtleSkge1xuICAgIHJldHVybiBgJHtuYW1lc3BhY2V9LSR7c3Via2V5fWA7XG4gIH0sXG5cbiAgZ2V0SGFzaFRhcmdldEVsKG1heWJlSGFzaCkge1xuICAgIGNvbnN0IGhhc2ggPSBtYXliZUhhc2gudG9TdHJpbmcoKS5zdWJzdHJpbmcoMSk7XG4gICAgaWYgKGhhc2ggPT09IFwiXCIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcmV0dXJuIChcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGhhc2gpIHx8XG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBhW25hbWU9XCIke2hhc2h9XCJdYClcbiAgICApO1xuICB9LFxufTtcblxuZXhwb3J0IGRlZmF1bHQgQnJvd3NlcjtcbiIsICJpbXBvcnQge1xuICBDSEVDS0FCTEVfSU5QVVRTLFxuICBERUJPVU5DRV9QUkVWX0tFWSxcbiAgREVCT1VOQ0VfVFJJR0dFUixcbiAgRk9DVVNBQkxFX0lOUFVUUyxcbiAgUEhYX0NPTVBPTkVOVCxcbiAgUEhYX1ZJRVdfUkVGLFxuICBQSFhfVEVMRVBPUlRFRF9SRUYsXG4gIFBIWF9IQVNfRk9DVVNFRCxcbiAgUEhYX0hBU19TVUJNSVRURUQsXG4gIFBIWF9NQUlOLFxuICBQSFhfUEFSRU5UX0lELFxuICBQSFhfUFJJVkFURSxcbiAgUEhYX1JFRl9TUkMsXG4gIFBIWF9SRUZfTE9DSyxcbiAgUEhYX1BFTkRJTkdfQVRUUlMsXG4gIFBIWF9ST09UX0lELFxuICBQSFhfU0VTU0lPTixcbiAgUEhYX1NUQVRJQyxcbiAgUEhYX1VQTE9BRF9SRUYsXG4gIFBIWF9WSUVXX1NFTEVDVE9SLFxuICBQSFhfU1RJQ0tZLFxuICBQSFhfRVZFTlRfQ0xBU1NFUyxcbiAgVEhST1RUTEVELFxuICBQSFhfUE9SVEFMLFxuICBQSFhfU1RSRUFNLFxufSBmcm9tIFwiLi9jb25zdGFudHNcIjtcblxuaW1wb3J0IHsgbG9nRXJyb3IgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5jb25zdCBET00gPSB7XG4gIGJ5SWQoaWQpIHtcbiAgICByZXR1cm4gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpIHx8IGxvZ0Vycm9yKGBubyBpZCBmb3VuZCBmb3IgJHtpZH1gKTtcbiAgfSxcblxuICByZW1vdmVDbGFzcyhlbCwgY2xhc3NOYW1lKSB7XG4gICAgZWwuY2xhc3NMaXN0LnJlbW92ZShjbGFzc05hbWUpO1xuICAgIGlmIChlbC5jbGFzc0xpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoXCJjbGFzc1wiKTtcbiAgICB9XG4gIH0sXG5cbiAgYWxsKG5vZGUsIHF1ZXJ5LCBjYWxsYmFjaykge1xuICAgIGlmICghbm9kZSkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICBjb25zdCBhcnJheSA9IEFycmF5LmZyb20obm9kZS5xdWVyeVNlbGVjdG9yQWxsKHF1ZXJ5KSk7XG4gICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICBhcnJheS5mb3JFYWNoKGNhbGxiYWNrKTtcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5O1xuICB9LFxuXG4gIGNoaWxkTm9kZUxlbmd0aChodG1sKSB7XG4gICAgY29uc3QgdGVtcGxhdGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidGVtcGxhdGVcIik7XG4gICAgdGVtcGxhdGUuaW5uZXJIVE1MID0gaHRtbDtcbiAgICByZXR1cm4gdGVtcGxhdGUuY29udGVudC5jaGlsZEVsZW1lbnRDb3VudDtcbiAgfSxcblxuICBpc1VwbG9hZElucHV0KGVsKSB7XG4gICAgcmV0dXJuIGVsLnR5cGUgPT09IFwiZmlsZVwiICYmIGVsLmdldEF0dHJpYnV0ZShQSFhfVVBMT0FEX1JFRikgIT09IG51bGw7XG4gIH0sXG5cbiAgaXNBdXRvVXBsb2FkKGlucHV0RWwpIHtcbiAgICByZXR1cm4gaW5wdXRFbC5oYXNBdHRyaWJ1dGUoXCJkYXRhLXBoeC1hdXRvLXVwbG9hZFwiKTtcbiAgfSxcblxuICBmaW5kVXBsb2FkSW5wdXRzKG5vZGUpIHtcbiAgICBjb25zdCBmb3JtSWQgPSBub2RlLmlkO1xuICAgIGNvbnN0IGlucHV0c091dHNpZGVGb3JtID0gdGhpcy5hbGwoXG4gICAgICBkb2N1bWVudCxcbiAgICAgIGBpbnB1dFt0eXBlPVwiZmlsZVwiXVske1BIWF9VUExPQURfUkVGfV1bZm9ybT1cIiR7Zm9ybUlkfVwiXWAsXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5hbGwobm9kZSwgYGlucHV0W3R5cGU9XCJmaWxlXCJdWyR7UEhYX1VQTE9BRF9SRUZ9XWApLmNvbmNhdChcbiAgICAgIGlucHV0c091dHNpZGVGb3JtLFxuICAgICk7XG4gIH0sXG5cbiAgZmluZENvbXBvbmVudE5vZGVMaXN0KHZpZXdJZCwgY2lkLCBkb2MgPSBkb2N1bWVudCkge1xuICAgIHJldHVybiB0aGlzLmFsbChcbiAgICAgIGRvYyxcbiAgICAgIGBbJHtQSFhfVklFV19SRUZ9PVwiJHt2aWV3SWR9XCJdWyR7UEhYX0NPTVBPTkVOVH09XCIke2NpZH1cIl1gLFxuICAgICk7XG4gIH0sXG5cbiAgaXNQaHhEZXN0cm95ZWQobm9kZSkge1xuICAgIHJldHVybiBub2RlLmlkICYmIERPTS5wcml2YXRlKG5vZGUsIFwiZGVzdHJveWVkXCIpID8gdHJ1ZSA6IGZhbHNlO1xuICB9LFxuXG4gIHdhbnRzTmV3VGFiKGUpIHtcbiAgICBjb25zdCB3YW50c05ld1RhYiA9XG4gICAgICBlLmN0cmxLZXkgfHwgZS5zaGlmdEtleSB8fCBlLm1ldGFLZXkgfHwgKGUuYnV0dG9uICYmIGUuYnV0dG9uID09PSAxKTtcbiAgICBjb25zdCBpc0Rvd25sb2FkID1cbiAgICAgIGUudGFyZ2V0IGluc3RhbmNlb2YgSFRNTEFuY2hvckVsZW1lbnQgJiZcbiAgICAgIGUudGFyZ2V0Lmhhc0F0dHJpYnV0ZShcImRvd25sb2FkXCIpO1xuICAgIGNvbnN0IGlzVGFyZ2V0QmxhbmsgPVxuICAgICAgZS50YXJnZXQuaGFzQXR0cmlidXRlKFwidGFyZ2V0XCIpICYmXG4gICAgICBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoXCJ0YXJnZXRcIikudG9Mb3dlckNhc2UoKSA9PT0gXCJfYmxhbmtcIjtcbiAgICBjb25zdCBpc1RhcmdldE5hbWVkVGFiID1cbiAgICAgIGUudGFyZ2V0Lmhhc0F0dHJpYnV0ZShcInRhcmdldFwiKSAmJlxuICAgICAgIWUudGFyZ2V0LmdldEF0dHJpYnV0ZShcInRhcmdldFwiKS5zdGFydHNXaXRoKFwiX1wiKTtcbiAgICByZXR1cm4gd2FudHNOZXdUYWIgfHwgaXNUYXJnZXRCbGFuayB8fCBpc0Rvd25sb2FkIHx8IGlzVGFyZ2V0TmFtZWRUYWI7XG4gIH0sXG5cbiAgaXNVbmxvYWRhYmxlRm9ybVN1Ym1pdChlKSB7XG4gICAgLy8gSWdub3JlIGZvcm0gc3VibWlzc2lvbnMgaW50ZW5kZWQgdG8gY2xvc2UgYSBuYXRpdmUgPGRpYWxvZz4gZWxlbWVudFxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvRWxlbWVudC9kaWFsb2cjdXNhZ2Vfbm90ZXNcbiAgICBjb25zdCBpc0RpYWxvZ1N1Ym1pdCA9XG4gICAgICAoZS50YXJnZXQgJiYgZS50YXJnZXQuZ2V0QXR0cmlidXRlKFwibWV0aG9kXCIpID09PSBcImRpYWxvZ1wiKSB8fFxuICAgICAgKGUuc3VibWl0dGVyICYmIGUuc3VibWl0dGVyLmdldEF0dHJpYnV0ZShcImZvcm1tZXRob2RcIikgPT09IFwiZGlhbG9nXCIpO1xuXG4gICAgaWYgKGlzRGlhbG9nU3VibWl0KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAhZS5kZWZhdWx0UHJldmVudGVkICYmICF0aGlzLndhbnRzTmV3VGFiKGUpO1xuICAgIH1cbiAgfSxcblxuICBpc05ld1BhZ2VDbGljayhlLCBjdXJyZW50TG9jYXRpb24pIHtcbiAgICBjb25zdCBocmVmID1cbiAgICAgIGUudGFyZ2V0IGluc3RhbmNlb2YgSFRNTEFuY2hvckVsZW1lbnRcbiAgICAgICAgPyBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoXCJocmVmXCIpXG4gICAgICAgIDogbnVsbDtcbiAgICBsZXQgdXJsO1xuXG4gICAgaWYgKGUuZGVmYXVsdFByZXZlbnRlZCB8fCBocmVmID09PSBudWxsIHx8IHRoaXMud2FudHNOZXdUYWIoZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKGhyZWYuc3RhcnRzV2l0aChcIm1haWx0bzpcIikgfHwgaHJlZi5zdGFydHNXaXRoKFwidGVsOlwiKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoZS50YXJnZXQuaXNDb250ZW50RWRpdGFibGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgdXJsID0gbmV3IFVSTChocmVmKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHVybCA9IG5ldyBVUkwoaHJlZiwgY3VycmVudExvY2F0aW9uKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBiYWQgVVJMLCBmYWxsYmFjayB0byBsZXQgYnJvd3NlciB0cnkgaXQgYXMgZXh0ZXJuYWxcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdXJsLmhvc3QgPT09IGN1cnJlbnRMb2NhdGlvbi5ob3N0ICYmXG4gICAgICB1cmwucHJvdG9jb2wgPT09IGN1cnJlbnRMb2NhdGlvbi5wcm90b2NvbFxuICAgICkge1xuICAgICAgaWYgKFxuICAgICAgICB1cmwucGF0aG5hbWUgPT09IGN1cnJlbnRMb2NhdGlvbi5wYXRobmFtZSAmJlxuICAgICAgICB1cmwuc2VhcmNoID09PSBjdXJyZW50TG9jYXRpb24uc2VhcmNoXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIHVybC5oYXNoID09PSBcIlwiICYmICF1cmwuaHJlZi5lbmRzV2l0aChcIiNcIik7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB1cmwucHJvdG9jb2wuc3RhcnRzV2l0aChcImh0dHBcIik7XG4gIH0sXG5cbiAgbWFya1BoeENoaWxkRGVzdHJveWVkKGVsKSB7XG4gICAgaWYgKHRoaXMuaXNQaHhDaGlsZChlbCkpIHtcbiAgICAgIGVsLnNldEF0dHJpYnV0ZShQSFhfU0VTU0lPTiwgXCJcIik7XG4gICAgfVxuICAgIHRoaXMucHV0UHJpdmF0ZShlbCwgXCJkZXN0cm95ZWRcIiwgdHJ1ZSk7XG4gIH0sXG5cbiAgZmluZFBoeENoaWxkcmVuSW5GcmFnbWVudChodG1sLCBwYXJlbnRJZCkge1xuICAgIGNvbnN0IHRlbXBsYXRlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRlbXBsYXRlXCIpO1xuICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IGh0bWw7XG4gICAgcmV0dXJuIHRoaXMuZmluZFBoeENoaWxkcmVuKHRlbXBsYXRlLmNvbnRlbnQsIHBhcmVudElkKTtcbiAgfSxcblxuICBpc0lnbm9yZWQoZWwsIHBoeFVwZGF0ZSkge1xuICAgIHJldHVybiAoXG4gICAgICAoZWwuZ2V0QXR0cmlidXRlKHBoeFVwZGF0ZSkgfHwgZWwuZ2V0QXR0cmlidXRlKFwiZGF0YS1waHgtdXBkYXRlXCIpKSA9PT1cbiAgICAgIFwiaWdub3JlXCJcbiAgICApO1xuICB9LFxuXG4gIGlzUGh4VXBkYXRlKGVsLCBwaHhVcGRhdGUsIHVwZGF0ZVR5cGVzKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIGVsLmdldEF0dHJpYnV0ZSAmJiB1cGRhdGVUeXBlcy5pbmRleE9mKGVsLmdldEF0dHJpYnV0ZShwaHhVcGRhdGUpKSA+PSAwXG4gICAgKTtcbiAgfSxcblxuICBmaW5kUGh4U3RpY2t5KGVsKSB7XG4gICAgcmV0dXJuIHRoaXMuYWxsKGVsLCBgWyR7UEhYX1NUSUNLWX1dYCk7XG4gIH0sXG5cbiAgZmluZFBoeENoaWxkcmVuKGVsLCBwYXJlbnRJZCkge1xuICAgIHJldHVybiB0aGlzLmFsbChlbCwgYCR7UEhYX1ZJRVdfU0VMRUNUT1J9WyR7UEhYX1BBUkVOVF9JRH09XCIke3BhcmVudElkfVwiXWApO1xuICB9LFxuXG4gIGZpbmRFeGlzdGluZ1BhcmVudENJRHModmlld0lkLCBjaWRzKSB7XG4gICAgLy8gd2Ugb25seSB3YW50IHRvIGZpbmQgcGFyZW50cyB0aGF0IGV4aXN0IG9uIHRoZSBwYWdlXG4gICAgLy8gaWYgYSBjaWQgaXMgbm90IG9uIHRoZSBwYWdlLCB0aGUgb25seSB3YXkgaXQgY2FuIGJlIGFkZGVkIGJhY2sgdG8gdGhlIHBhZ2VcbiAgICAvLyBpcyBpZiBhIHBhcmVudCBhZGRzIGl0IGJhY2ssIHRoZXJlZm9yZSBpZiBhIGNpZCBkb2VzIG5vdCBleGlzdCBvbiB0aGUgcGFnZSxcbiAgICAvLyB3ZSBzaG91bGQgbm90IHRyeSB0byByZW5kZXIgaXQgYnkgaXRzZWxmIChiZWNhdXNlIGl0IHdvdWxkIGJlIHJlbmRlcmVkIHR3aWNlLFxuICAgIC8vIG9uZSBieSB0aGUgcGFyZW50LCBhbmQgYSBzZWNvbmQgdGltZSBieSBpdHNlbGYpXG4gICAgY29uc3QgcGFyZW50Q2lkcyA9IG5ldyBTZXQoKTtcbiAgICBjb25zdCBjaGlsZHJlbkNpZHMgPSBuZXcgU2V0KCk7XG5cbiAgICBjaWRzLmZvckVhY2goKGNpZCkgPT4ge1xuICAgICAgdGhpcy5hbGwoXG4gICAgICAgIGRvY3VtZW50LFxuICAgICAgICBgWyR7UEhYX1ZJRVdfUkVGfT1cIiR7dmlld0lkfVwiXVske1BIWF9DT01QT05FTlR9PVwiJHtjaWR9XCJdYCxcbiAgICAgICkuZm9yRWFjaCgocGFyZW50KSA9PiB7XG4gICAgICAgIHBhcmVudENpZHMuYWRkKGNpZCk7XG4gICAgICAgIHRoaXMuYWxsKHBhcmVudCwgYFske1BIWF9WSUVXX1JFRn09XCIke3ZpZXdJZH1cIl1bJHtQSFhfQ09NUE9ORU5UfV1gKVxuICAgICAgICAgIC5tYXAoKGVsKSA9PiBwYXJzZUludChlbC5nZXRBdHRyaWJ1dGUoUEhYX0NPTVBPTkVOVCkpKVxuICAgICAgICAgIC5mb3JFYWNoKChjaGlsZENJRCkgPT4gY2hpbGRyZW5DaWRzLmFkZChjaGlsZENJRCkpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBjaGlsZHJlbkNpZHMuZm9yRWFjaCgoY2hpbGRDaWQpID0+IHBhcmVudENpZHMuZGVsZXRlKGNoaWxkQ2lkKSk7XG5cbiAgICByZXR1cm4gcGFyZW50Q2lkcztcbiAgfSxcblxuICBwcml2YXRlKGVsLCBrZXkpIHtcbiAgICByZXR1cm4gZWxbUEhYX1BSSVZBVEVdICYmIGVsW1BIWF9QUklWQVRFXVtrZXldO1xuICB9LFxuXG4gIGRlbGV0ZVByaXZhdGUoZWwsIGtleSkge1xuICAgIGVsW1BIWF9QUklWQVRFXSAmJiBkZWxldGUgZWxbUEhYX1BSSVZBVEVdW2tleV07XG4gIH0sXG5cbiAgcHV0UHJpdmF0ZShlbCwga2V5LCB2YWx1ZSkge1xuICAgIGlmICghZWxbUEhYX1BSSVZBVEVdKSB7XG4gICAgICBlbFtQSFhfUFJJVkFURV0gPSB7fTtcbiAgICB9XG4gICAgZWxbUEhYX1BSSVZBVEVdW2tleV0gPSB2YWx1ZTtcbiAgfSxcblxuICB1cGRhdGVQcml2YXRlKGVsLCBrZXksIGRlZmF1bHRWYWwsIHVwZGF0ZUZ1bmMpIHtcbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMucHJpdmF0ZShlbCwga2V5KTtcbiAgICBpZiAoZXhpc3RpbmcgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5wdXRQcml2YXRlKGVsLCBrZXksIHVwZGF0ZUZ1bmMoZGVmYXVsdFZhbCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnB1dFByaXZhdGUoZWwsIGtleSwgdXBkYXRlRnVuYyhleGlzdGluZykpO1xuICAgIH1cbiAgfSxcblxuICBzeW5jUGVuZGluZ0F0dHJzKGZyb21FbCwgdG9FbCkge1xuICAgIGlmICghZnJvbUVsLmhhc0F0dHJpYnV0ZShQSFhfUkVGX1NSQykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgUEhYX0VWRU5UX0NMQVNTRVMuZm9yRWFjaCgoY2xhc3NOYW1lKSA9PiB7XG4gICAgICBmcm9tRWwuY2xhc3NMaXN0LmNvbnRhaW5zKGNsYXNzTmFtZSkgJiYgdG9FbC5jbGFzc0xpc3QuYWRkKGNsYXNzTmFtZSk7XG4gICAgfSk7XG4gICAgUEhYX1BFTkRJTkdfQVRUUlMuZmlsdGVyKChhdHRyKSA9PiBmcm9tRWwuaGFzQXR0cmlidXRlKGF0dHIpKS5mb3JFYWNoKFxuICAgICAgKGF0dHIpID0+IHtcbiAgICAgICAgdG9FbC5zZXRBdHRyaWJ1dGUoYXR0ciwgZnJvbUVsLmdldEF0dHJpYnV0ZShhdHRyKSk7XG4gICAgICB9LFxuICAgICk7XG4gIH0sXG5cbiAgY29weVByaXZhdGVzKHRhcmdldCwgc291cmNlKSB7XG4gICAgaWYgKHNvdXJjZVtQSFhfUFJJVkFURV0pIHtcbiAgICAgIHRhcmdldFtQSFhfUFJJVkFURV0gPSBzb3VyY2VbUEhYX1BSSVZBVEVdO1xuICAgIH1cbiAgfSxcblxuICBwdXRUaXRsZShzdHIpIHtcbiAgICBjb25zdCB0aXRsZUVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcInRpdGxlXCIpO1xuICAgIGlmICh0aXRsZUVsKSB7XG4gICAgICBjb25zdCB7IHByZWZpeCwgc3VmZml4LCBkZWZhdWx0OiBkZWZhdWx0VGl0bGUgfSA9IHRpdGxlRWwuZGF0YXNldDtcbiAgICAgIGNvbnN0IGlzRW1wdHkgPSB0eXBlb2Ygc3RyICE9PSBcInN0cmluZ1wiIHx8IHN0ci50cmltKCkgPT09IFwiXCI7XG4gICAgICBpZiAoaXNFbXB0eSAmJiB0eXBlb2YgZGVmYXVsdFRpdGxlICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaW5uZXIgPSBpc0VtcHR5ID8gZGVmYXVsdFRpdGxlIDogc3RyO1xuICAgICAgZG9jdW1lbnQudGl0bGUgPSBgJHtwcmVmaXggfHwgXCJcIn0ke2lubmVyIHx8IFwiXCJ9JHtzdWZmaXggfHwgXCJcIn1gO1xuICAgIH0gZWxzZSB7XG4gICAgICBkb2N1bWVudC50aXRsZSA9IHN0cjtcbiAgICB9XG4gIH0sXG5cbiAgZGVib3VuY2UoXG4gICAgZWwsXG4gICAgZXZlbnQsXG4gICAgcGh4RGVib3VuY2UsXG4gICAgZGVmYXVsdERlYm91bmNlLFxuICAgIHBoeFRocm90dGxlLFxuICAgIGRlZmF1bHRUaHJvdHRsZSxcbiAgICBhc3luY0ZpbHRlcixcbiAgICBjYWxsYmFjayxcbiAgKSB7XG4gICAgbGV0IGRlYm91bmNlID0gZWwuZ2V0QXR0cmlidXRlKHBoeERlYm91bmNlKTtcbiAgICBsZXQgdGhyb3R0bGUgPSBlbC5nZXRBdHRyaWJ1dGUocGh4VGhyb3R0bGUpO1xuXG4gICAgaWYgKGRlYm91bmNlID09PSBcIlwiKSB7XG4gICAgICBkZWJvdW5jZSA9IGRlZmF1bHREZWJvdW5jZTtcbiAgICB9XG4gICAgaWYgKHRocm90dGxlID09PSBcIlwiKSB7XG4gICAgICB0aHJvdHRsZSA9IGRlZmF1bHRUaHJvdHRsZTtcbiAgICB9XG4gICAgY29uc3QgdmFsdWUgPSBkZWJvdW5jZSB8fCB0aHJvdHRsZTtcbiAgICBzd2l0Y2ggKHZhbHVlKSB7XG4gICAgICBjYXNlIG51bGw6XG4gICAgICAgIHJldHVybiBjYWxsYmFjaygpO1xuXG4gICAgICBjYXNlIFwiYmx1clwiOlxuICAgICAgICB0aGlzLmluY0N5Y2xlKGVsLCBcImRlYm91bmNlLWJsdXItY3ljbGVcIiwgKCkgPT4ge1xuICAgICAgICAgIGlmIChhc3luY0ZpbHRlcigpKSB7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLm9uY2UoZWwsIFwiZGVib3VuY2UtYmx1clwiKSkge1xuICAgICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoXCJibHVyXCIsICgpID0+XG4gICAgICAgICAgICB0aGlzLnRyaWdnZXJDeWNsZShlbCwgXCJkZWJvdW5jZS1ibHVyLWN5Y2xlXCIpLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBjb25zdCB0aW1lb3V0ID0gcGFyc2VJbnQodmFsdWUpO1xuICAgICAgICBjb25zdCB0cmlnZ2VyID0gKCkgPT5cbiAgICAgICAgICB0aHJvdHRsZSA/IHRoaXMuZGVsZXRlUHJpdmF0ZShlbCwgVEhST1RUTEVEKSA6IGNhbGxiYWNrKCk7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRDeWNsZSA9IHRoaXMuaW5jQ3ljbGUoZWwsIERFQk9VTkNFX1RSSUdHRVIsIHRyaWdnZXIpO1xuICAgICAgICBpZiAoaXNOYU4odGltZW91dCkpIHtcbiAgICAgICAgICByZXR1cm4gbG9nRXJyb3IoYGludmFsaWQgdGhyb3R0bGUvZGVib3VuY2UgdmFsdWU6ICR7dmFsdWV9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRocm90dGxlKSB7XG4gICAgICAgICAgbGV0IG5ld0tleURvd24gPSBmYWxzZTtcbiAgICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJrZXlkb3duXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IHByZXZLZXkgPSB0aGlzLnByaXZhdGUoZWwsIERFQk9VTkNFX1BSRVZfS0VZKTtcbiAgICAgICAgICAgIHRoaXMucHV0UHJpdmF0ZShlbCwgREVCT1VOQ0VfUFJFVl9LRVksIGV2ZW50LmtleSk7XG4gICAgICAgICAgICBuZXdLZXlEb3duID0gcHJldktleSAhPT0gZXZlbnQua2V5O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghbmV3S2V5RG93biAmJiB0aGlzLnByaXZhdGUoZWwsIFRIUk9UVExFRCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgIGNvbnN0IHQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKGFzeW5jRmlsdGVyKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXJDeWNsZShlbCwgREVCT1VOQ0VfVFJJR0dFUik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sIHRpbWVvdXQpO1xuICAgICAgICAgICAgdGhpcy5wdXRQcml2YXRlKGVsLCBUSFJPVFRMRUQsIHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGlmIChhc3luY0ZpbHRlcigpKSB7XG4gICAgICAgICAgICAgIHRoaXMudHJpZ2dlckN5Y2xlKGVsLCBERUJPVU5DRV9UUklHR0VSLCBjdXJyZW50Q3ljbGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sIHRpbWVvdXQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZm9ybSA9IGVsLmZvcm07XG4gICAgICAgIGlmIChmb3JtICYmIHRoaXMub25jZShmb3JtLCBcImJpbmQtZGVib3VuY2VcIikpIHtcbiAgICAgICAgICBmb3JtLmFkZEV2ZW50TGlzdGVuZXIoXCJzdWJtaXRcIiwgKCkgPT4ge1xuICAgICAgICAgICAgQXJyYXkuZnJvbShuZXcgRm9ybURhdGEoZm9ybSkuZW50cmllcygpLCAoW25hbWVdKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IGlucHV0ID0gZm9ybS5xdWVyeVNlbGVjdG9yKGBbbmFtZT1cIiR7bmFtZX1cIl1gKTtcbiAgICAgICAgICAgICAgdGhpcy5pbmNDeWNsZShpbnB1dCwgREVCT1VOQ0VfVFJJR0dFUik7XG4gICAgICAgICAgICAgIHRoaXMuZGVsZXRlUHJpdmF0ZShpbnB1dCwgVEhST1RUTEVEKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm9uY2UoZWwsIFwiYmluZC1kZWJvdW5jZVwiKSkge1xuICAgICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoXCJibHVyXCIsICgpID0+IHtcbiAgICAgICAgICAgIC8vIGJlY2F1c2Ugd2UgdHJpZ2dlciB0aGUgY2FsbGJhY2sgaGVyZSxcbiAgICAgICAgICAgIC8vIHdlIGFsc28gY2xlYXIgdGhlIHRocm90dGxlIHRpbWVvdXQgdG8gcHJldmVudCB0aGUgY2FsbGJhY2tcbiAgICAgICAgICAgIC8vIGZyb20gYmVpbmcgY2FsbGVkIGFnYWluIGFmdGVyIHRoZSB0aW1lb3V0IGZpcmVzXG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wcml2YXRlKGVsLCBUSFJPVFRMRUQpKTtcbiAgICAgICAgICAgIHRoaXMudHJpZ2dlckN5Y2xlKGVsLCBERUJPVU5DRV9UUklHR0VSKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgfSxcblxuICB0cmlnZ2VyQ3ljbGUoZWwsIGtleSwgY3VycmVudEN5Y2xlKSB7XG4gICAgY29uc3QgW2N5Y2xlLCB0cmlnZ2VyXSA9IHRoaXMucHJpdmF0ZShlbCwga2V5KTtcbiAgICBpZiAoIWN1cnJlbnRDeWNsZSkge1xuICAgICAgY3VycmVudEN5Y2xlID0gY3ljbGU7XG4gICAgfVxuICAgIGlmIChjdXJyZW50Q3ljbGUgPT09IGN5Y2xlKSB7XG4gICAgICB0aGlzLmluY0N5Y2xlKGVsLCBrZXkpO1xuICAgICAgdHJpZ2dlcigpO1xuICAgIH1cbiAgfSxcblxuICBvbmNlKGVsLCBrZXkpIHtcbiAgICBpZiAodGhpcy5wcml2YXRlKGVsLCBrZXkpID09PSB0cnVlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRoaXMucHV0UHJpdmF0ZShlbCwga2V5LCB0cnVlKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSxcblxuICBpbmNDeWNsZShlbCwga2V5LCB0cmlnZ2VyID0gZnVuY3Rpb24gKCkge30pIHtcbiAgICBsZXQgW2N1cnJlbnRDeWNsZV0gPSB0aGlzLnByaXZhdGUoZWwsIGtleSkgfHwgWzAsIHRyaWdnZXJdO1xuICAgIGN1cnJlbnRDeWNsZSsrO1xuICAgIHRoaXMucHV0UHJpdmF0ZShlbCwga2V5LCBbY3VycmVudEN5Y2xlLCB0cmlnZ2VyXSk7XG4gICAgcmV0dXJuIGN1cnJlbnRDeWNsZTtcbiAgfSxcblxuICAvLyBtYWludGFpbnMgb3IgYWRkcyBwcml2YXRlbHkgdXNlZCBob29rIGluZm9ybWF0aW9uXG4gIC8vIGZyb21FbCBhbmQgdG9FbCBjYW4gYmUgdGhlIHNhbWUgZWxlbWVudCBpbiB0aGUgY2FzZSBvZiBhIG5ld2x5IGFkZGVkIG5vZGVcbiAgLy8gZnJvbUVsIGFuZCB0b0VsIGNhbiBiZSBhbnkgSFRNTCBub2RlIHR5cGUsIHNvIHdlIG5lZWQgdG8gY2hlY2sgaWYgaXQncyBhbiBlbGVtZW50IG5vZGVcbiAgbWFpbnRhaW5Qcml2YXRlSG9va3MoZnJvbUVsLCB0b0VsLCBwaHhWaWV3cG9ydFRvcCwgcGh4Vmlld3BvcnRCb3R0b20pIHtcbiAgICAvLyBtYWludGFpbiB0aGUgaG9va3MgY3JlYXRlZCB3aXRoIGNyZWF0ZUhvb2tcbiAgICBpZiAoXG4gICAgICBmcm9tRWwuaGFzQXR0cmlidXRlICYmXG4gICAgICBmcm9tRWwuaGFzQXR0cmlidXRlKFwiZGF0YS1waHgtaG9va1wiKSAmJlxuICAgICAgIXRvRWwuaGFzQXR0cmlidXRlKFwiZGF0YS1waHgtaG9va1wiKVxuICAgICkge1xuICAgICAgdG9FbC5zZXRBdHRyaWJ1dGUoXCJkYXRhLXBoeC1ob29rXCIsIGZyb21FbC5nZXRBdHRyaWJ1dGUoXCJkYXRhLXBoeC1ob29rXCIpKTtcbiAgICB9XG4gICAgLy8gYWRkIGhvb2tzIHRvIGVsZW1lbnRzIHdpdGggdmlld3BvcnQgYXR0cmlidXRlc1xuICAgIGlmIChcbiAgICAgIHRvRWwuaGFzQXR0cmlidXRlICYmXG4gICAgICAodG9FbC5oYXNBdHRyaWJ1dGUocGh4Vmlld3BvcnRUb3ApIHx8XG4gICAgICAgIHRvRWwuaGFzQXR0cmlidXRlKHBoeFZpZXdwb3J0Qm90dG9tKSlcbiAgICApIHtcbiAgICAgIHRvRWwuc2V0QXR0cmlidXRlKFwiZGF0YS1waHgtaG9va1wiLCBcIlBob2VuaXguSW5maW5pdGVTY3JvbGxcIik7XG4gICAgfVxuICB9LFxuXG4gIHB1dEN1c3RvbUVsSG9vayhlbCwgaG9vaykge1xuICAgIGlmIChlbC5pc0Nvbm5lY3RlZCkge1xuICAgICAgZWwuc2V0QXR0cmlidXRlKFwiZGF0YS1waHgtaG9va1wiLCBcIlwiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5lcnJvcihgXG4gICAgICAgIGhvb2sgYXR0YWNoZWQgdG8gbm9uLWNvbm5lY3RlZCBET00gZWxlbWVudFxuICAgICAgICBlbnN1cmUgeW91IGFyZSBjYWxsaW5nIGNyZWF0ZUhvb2sgd2l0aGluIHlvdXIgY29ubmVjdGVkQ2FsbGJhY2suICR7ZWwub3V0ZXJIVE1MfVxuICAgICAgYCk7XG4gICAgfVxuICAgIHRoaXMucHV0UHJpdmF0ZShlbCwgXCJjdXN0b20tZWwtaG9va1wiLCBob29rKTtcbiAgfSxcblxuICBnZXRDdXN0b21FbEhvb2soZWwpIHtcbiAgICByZXR1cm4gdGhpcy5wcml2YXRlKGVsLCBcImN1c3RvbS1lbC1ob29rXCIpO1xuICB9LFxuXG4gIGlzVXNlZElucHV0KGVsKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIGVsLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSAmJlxuICAgICAgKHRoaXMucHJpdmF0ZShlbCwgUEhYX0hBU19GT0NVU0VEKSB8fCB0aGlzLnByaXZhdGUoZWwsIFBIWF9IQVNfU1VCTUlUVEVEKSlcbiAgICApO1xuICB9LFxuXG4gIHJlc2V0Rm9ybShmb3JtKSB7XG4gICAgQXJyYXkuZnJvbShmb3JtLmVsZW1lbnRzKS5mb3JFYWNoKChpbnB1dCkgPT4ge1xuICAgICAgdGhpcy5kZWxldGVQcml2YXRlKGlucHV0LCBQSFhfSEFTX0ZPQ1VTRUQpO1xuICAgICAgdGhpcy5kZWxldGVQcml2YXRlKGlucHV0LCBQSFhfSEFTX1NVQk1JVFRFRCk7XG4gICAgfSk7XG4gIH0sXG5cbiAgaXNQaHhDaGlsZChub2RlKSB7XG4gICAgcmV0dXJuIG5vZGUuZ2V0QXR0cmlidXRlICYmIG5vZGUuZ2V0QXR0cmlidXRlKFBIWF9QQVJFTlRfSUQpO1xuICB9LFxuXG4gIGlzUGh4U3RpY2t5KG5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS5nZXRBdHRyaWJ1dGUgJiYgbm9kZS5nZXRBdHRyaWJ1dGUoUEhYX1NUSUNLWSkgIT09IG51bGw7XG4gIH0sXG5cbiAgaXNDaGlsZE9mQW55KGVsLCBwYXJlbnRzKSB7XG4gICAgcmV0dXJuICEhcGFyZW50cy5maW5kKChwYXJlbnQpID0+IHBhcmVudC5jb250YWlucyhlbCkpO1xuICB9LFxuXG4gIGZpcnN0UGh4Q2hpbGQoZWwpIHtcbiAgICByZXR1cm4gdGhpcy5pc1BoeENoaWxkKGVsKSA/IGVsIDogdGhpcy5hbGwoZWwsIGBbJHtQSFhfUEFSRU5UX0lEfV1gKVswXTtcbiAgfSxcblxuICBpc1BvcnRhbFRlbXBsYXRlKGVsKSB7XG4gICAgcmV0dXJuIGVsLnRhZ05hbWUgPT09IFwiVEVNUExBVEVcIiAmJiBlbC5oYXNBdHRyaWJ1dGUoUEhYX1BPUlRBTCk7XG4gIH0sXG5cbiAgY2xvc2VzdFZpZXdFbChlbCkge1xuICAgIC8vIGZpbmQgdGhlIGNsb3Nlc3QgcG9ydGFsIG9yIHZpZXcgZWxlbWVudCwgd2hpY2hldmVyIGNvbWVzIGZpcnN0XG4gICAgY29uc3QgcG9ydGFsT3JWaWV3RWwgPSBlbC5jbG9zZXN0KFxuICAgICAgYFske1BIWF9URUxFUE9SVEVEX1JFRn1dLCR7UEhYX1ZJRVdfU0VMRUNUT1J9YCxcbiAgICApO1xuICAgIGlmICghcG9ydGFsT3JWaWV3RWwpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAocG9ydGFsT3JWaWV3RWwuaGFzQXR0cmlidXRlKFBIWF9URUxFUE9SVEVEX1JFRikpIHtcbiAgICAgIC8vIFBIWF9URUxFUE9SVEVEX1JFRiBpcyBzZXQgdG8gdGhlIGlkIG9mIHRoZSB2aWV3IHRoYXQgb3ducyB0aGUgcG9ydGFsIGVsZW1lbnRcbiAgICAgIHJldHVybiB0aGlzLmJ5SWQocG9ydGFsT3JWaWV3RWwuZ2V0QXR0cmlidXRlKFBIWF9URUxFUE9SVEVEX1JFRikpO1xuICAgIH0gZWxzZSBpZiAocG9ydGFsT3JWaWV3RWwuaGFzQXR0cmlidXRlKFBIWF9TRVNTSU9OKSkge1xuICAgICAgcmV0dXJuIHBvcnRhbE9yVmlld0VsO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfSxcblxuICBkaXNwYXRjaEV2ZW50KHRhcmdldCwgbmFtZSwgb3B0cyA9IHt9KSB7XG4gICAgbGV0IGRlZmF1bHRCdWJibGUgPSB0cnVlO1xuICAgIGNvbnN0IGlzVXBsb2FkVGFyZ2V0ID1cbiAgICAgIHRhcmdldC5ub2RlTmFtZSA9PT0gXCJJTlBVVFwiICYmIHRhcmdldC50eXBlID09PSBcImZpbGVcIjtcbiAgICBpZiAoaXNVcGxvYWRUYXJnZXQgJiYgbmFtZSA9PT0gXCJjbGlja1wiKSB7XG4gICAgICBkZWZhdWx0QnViYmxlID0gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IGJ1YmJsZXMgPSBvcHRzLmJ1YmJsZXMgPT09IHVuZGVmaW5lZCA/IGRlZmF1bHRCdWJibGUgOiAhIW9wdHMuYnViYmxlcztcbiAgICBjb25zdCBldmVudE9wdHMgPSB7XG4gICAgICBidWJibGVzOiBidWJibGVzLFxuICAgICAgY2FuY2VsYWJsZTogdHJ1ZSxcbiAgICAgIGRldGFpbDogb3B0cy5kZXRhaWwgfHwge30sXG4gICAgfTtcbiAgICBjb25zdCBldmVudCA9XG4gICAgICBuYW1lID09PSBcImNsaWNrXCJcbiAgICAgICAgPyBuZXcgTW91c2VFdmVudChcImNsaWNrXCIsIGV2ZW50T3B0cylcbiAgICAgICAgOiBuZXcgQ3VzdG9tRXZlbnQobmFtZSwgZXZlbnRPcHRzKTtcbiAgICB0YXJnZXQuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gIH0sXG5cbiAgY2xvbmVOb2RlKG5vZGUsIGh0bWwpIHtcbiAgICBpZiAodHlwZW9mIGh0bWwgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgIHJldHVybiBub2RlLmNsb25lTm9kZSh0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgY2xvbmVkID0gbm9kZS5jbG9uZU5vZGUoZmFsc2UpO1xuICAgICAgY2xvbmVkLmlubmVySFRNTCA9IGh0bWw7XG4gICAgICByZXR1cm4gY2xvbmVkO1xuICAgIH1cbiAgfSxcblxuICAvLyBtZXJnZSBhdHRyaWJ1dGVzIGZyb20gc291cmNlIHRvIHRhcmdldFxuICAvLyBpZiBhbiBlbGVtZW50IGlzIGlnbm9yZWQsIHdlIG9ubHkgbWVyZ2UgZGF0YSBhdHRyaWJ1dGVzXG4gIC8vIGluY2x1ZGluZyByZW1vdmluZyBkYXRhIGF0dHJpYnV0ZXMgdGhhdCBhcmUgbm8gbG9uZ2VyIGluIHRoZSBzb3VyY2VcbiAgbWVyZ2VBdHRycyh0YXJnZXQsIHNvdXJjZSwgb3B0cyA9IHt9KSB7XG4gICAgY29uc3QgZXhjbHVkZSA9IG5ldyBTZXQob3B0cy5leGNsdWRlIHx8IFtdKTtcbiAgICBjb25zdCBpc0lnbm9yZWQgPSBvcHRzLmlzSWdub3JlZDtcbiAgICBjb25zdCBzb3VyY2VBdHRycyA9IHNvdXJjZS5hdHRyaWJ1dGVzO1xuICAgIGZvciAobGV0IGkgPSBzb3VyY2VBdHRycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgY29uc3QgbmFtZSA9IHNvdXJjZUF0dHJzW2ldLm5hbWU7XG4gICAgICBpZiAoIWV4Y2x1ZGUuaGFzKG5hbWUpKSB7XG4gICAgICAgIGNvbnN0IHNvdXJjZVZhbHVlID0gc291cmNlLmdldEF0dHJpYnV0ZShuYW1lKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRhcmdldC5nZXRBdHRyaWJ1dGUobmFtZSkgIT09IHNvdXJjZVZhbHVlICYmXG4gICAgICAgICAgKCFpc0lnbm9yZWQgfHwgKGlzSWdub3JlZCAmJiBuYW1lLnN0YXJ0c1dpdGgoXCJkYXRhLVwiKSkpXG4gICAgICAgICkge1xuICAgICAgICAgIHRhcmdldC5zZXRBdHRyaWJ1dGUobmFtZSwgc291cmNlVmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBXZSBleGNsdWRlIHRoZSB2YWx1ZSBmcm9tIGJlaW5nIG1lcmdlZCBvbiBmb2N1c2VkIGlucHV0cywgYmVjYXVzZSB0aGVcbiAgICAgICAgLy8gdXNlcidzIGlucHV0IHNob3VsZCBhbHdheXMgd2luLlxuICAgICAgICAvLyBXZSBjYW4gc3RpbGwgYXNzaWduIGl0IGFzIGxvbmcgYXMgdGhlIHZhbHVlIHByb3BlcnR5IGlzIHRoZSBzYW1lLCB0aG91Z2guXG4gICAgICAgIC8vIFRoaXMgcHJldmVudHMgYSBzaXR1YXRpb24gd2hlcmUgdGhlIHVwZGF0ZWQgaG9vayBpcyBub3QgYmVpbmcgdHJpZ2dlcmVkXG4gICAgICAgIC8vIHdoZW4gYW4gaW5wdXQgaXMgYmFjayBpbiBpdHMgXCJvcmlnaW5hbCBzdGF0ZVwiLCBiZWNhdXNlIHRoZSBhdHRyaWJ1dGVcbiAgICAgICAgLy8gd2FzIG5ldmVyIGNoYW5nZWQsIHNlZTpcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3Bob2VuaXhmcmFtZXdvcmsvcGhvZW5peF9saXZlX3ZpZXcvaXNzdWVzLzIxNjNcbiAgICAgICAgaWYgKG5hbWUgPT09IFwidmFsdWVcIikge1xuICAgICAgICAgIGNvbnN0IHNvdXJjZVZhbHVlID0gc291cmNlLnZhbHVlID8/IHNvdXJjZS5nZXRBdHRyaWJ1dGUobmFtZSk7XG4gICAgICAgICAgaWYgKHRhcmdldC52YWx1ZSA9PT0gc291cmNlVmFsdWUpIHtcbiAgICAgICAgICAgIC8vIGFjdHVhbGx5IHNldCB0aGUgdmFsdWUgYXR0cmlidXRlIHRvIHN5bmMgaXQgd2l0aCB0aGUgdmFsdWUgcHJvcGVydHlcbiAgICAgICAgICAgIHRhcmdldC5zZXRBdHRyaWJ1dGUoXCJ2YWx1ZVwiLCBzb3VyY2UuZ2V0QXR0cmlidXRlKG5hbWUpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB0YXJnZXRBdHRycyA9IHRhcmdldC5hdHRyaWJ1dGVzO1xuICAgIGZvciAobGV0IGkgPSB0YXJnZXRBdHRycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgY29uc3QgbmFtZSA9IHRhcmdldEF0dHJzW2ldLm5hbWU7XG4gICAgICBpZiAoaXNJZ25vcmVkKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBuYW1lLnN0YXJ0c1dpdGgoXCJkYXRhLVwiKSAmJlxuICAgICAgICAgICFzb3VyY2UuaGFzQXR0cmlidXRlKG5hbWUpICYmXG4gICAgICAgICAgIVBIWF9QRU5ESU5HX0FUVFJTLmluY2x1ZGVzKG5hbWUpXG4gICAgICAgICkge1xuICAgICAgICAgIHRhcmdldC5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICghc291cmNlLmhhc0F0dHJpYnV0ZShuYW1lKSkge1xuICAgICAgICAgIHRhcmdldC5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgbWVyZ2VGb2N1c2VkSW5wdXQodGFyZ2V0LCBzb3VyY2UpIHtcbiAgICAvLyBza2lwIHNlbGVjdHMgYmVjYXVzZSBGRiB3aWxsIHJlc2V0IGhpZ2hsaWdodGVkIGluZGV4IGZvciBhbnkgc2V0QXR0cmlidXRlXG4gICAgaWYgKCEodGFyZ2V0IGluc3RhbmNlb2YgSFRNTFNlbGVjdEVsZW1lbnQpKSB7XG4gICAgICBET00ubWVyZ2VBdHRycyh0YXJnZXQsIHNvdXJjZSwgeyBleGNsdWRlOiBbXCJ2YWx1ZVwiXSB9KTtcbiAgICB9XG5cbiAgICBpZiAoc291cmNlLnJlYWRPbmx5KSB7XG4gICAgICB0YXJnZXQuc2V0QXR0cmlidXRlKFwicmVhZG9ubHlcIiwgdHJ1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRhcmdldC5yZW1vdmVBdHRyaWJ1dGUoXCJyZWFkb25seVwiKTtcbiAgICB9XG4gIH0sXG5cbiAgaGFzU2VsZWN0aW9uUmFuZ2UoZWwpIHtcbiAgICByZXR1cm4gKFxuICAgICAgZWwuc2V0U2VsZWN0aW9uUmFuZ2UgJiYgKGVsLnR5cGUgPT09IFwidGV4dFwiIHx8IGVsLnR5cGUgPT09IFwidGV4dGFyZWFcIilcbiAgICApO1xuICB9LFxuXG4gIHJlc3RvcmVGb2N1cyhmb2N1c2VkLCBzZWxlY3Rpb25TdGFydCwgc2VsZWN0aW9uRW5kKSB7XG4gICAgaWYgKGZvY3VzZWQgaW5zdGFuY2VvZiBIVE1MU2VsZWN0RWxlbWVudCkge1xuICAgICAgZm9jdXNlZC5mb2N1cygpO1xuICAgIH1cbiAgICBpZiAoIURPTS5pc1RleHR1YWxJbnB1dChmb2N1c2VkKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHdhc0ZvY3VzZWQgPSBmb2N1c2VkLm1hdGNoZXMoXCI6Zm9jdXNcIik7XG4gICAgaWYgKCF3YXNGb2N1c2VkKSB7XG4gICAgICBmb2N1c2VkLmZvY3VzKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmhhc1NlbGVjdGlvblJhbmdlKGZvY3VzZWQpKSB7XG4gICAgICBmb2N1c2VkLnNldFNlbGVjdGlvblJhbmdlKHNlbGVjdGlvblN0YXJ0LCBzZWxlY3Rpb25FbmQpO1xuICAgIH1cbiAgfSxcblxuICBpc0Zvcm1JbnB1dChlbCkge1xuICAgIGlmIChlbC5sb2NhbE5hbWUgJiYgY3VzdG9tRWxlbWVudHMuZ2V0KGVsLmxvY2FsTmFtZSkpIHtcbiAgICAgIC8vIEN1c3RvbSBFbGVtZW50cyBtYXkgYmUgZm9ybSBhc3NvY2lhdGVkLiBUaGlzIGFsbG93cyB0aGVtXG4gICAgICAvLyB0byBwYXJ0aWNpcGF0ZSB3aXRoaW4gYSBmb3JtJ3MgbGlmZWN5Y2xlLCBpbmNsdWRpbmcgZm9ybVxuICAgICAgLy8gdmFsaWRpdHkgYW5kIGZvcm0gc3VibWlzc2lvbnMuXG4gICAgICAvLyBUaGUgc3BlYyBmb3IgRm9ybSBBc3NvY2lhdGVkIGN1c3RvbSBlbGVtZW50cyByZXF1aXJlcyB0aGVcbiAgICAgIC8vIGN1c3RvbSBlbGVtZW50J3MgY2xhc3MgdG8gY29udGFpbiBhIHN0YXRpYyBib29sZWFuIHZhbHVlIG9mIGBmb3JtQXNzb2NpYXRlZGBcbiAgICAgIC8vIHdoaWNoIGlkZW50aWZpZXMgdGhpcyBjbGFzcyBhcyBhbGxvd2VkIHRvIGFzc29jaWF0ZSB0byBhIGZvcm0uXG4gICAgICAvLyBTZWUgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9kZXYvY3VzdG9tLWVsZW1lbnRzLmh0bWwjY3VzdG9tLWVsZW1lbnRzLWZhY2UtZXhhbXBsZVxuICAgICAgLy8gZm9yIGRldGFpbHMuXG4gICAgICByZXR1cm4gY3VzdG9tRWxlbWVudHMuZ2V0KGVsLmxvY2FsTmFtZSlbYGZvcm1Bc3NvY2lhdGVkYF07XG4gICAgfVxuXG4gICAgcmV0dXJuIChcbiAgICAgIC9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhKSQvaS50ZXN0KGVsLnRhZ05hbWUpICYmIGVsLnR5cGUgIT09IFwiYnV0dG9uXCJcbiAgICApO1xuICB9LFxuXG4gIHN5bmNBdHRyc1RvUHJvcHMoZWwpIHtcbiAgICBpZiAoXG4gICAgICBlbCBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQgJiZcbiAgICAgIENIRUNLQUJMRV9JTlBVVFMuaW5kZXhPZihlbC50eXBlLnRvTG9jYWxlTG93ZXJDYXNlKCkpID49IDBcbiAgICApIHtcbiAgICAgIGVsLmNoZWNrZWQgPSBlbC5nZXRBdHRyaWJ1dGUoXCJjaGVja2VkXCIpICE9PSBudWxsO1xuICAgIH1cbiAgfSxcblxuICBpc1RleHR1YWxJbnB1dChlbCkge1xuICAgIHJldHVybiBGT0NVU0FCTEVfSU5QVVRTLmluZGV4T2YoZWwudHlwZSkgPj0gMDtcbiAgfSxcblxuICBpc05vd1RyaWdnZXJGb3JtRXh0ZXJuYWwoZWwsIHBoeFRyaWdnZXJFeHRlcm5hbCkge1xuICAgIHJldHVybiAoXG4gICAgICBlbC5nZXRBdHRyaWJ1dGUgJiZcbiAgICAgIGVsLmdldEF0dHJpYnV0ZShwaHhUcmlnZ2VyRXh0ZXJuYWwpICE9PSBudWxsICYmXG4gICAgICBkb2N1bWVudC5ib2R5LmNvbnRhaW5zKGVsKVxuICAgICk7XG4gIH0sXG5cbiAgY2xlYW5DaGlsZE5vZGVzKGNvbnRhaW5lciwgcGh4VXBkYXRlKSB7XG4gICAgaWYgKFxuICAgICAgRE9NLmlzUGh4VXBkYXRlKGNvbnRhaW5lciwgcGh4VXBkYXRlLCBbXCJhcHBlbmRcIiwgXCJwcmVwZW5kXCIsIFBIWF9TVFJFQU1dKVxuICAgICkge1xuICAgICAgY29uc3QgdG9SZW1vdmUgPSBbXTtcbiAgICAgIGNvbnRhaW5lci5jaGlsZE5vZGVzLmZvckVhY2goKGNoaWxkTm9kZSkgPT4ge1xuICAgICAgICBpZiAoIWNoaWxkTm9kZS5pZCkge1xuICAgICAgICAgIC8vIFNraXAgd2FybmluZyBpZiBpdCdzIGFuIGVtcHR5IHRleHQgbm9kZSAoZS5nLiBhIG5ldy1saW5lKVxuICAgICAgICAgIGNvbnN0IGlzRW1wdHlUZXh0Tm9kZSA9XG4gICAgICAgICAgICBjaGlsZE5vZGUubm9kZVR5cGUgPT09IE5vZGUuVEVYVF9OT0RFICYmXG4gICAgICAgICAgICBjaGlsZE5vZGUubm9kZVZhbHVlLnRyaW0oKSA9PT0gXCJcIjtcbiAgICAgICAgICBpZiAoIWlzRW1wdHlUZXh0Tm9kZSAmJiBjaGlsZE5vZGUubm9kZVR5cGUgIT09IE5vZGUuQ09NTUVOVF9OT0RFKSB7XG4gICAgICAgICAgICBsb2dFcnJvcihcbiAgICAgICAgICAgICAgXCJvbmx5IEhUTUwgZWxlbWVudCB0YWdzIHdpdGggYW4gaWQgYXJlIGFsbG93ZWQgaW5zaWRlIGNvbnRhaW5lcnMgd2l0aCBwaHgtdXBkYXRlLlxcblxcblwiICtcbiAgICAgICAgICAgICAgICBgcmVtb3ZpbmcgaWxsZWdhbCBub2RlOiBcIiR7KGNoaWxkTm9kZS5vdXRlckhUTUwgfHwgY2hpbGROb2RlLm5vZGVWYWx1ZSkudHJpbSgpfVwiXFxuXFxuYCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRvUmVtb3ZlLnB1c2goY2hpbGROb2RlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0b1JlbW92ZS5mb3JFYWNoKChjaGlsZE5vZGUpID0+IGNoaWxkTm9kZS5yZW1vdmUoKSk7XG4gICAgfVxuICB9LFxuXG4gIHJlcGxhY2VSb290Q29udGFpbmVyKGNvbnRhaW5lciwgdGFnTmFtZSwgYXR0cnMpIHtcbiAgICBjb25zdCByZXRhaW5lZEF0dHJzID0gbmV3IFNldChbXG4gICAgICBcImlkXCIsXG4gICAgICBQSFhfU0VTU0lPTixcbiAgICAgIFBIWF9TVEFUSUMsXG4gICAgICBQSFhfTUFJTixcbiAgICAgIFBIWF9ST09UX0lELFxuICAgIF0pO1xuICAgIGlmIChjb250YWluZXIudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSB0YWdOYW1lLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgIEFycmF5LmZyb20oY29udGFpbmVyLmF0dHJpYnV0ZXMpXG4gICAgICAgIC5maWx0ZXIoKGF0dHIpID0+ICFyZXRhaW5lZEF0dHJzLmhhcyhhdHRyLm5hbWUudG9Mb3dlckNhc2UoKSkpXG4gICAgICAgIC5mb3JFYWNoKChhdHRyKSA9PiBjb250YWluZXIucmVtb3ZlQXR0cmlidXRlKGF0dHIubmFtZSkpO1xuXG4gICAgICBPYmplY3Qua2V5cyhhdHRycylcbiAgICAgICAgLmZpbHRlcigobmFtZSkgPT4gIXJldGFpbmVkQXR0cnMuaGFzKG5hbWUudG9Mb3dlckNhc2UoKSkpXG4gICAgICAgIC5mb3JFYWNoKChhdHRyKSA9PiBjb250YWluZXIuc2V0QXR0cmlidXRlKGF0dHIsIGF0dHJzW2F0dHJdKSk7XG5cbiAgICAgIHJldHVybiBjb250YWluZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG5ld0NvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSk7XG4gICAgICBPYmplY3Qua2V5cyhhdHRycykuZm9yRWFjaCgoYXR0cikgPT5cbiAgICAgICAgbmV3Q29udGFpbmVyLnNldEF0dHJpYnV0ZShhdHRyLCBhdHRyc1thdHRyXSksXG4gICAgICApO1xuICAgICAgcmV0YWluZWRBdHRycy5mb3JFYWNoKChhdHRyKSA9PlxuICAgICAgICBuZXdDb250YWluZXIuc2V0QXR0cmlidXRlKGF0dHIsIGNvbnRhaW5lci5nZXRBdHRyaWJ1dGUoYXR0cikpLFxuICAgICAgKTtcbiAgICAgIG5ld0NvbnRhaW5lci5pbm5lckhUTUwgPSBjb250YWluZXIuaW5uZXJIVE1MO1xuICAgICAgY29udGFpbmVyLnJlcGxhY2VXaXRoKG5ld0NvbnRhaW5lcik7XG4gICAgICByZXR1cm4gbmV3Q29udGFpbmVyO1xuICAgIH1cbiAgfSxcblxuICBnZXRTdGlja3koZWwsIG5hbWUsIGRlZmF1bHRWYWwpIHtcbiAgICBjb25zdCBvcCA9IChET00ucHJpdmF0ZShlbCwgXCJzdGlja3lcIikgfHwgW10pLmZpbmQoXG4gICAgICAoW2V4aXN0aW5nTmFtZV0pID0+IG5hbWUgPT09IGV4aXN0aW5nTmFtZSxcbiAgICApO1xuICAgIGlmIChvcCkge1xuICAgICAgY29uc3QgW19uYW1lLCBfb3AsIHN0YXNoZWRSZXN1bHRdID0gb3A7XG4gICAgICByZXR1cm4gc3Rhc2hlZFJlc3VsdDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHR5cGVvZiBkZWZhdWx0VmFsID09PSBcImZ1bmN0aW9uXCIgPyBkZWZhdWx0VmFsKCkgOiBkZWZhdWx0VmFsO1xuICAgIH1cbiAgfSxcblxuICBkZWxldGVTdGlja3koZWwsIG5hbWUpIHtcbiAgICB0aGlzLnVwZGF0ZVByaXZhdGUoZWwsIFwic3RpY2t5XCIsIFtdLCAob3BzKSA9PiB7XG4gICAgICByZXR1cm4gb3BzLmZpbHRlcigoW2V4aXN0aW5nTmFtZSwgX10pID0+IGV4aXN0aW5nTmFtZSAhPT0gbmFtZSk7XG4gICAgfSk7XG4gIH0sXG5cbiAgcHV0U3RpY2t5KGVsLCBuYW1lLCBvcCkge1xuICAgIGNvbnN0IHN0YXNoZWRSZXN1bHQgPSBvcChlbCk7XG4gICAgdGhpcy51cGRhdGVQcml2YXRlKGVsLCBcInN0aWNreVwiLCBbXSwgKG9wcykgPT4ge1xuICAgICAgY29uc3QgZXhpc3RpbmdJbmRleCA9IG9wcy5maW5kSW5kZXgoXG4gICAgICAgIChbZXhpc3RpbmdOYW1lXSkgPT4gbmFtZSA9PT0gZXhpc3RpbmdOYW1lLFxuICAgICAgKTtcbiAgICAgIGlmIChleGlzdGluZ0luZGV4ID49IDApIHtcbiAgICAgICAgb3BzW2V4aXN0aW5nSW5kZXhdID0gW25hbWUsIG9wLCBzdGFzaGVkUmVzdWx0XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9wcy5wdXNoKFtuYW1lLCBvcCwgc3Rhc2hlZFJlc3VsdF0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9wcztcbiAgICB9KTtcbiAgfSxcblxuICBhcHBseVN0aWNreU9wZXJhdGlvbnMoZWwpIHtcbiAgICBjb25zdCBvcHMgPSBET00ucHJpdmF0ZShlbCwgXCJzdGlja3lcIik7XG4gICAgaWYgKCFvcHMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBvcHMuZm9yRWFjaCgoW25hbWUsIG9wLCBfc3Rhc2hlZF0pID0+IHRoaXMucHV0U3RpY2t5KGVsLCBuYW1lLCBvcCkpO1xuICB9LFxuXG4gIGlzTG9ja2VkKGVsKSB7XG4gICAgcmV0dXJuIGVsLmhhc0F0dHJpYnV0ZSAmJiBlbC5oYXNBdHRyaWJ1dGUoUEhYX1JFRl9MT0NLKTtcbiAgfSxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IERPTTtcbiIsICJpbXBvcnQge1xuICBQSFhfQUNUSVZFX0VOVFJZX1JFRlMsXG4gIFBIWF9MSVZFX0ZJTEVfVVBEQVRFRCxcbiAgUEhYX1BSRUZMSUdIVEVEX1JFRlMsXG59IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuXG5pbXBvcnQgeyBjaGFubmVsVXBsb2FkZXIsIGxvZ0Vycm9yIH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuaW1wb3J0IExpdmVVcGxvYWRlciBmcm9tIFwiLi9saXZlX3VwbG9hZGVyXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFVwbG9hZEVudHJ5IHtcbiAgc3RhdGljIGlzQWN0aXZlKGZpbGVFbCwgZmlsZSkge1xuICAgIGNvbnN0IGlzTmV3ID0gZmlsZS5fcGh4UmVmID09PSB1bmRlZmluZWQ7XG4gICAgY29uc3QgYWN0aXZlUmVmcyA9IGZpbGVFbC5nZXRBdHRyaWJ1dGUoUEhYX0FDVElWRV9FTlRSWV9SRUZTKS5zcGxpdChcIixcIik7XG4gICAgY29uc3QgaXNBY3RpdmUgPSBhY3RpdmVSZWZzLmluZGV4T2YoTGl2ZVVwbG9hZGVyLmdlbkZpbGVSZWYoZmlsZSkpID49IDA7XG4gICAgcmV0dXJuIGZpbGUuc2l6ZSA+IDAgJiYgKGlzTmV3IHx8IGlzQWN0aXZlKTtcbiAgfVxuXG4gIHN0YXRpYyBpc1ByZWZsaWdodGVkKGZpbGVFbCwgZmlsZSkge1xuICAgIGNvbnN0IHByZWZsaWdodGVkUmVmcyA9IGZpbGVFbFxuICAgICAgLmdldEF0dHJpYnV0ZShQSFhfUFJFRkxJR0hURURfUkVGUylcbiAgICAgIC5zcGxpdChcIixcIik7XG4gICAgY29uc3QgaXNQcmVmbGlnaHRlZCA9XG4gICAgICBwcmVmbGlnaHRlZFJlZnMuaW5kZXhPZihMaXZlVXBsb2FkZXIuZ2VuRmlsZVJlZihmaWxlKSkgPj0gMDtcbiAgICByZXR1cm4gaXNQcmVmbGlnaHRlZCAmJiB0aGlzLmlzQWN0aXZlKGZpbGVFbCwgZmlsZSk7XG4gIH1cblxuICBzdGF0aWMgaXNQcmVmbGlnaHRJblByb2dyZXNzKGZpbGUpIHtcbiAgICByZXR1cm4gZmlsZS5fcHJlZmxpZ2h0SW5Qcm9ncmVzcyA9PT0gdHJ1ZTtcbiAgfVxuXG4gIHN0YXRpYyBtYXJrUHJlZmxpZ2h0SW5Qcm9ncmVzcyhmaWxlKSB7XG4gICAgZmlsZS5fcHJlZmxpZ2h0SW5Qcm9ncmVzcyA9IHRydWU7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihmaWxlRWwsIGZpbGUsIHZpZXcsIGF1dG9VcGxvYWQpIHtcbiAgICB0aGlzLnJlZiA9IExpdmVVcGxvYWRlci5nZW5GaWxlUmVmKGZpbGUpO1xuICAgIHRoaXMuZmlsZUVsID0gZmlsZUVsO1xuICAgIHRoaXMuZmlsZSA9IGZpbGU7XG4gICAgdGhpcy52aWV3ID0gdmlldztcbiAgICB0aGlzLm1ldGEgPSBudWxsO1xuICAgIHRoaXMuX2lzQ2FuY2VsbGVkID0gZmFsc2U7XG4gICAgdGhpcy5faXNEb25lID0gZmFsc2U7XG4gICAgdGhpcy5fcHJvZ3Jlc3MgPSAwO1xuICAgIHRoaXMuX2xhc3RQcm9ncmVzc1NlbnQgPSAtMTtcbiAgICB0aGlzLl9vbkRvbmUgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICB0aGlzLl9vbkVsVXBkYXRlZCA9IHRoaXMub25FbFVwZGF0ZWQuYmluZCh0aGlzKTtcbiAgICB0aGlzLmZpbGVFbC5hZGRFdmVudExpc3RlbmVyKFBIWF9MSVZFX0ZJTEVfVVBEQVRFRCwgdGhpcy5fb25FbFVwZGF0ZWQpO1xuICAgIHRoaXMuYXV0b1VwbG9hZCA9IGF1dG9VcGxvYWQ7XG4gIH1cblxuICBtZXRhZGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy5tZXRhO1xuICB9XG5cbiAgcHJvZ3Jlc3MocHJvZ3Jlc3MpIHtcbiAgICB0aGlzLl9wcm9ncmVzcyA9IE1hdGguZmxvb3IocHJvZ3Jlc3MpO1xuICAgIGlmICh0aGlzLl9wcm9ncmVzcyA+IHRoaXMuX2xhc3RQcm9ncmVzc1NlbnQpIHtcbiAgICAgIGlmICh0aGlzLl9wcm9ncmVzcyA+PSAxMDApIHtcbiAgICAgICAgdGhpcy5fcHJvZ3Jlc3MgPSAxMDA7XG4gICAgICAgIHRoaXMuX2xhc3RQcm9ncmVzc1NlbnQgPSAxMDA7XG4gICAgICAgIHRoaXMuX2lzRG9uZSA9IHRydWU7XG4gICAgICAgIHRoaXMudmlldy5wdXNoRmlsZVByb2dyZXNzKHRoaXMuZmlsZUVsLCB0aGlzLnJlZiwgMTAwLCAoKSA9PiB7XG4gICAgICAgICAgTGl2ZVVwbG9hZGVyLnVudHJhY2tGaWxlKHRoaXMuZmlsZUVsLCB0aGlzLmZpbGUpO1xuICAgICAgICAgIHRoaXMuX29uRG9uZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2xhc3RQcm9ncmVzc1NlbnQgPSB0aGlzLl9wcm9ncmVzcztcbiAgICAgICAgdGhpcy52aWV3LnB1c2hGaWxlUHJvZ3Jlc3ModGhpcy5maWxlRWwsIHRoaXMucmVmLCB0aGlzLl9wcm9ncmVzcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaXNDYW5jZWxsZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2lzQ2FuY2VsbGVkO1xuICB9XG5cbiAgY2FuY2VsKCkge1xuICAgIHRoaXMuZmlsZS5fcHJlZmxpZ2h0SW5Qcm9ncmVzcyA9IGZhbHNlO1xuICAgIHRoaXMuX2lzQ2FuY2VsbGVkID0gdHJ1ZTtcbiAgICB0aGlzLl9pc0RvbmUgPSB0cnVlO1xuICAgIHRoaXMuX29uRG9uZSgpO1xuICB9XG5cbiAgaXNEb25lKCkge1xuICAgIHJldHVybiB0aGlzLl9pc0RvbmU7XG4gIH1cblxuICBlcnJvcihyZWFzb24gPSBcImZhaWxlZFwiKSB7XG4gICAgdGhpcy5maWxlRWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihQSFhfTElWRV9GSUxFX1VQREFURUQsIHRoaXMuX29uRWxVcGRhdGVkKTtcbiAgICB0aGlzLnZpZXcucHVzaEZpbGVQcm9ncmVzcyh0aGlzLmZpbGVFbCwgdGhpcy5yZWYsIHsgZXJyb3I6IHJlYXNvbiB9KTtcbiAgICBpZiAoIXRoaXMuaXNBdXRvVXBsb2FkKCkpIHtcbiAgICAgIExpdmVVcGxvYWRlci5jbGVhckZpbGVzKHRoaXMuZmlsZUVsKTtcbiAgICB9XG4gIH1cblxuICBpc0F1dG9VcGxvYWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuYXV0b1VwbG9hZDtcbiAgfVxuXG4gIC8vcHJpdmF0ZVxuXG4gIG9uRG9uZShjYWxsYmFjaykge1xuICAgIHRoaXMuX29uRG9uZSA9ICgpID0+IHtcbiAgICAgIHRoaXMuZmlsZUVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoUEhYX0xJVkVfRklMRV9VUERBVEVELCB0aGlzLl9vbkVsVXBkYXRlZCk7XG4gICAgICBjYWxsYmFjaygpO1xuICAgIH07XG4gIH1cblxuICBvbkVsVXBkYXRlZCgpIHtcbiAgICBjb25zdCBhY3RpdmVSZWZzID0gdGhpcy5maWxlRWxcbiAgICAgIC5nZXRBdHRyaWJ1dGUoUEhYX0FDVElWRV9FTlRSWV9SRUZTKVxuICAgICAgLnNwbGl0KFwiLFwiKTtcbiAgICBpZiAoYWN0aXZlUmVmcy5pbmRleE9mKHRoaXMucmVmKSA9PT0gLTEpIHtcbiAgICAgIExpdmVVcGxvYWRlci51bnRyYWNrRmlsZSh0aGlzLmZpbGVFbCwgdGhpcy5maWxlKTtcbiAgICAgIHRoaXMuY2FuY2VsKCk7XG4gICAgfVxuICB9XG5cbiAgdG9QcmVmbGlnaHRQYXlsb2FkKCkge1xuICAgIHJldHVybiB7XG4gICAgICBsYXN0X21vZGlmaWVkOiB0aGlzLmZpbGUubGFzdE1vZGlmaWVkLFxuICAgICAgbmFtZTogdGhpcy5maWxlLm5hbWUsXG4gICAgICByZWxhdGl2ZV9wYXRoOiB0aGlzLmZpbGUud2Via2l0UmVsYXRpdmVQYXRoLFxuICAgICAgc2l6ZTogdGhpcy5maWxlLnNpemUsXG4gICAgICB0eXBlOiB0aGlzLmZpbGUudHlwZSxcbiAgICAgIHJlZjogdGhpcy5yZWYsXG4gICAgICBtZXRhOiB0eXBlb2YgdGhpcy5maWxlLm1ldGEgPT09IFwiZnVuY3Rpb25cIiA/IHRoaXMuZmlsZS5tZXRhKCkgOiB1bmRlZmluZWQsXG4gICAgfTtcbiAgfVxuXG4gIHVwbG9hZGVyKHVwbG9hZGVycykge1xuICAgIGlmICh0aGlzLm1ldGEudXBsb2FkZXIpIHtcbiAgICAgIGNvbnN0IGNhbGxiYWNrID1cbiAgICAgICAgdXBsb2FkZXJzW3RoaXMubWV0YS51cGxvYWRlcl0gfHxcbiAgICAgICAgbG9nRXJyb3IoYG5vIHVwbG9hZGVyIGNvbmZpZ3VyZWQgZm9yICR7dGhpcy5tZXRhLnVwbG9hZGVyfWApO1xuICAgICAgcmV0dXJuIHsgbmFtZTogdGhpcy5tZXRhLnVwbG9hZGVyLCBjYWxsYmFjazogY2FsbGJhY2sgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHsgbmFtZTogXCJjaGFubmVsXCIsIGNhbGxiYWNrOiBjaGFubmVsVXBsb2FkZXIgfTtcbiAgICB9XG4gIH1cblxuICB6aXBQb3N0RmxpZ2h0KHJlc3ApIHtcbiAgICB0aGlzLm1ldGEgPSByZXNwLmVudHJpZXNbdGhpcy5yZWZdO1xuICAgIGlmICghdGhpcy5tZXRhKSB7XG4gICAgICBsb2dFcnJvcihgbm8gcHJlZmxpZ2h0IHVwbG9hZCByZXNwb25zZSByZXR1cm5lZCB3aXRoIHJlZiAke3RoaXMucmVmfWAsIHtcbiAgICAgICAgaW5wdXQ6IHRoaXMuZmlsZUVsLFxuICAgICAgICByZXNwb25zZTogcmVzcCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIFBIWF9ET05FX1JFRlMsXG4gIFBIWF9QUkVGTElHSFRFRF9SRUZTLFxuICBQSFhfVVBMT0FEX1JFRixcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cbmltcG9ydCB7fSBmcm9tIFwiLi91dGlsc1wiO1xuXG5pbXBvcnQgRE9NIGZyb20gXCIuL2RvbVwiO1xuaW1wb3J0IFVwbG9hZEVudHJ5IGZyb20gXCIuL3VwbG9hZF9lbnRyeVwiO1xuXG5sZXQgbGl2ZVVwbG9hZGVyRmlsZVJlZiA9IDA7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExpdmVVcGxvYWRlciB7XG4gIHN0YXRpYyBnZW5GaWxlUmVmKGZpbGUpIHtcbiAgICBjb25zdCByZWYgPSBmaWxlLl9waHhSZWY7XG4gICAgaWYgKHJlZiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gcmVmO1xuICAgIH0gZWxzZSB7XG4gICAgICBmaWxlLl9waHhSZWYgPSAobGl2ZVVwbG9hZGVyRmlsZVJlZisrKS50b1N0cmluZygpO1xuICAgICAgcmV0dXJuIGZpbGUuX3BoeFJlZjtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgZ2V0RW50cnlEYXRhVVJMKGlucHV0RWwsIHJlZiwgY2FsbGJhY2spIHtcbiAgICBjb25zdCBmaWxlID0gdGhpcy5hY3RpdmVGaWxlcyhpbnB1dEVsKS5maW5kKFxuICAgICAgKGZpbGUpID0+IHRoaXMuZ2VuRmlsZVJlZihmaWxlKSA9PT0gcmVmLFxuICAgICk7XG4gICAgY2FsbGJhY2soVVJMLmNyZWF0ZU9iamVjdFVSTChmaWxlKSk7XG4gIH1cblxuICBzdGF0aWMgaGFzVXBsb2Fkc0luUHJvZ3Jlc3MoZm9ybUVsKSB7XG4gICAgbGV0IGFjdGl2ZSA9IDA7XG4gICAgRE9NLmZpbmRVcGxvYWRJbnB1dHMoZm9ybUVsKS5mb3JFYWNoKChpbnB1dCkgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICBpbnB1dC5nZXRBdHRyaWJ1dGUoUEhYX1BSRUZMSUdIVEVEX1JFRlMpICE9PVxuICAgICAgICBpbnB1dC5nZXRBdHRyaWJ1dGUoUEhYX0RPTkVfUkVGUylcbiAgICAgICkge1xuICAgICAgICBhY3RpdmUrKztcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gYWN0aXZlID4gMDtcbiAgfVxuXG4gIHN0YXRpYyBzZXJpYWxpemVVcGxvYWRzKGlucHV0RWwpIHtcbiAgICBjb25zdCBmaWxlcyA9IHRoaXMuYWN0aXZlRmlsZXMoaW5wdXRFbCk7XG4gICAgY29uc3QgZmlsZURhdGEgPSB7fTtcbiAgICBmaWxlcy5mb3JFYWNoKChmaWxlKSA9PiB7XG4gICAgICBjb25zdCBlbnRyeSA9IHsgcGF0aDogaW5wdXRFbC5uYW1lIH07XG4gICAgICBjb25zdCB1cGxvYWRSZWYgPSBpbnB1dEVsLmdldEF0dHJpYnV0ZShQSFhfVVBMT0FEX1JFRik7XG4gICAgICBmaWxlRGF0YVt1cGxvYWRSZWZdID0gZmlsZURhdGFbdXBsb2FkUmVmXSB8fCBbXTtcbiAgICAgIGVudHJ5LnJlZiA9IHRoaXMuZ2VuRmlsZVJlZihmaWxlKTtcbiAgICAgIGVudHJ5Lmxhc3RfbW9kaWZpZWQgPSBmaWxlLmxhc3RNb2RpZmllZDtcbiAgICAgIGVudHJ5Lm5hbWUgPSBmaWxlLm5hbWUgfHwgZW50cnkucmVmO1xuICAgICAgZW50cnkucmVsYXRpdmVfcGF0aCA9IGZpbGUud2Via2l0UmVsYXRpdmVQYXRoO1xuICAgICAgZW50cnkudHlwZSA9IGZpbGUudHlwZTtcbiAgICAgIGVudHJ5LnNpemUgPSBmaWxlLnNpemU7XG4gICAgICBpZiAodHlwZW9mIGZpbGUubWV0YSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGVudHJ5Lm1ldGEgPSBmaWxlLm1ldGEoKTtcbiAgICAgIH1cbiAgICAgIGZpbGVEYXRhW3VwbG9hZFJlZl0ucHVzaChlbnRyeSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGZpbGVEYXRhO1xuICB9XG5cbiAgc3RhdGljIGNsZWFyRmlsZXMoaW5wdXRFbCkge1xuICAgIGlucHV0RWwudmFsdWUgPSBudWxsO1xuICAgIGlucHV0RWwucmVtb3ZlQXR0cmlidXRlKFBIWF9VUExPQURfUkVGKTtcbiAgICBET00ucHV0UHJpdmF0ZShpbnB1dEVsLCBcImZpbGVzXCIsIFtdKTtcbiAgfVxuXG4gIHN0YXRpYyB1bnRyYWNrRmlsZShpbnB1dEVsLCBmaWxlKSB7XG4gICAgRE9NLnB1dFByaXZhdGUoXG4gICAgICBpbnB1dEVsLFxuICAgICAgXCJmaWxlc1wiLFxuICAgICAgRE9NLnByaXZhdGUoaW5wdXRFbCwgXCJmaWxlc1wiKS5maWx0ZXIoKGYpID0+ICFPYmplY3QuaXMoZiwgZmlsZSkpLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtIVE1MSW5wdXRFbGVtZW50fSBpbnB1dEVsXG4gICAqIEBwYXJhbSB7QXJyYXk8RmlsZXxCbG9iPn0gZmlsZXNcbiAgICogQHBhcmFtIHtEYXRhVHJhbnNmZXJ9IFtkYXRhVHJhbnNmZXJdXG4gICAqL1xuICBzdGF0aWMgdHJhY2tGaWxlcyhpbnB1dEVsLCBmaWxlcywgZGF0YVRyYW5zZmVyKSB7XG4gICAgaWYgKGlucHV0RWwuZ2V0QXR0cmlidXRlKFwibXVsdGlwbGVcIikgIT09IG51bGwpIHtcbiAgICAgIGNvbnN0IG5ld0ZpbGVzID0gZmlsZXMuZmlsdGVyKFxuICAgICAgICAoZmlsZSkgPT4gIXRoaXMuYWN0aXZlRmlsZXMoaW5wdXRFbCkuZmluZCgoZikgPT4gT2JqZWN0LmlzKGYsIGZpbGUpKSxcbiAgICAgICk7XG4gICAgICBET00udXBkYXRlUHJpdmF0ZShpbnB1dEVsLCBcImZpbGVzXCIsIFtdLCAoZXhpc3RpbmcpID0+XG4gICAgICAgIGV4aXN0aW5nLmNvbmNhdChuZXdGaWxlcyksXG4gICAgICApO1xuICAgICAgaW5wdXRFbC52YWx1ZSA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFJlc2V0IGlucHV0RWwgZmlsZXMgdG8gYWxpZ24gb3V0cHV0IHdpdGggcHJvZ3JhbW1hdGljIGNoYW5nZXMgKGkuZS4gZHJhZyBhbmQgZHJvcClcbiAgICAgIGlmIChkYXRhVHJhbnNmZXIgJiYgZGF0YVRyYW5zZmVyLmZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgaW5wdXRFbC5maWxlcyA9IGRhdGFUcmFuc2Zlci5maWxlcztcbiAgICAgIH1cbiAgICAgIERPTS5wdXRQcml2YXRlKGlucHV0RWwsIFwiZmlsZXNcIiwgZmlsZXMpO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBhY3RpdmVGaWxlSW5wdXRzKGZvcm1FbCkge1xuICAgIGNvbnN0IGZpbGVJbnB1dHMgPSBET00uZmluZFVwbG9hZElucHV0cyhmb3JtRWwpO1xuICAgIHJldHVybiBBcnJheS5mcm9tKGZpbGVJbnB1dHMpLmZpbHRlcihcbiAgICAgIChlbCkgPT4gZWwuZmlsZXMgJiYgdGhpcy5hY3RpdmVGaWxlcyhlbCkubGVuZ3RoID4gMCxcbiAgICApO1xuICB9XG5cbiAgc3RhdGljIGFjdGl2ZUZpbGVzKGlucHV0KSB7XG4gICAgcmV0dXJuIChET00ucHJpdmF0ZShpbnB1dCwgXCJmaWxlc1wiKSB8fCBbXSkuZmlsdGVyKChmKSA9PlxuICAgICAgVXBsb2FkRW50cnkuaXNBY3RpdmUoaW5wdXQsIGYpLFxuICAgICk7XG4gIH1cblxuICBzdGF0aWMgaW5wdXRzQXdhaXRpbmdQcmVmbGlnaHQoZm9ybUVsKSB7XG4gICAgY29uc3QgZmlsZUlucHV0cyA9IERPTS5maW5kVXBsb2FkSW5wdXRzKGZvcm1FbCk7XG4gICAgcmV0dXJuIEFycmF5LmZyb20oZmlsZUlucHV0cykuZmlsdGVyKFxuICAgICAgKGlucHV0KSA9PiB0aGlzLmZpbGVzQXdhaXRpbmdQcmVmbGlnaHQoaW5wdXQpLmxlbmd0aCA+IDAsXG4gICAgKTtcbiAgfVxuXG4gIHN0YXRpYyBmaWxlc0F3YWl0aW5nUHJlZmxpZ2h0KGlucHV0KSB7XG4gICAgcmV0dXJuIHRoaXMuYWN0aXZlRmlsZXMoaW5wdXQpLmZpbHRlcihcbiAgICAgIChmKSA9PlxuICAgICAgICAhVXBsb2FkRW50cnkuaXNQcmVmbGlnaHRlZChpbnB1dCwgZikgJiZcbiAgICAgICAgIVVwbG9hZEVudHJ5LmlzUHJlZmxpZ2h0SW5Qcm9ncmVzcyhmKSxcbiAgICApO1xuICB9XG5cbiAgc3RhdGljIG1hcmtQcmVmbGlnaHRJblByb2dyZXNzKGVudHJpZXMpIHtcbiAgICBlbnRyaWVzLmZvckVhY2goKGVudHJ5KSA9PiBVcGxvYWRFbnRyeS5tYXJrUHJlZmxpZ2h0SW5Qcm9ncmVzcyhlbnRyeS5maWxlKSk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihpbnB1dEVsLCB2aWV3LCBvbkNvbXBsZXRlKSB7XG4gICAgdGhpcy5hdXRvVXBsb2FkID0gRE9NLmlzQXV0b1VwbG9hZChpbnB1dEVsKTtcbiAgICB0aGlzLnZpZXcgPSB2aWV3O1xuICAgIHRoaXMub25Db21wbGV0ZSA9IG9uQ29tcGxldGU7XG4gICAgdGhpcy5fZW50cmllcyA9IEFycmF5LmZyb20oXG4gICAgICBMaXZlVXBsb2FkZXIuZmlsZXNBd2FpdGluZ1ByZWZsaWdodChpbnB1dEVsKSB8fCBbXSxcbiAgICApLm1hcCgoZmlsZSkgPT4gbmV3IFVwbG9hZEVudHJ5KGlucHV0RWwsIGZpbGUsIHZpZXcsIHRoaXMuYXV0b1VwbG9hZCkpO1xuXG4gICAgLy8gcHJldmVudCBzZW5kaW5nIGR1cGxpY2F0ZSBwcmVmbGlnaHQgcmVxdWVzdHNcbiAgICBMaXZlVXBsb2FkZXIubWFya1ByZWZsaWdodEluUHJvZ3Jlc3ModGhpcy5fZW50cmllcyk7XG5cbiAgICB0aGlzLm51bUVudHJpZXNJblByb2dyZXNzID0gdGhpcy5fZW50cmllcy5sZW5ndGg7XG4gIH1cblxuICBpc0F1dG9VcGxvYWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuYXV0b1VwbG9hZDtcbiAgfVxuXG4gIGVudHJpZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2VudHJpZXM7XG4gIH1cblxuICBpbml0QWRhcHRlclVwbG9hZChyZXNwLCBvbkVycm9yLCBsaXZlU29ja2V0KSB7XG4gICAgdGhpcy5fZW50cmllcyA9IHRoaXMuX2VudHJpZXMubWFwKChlbnRyeSkgPT4ge1xuICAgICAgaWYgKGVudHJ5LmlzQ2FuY2VsbGVkKCkpIHtcbiAgICAgICAgdGhpcy5udW1FbnRyaWVzSW5Qcm9ncmVzcy0tO1xuICAgICAgICBpZiAodGhpcy5udW1FbnRyaWVzSW5Qcm9ncmVzcyA9PT0gMCkge1xuICAgICAgICAgIHRoaXMub25Db21wbGV0ZSgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbnRyeS56aXBQb3N0RmxpZ2h0KHJlc3ApO1xuICAgICAgICBlbnRyeS5vbkRvbmUoKCkgPT4ge1xuICAgICAgICAgIHRoaXMubnVtRW50cmllc0luUHJvZ3Jlc3MtLTtcbiAgICAgICAgICBpZiAodGhpcy5udW1FbnRyaWVzSW5Qcm9ncmVzcyA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5vbkNvbXBsZXRlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBlbnRyeTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGdyb3VwZWRFbnRyaWVzID0gdGhpcy5fZW50cmllcy5yZWR1Y2UoKGFjYywgZW50cnkpID0+IHtcbiAgICAgIGlmICghZW50cnkubWV0YSkge1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfVxuICAgICAgY29uc3QgeyBuYW1lLCBjYWxsYmFjayB9ID0gZW50cnkudXBsb2FkZXIobGl2ZVNvY2tldC51cGxvYWRlcnMpO1xuICAgICAgYWNjW25hbWVdID0gYWNjW25hbWVdIHx8IHsgY2FsbGJhY2s6IGNhbGxiYWNrLCBlbnRyaWVzOiBbXSB9O1xuICAgICAgYWNjW25hbWVdLmVudHJpZXMucHVzaChlbnRyeSk7XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHt9KTtcblxuICAgIGZvciAoY29uc3QgbmFtZSBpbiBncm91cGVkRW50cmllcykge1xuICAgICAgY29uc3QgeyBjYWxsYmFjaywgZW50cmllcyB9ID0gZ3JvdXBlZEVudHJpZXNbbmFtZV07XG4gICAgICBjYWxsYmFjayhlbnRyaWVzLCBvbkVycm9yLCByZXNwLCBsaXZlU29ja2V0KTtcbiAgICB9XG4gIH1cbn1cbiIsICJjb25zdCBBUklBID0ge1xuICBhbnlPZihpbnN0YW5jZSwgY2xhc3Nlcykge1xuICAgIHJldHVybiBjbGFzc2VzLmZpbmQoKG5hbWUpID0+IGluc3RhbmNlIGluc3RhbmNlb2YgbmFtZSk7XG4gIH0sXG5cbiAgaXNGb2N1c2FibGUoZWwsIGludGVyYWN0aXZlT25seSkge1xuICAgIHJldHVybiAoXG4gICAgICAoZWwgaW5zdGFuY2VvZiBIVE1MQW5jaG9yRWxlbWVudCAmJiBlbC5yZWwgIT09IFwiaWdub3JlXCIpIHx8XG4gICAgICAoZWwgaW5zdGFuY2VvZiBIVE1MQXJlYUVsZW1lbnQgJiYgZWwuaHJlZiAhPT0gdW5kZWZpbmVkKSB8fFxuICAgICAgKCFlbC5kaXNhYmxlZCAmJlxuICAgICAgICB0aGlzLmFueU9mKGVsLCBbXG4gICAgICAgICAgSFRNTElucHV0RWxlbWVudCxcbiAgICAgICAgICBIVE1MU2VsZWN0RWxlbWVudCxcbiAgICAgICAgICBIVE1MVGV4dEFyZWFFbGVtZW50LFxuICAgICAgICAgIEhUTUxCdXR0b25FbGVtZW50LFxuICAgICAgICBdKSkgfHxcbiAgICAgIGVsIGluc3RhbmNlb2YgSFRNTElGcmFtZUVsZW1lbnQgfHxcbiAgICAgIChlbC50YWJJbmRleCA+PSAwICYmIGVsLmdldEF0dHJpYnV0ZShcImFyaWEtaGlkZGVuXCIpICE9PSBcInRydWVcIikgfHxcbiAgICAgICghaW50ZXJhY3RpdmVPbmx5ICYmXG4gICAgICAgIGVsLmdldEF0dHJpYnV0ZShcInRhYmluZGV4XCIpICE9PSBudWxsICYmXG4gICAgICAgIGVsLmdldEF0dHJpYnV0ZShcImFyaWEtaGlkZGVuXCIpICE9PSBcInRydWVcIilcbiAgICApO1xuICB9LFxuXG4gIGF0dGVtcHRGb2N1cyhlbCwgaW50ZXJhY3RpdmVPbmx5KSB7XG4gICAgaWYgKHRoaXMuaXNGb2N1c2FibGUoZWwsIGludGVyYWN0aXZlT25seSkpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGVsLmZvY3VzKCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gdGhhdCdzIGZpbmVcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuICEhZG9jdW1lbnQuYWN0aXZlRWxlbWVudCAmJiBkb2N1bWVudC5hY3RpdmVFbGVtZW50LmlzU2FtZU5vZGUoZWwpO1xuICB9LFxuXG4gIGZvY3VzRmlyc3RJbnRlcmFjdGl2ZShlbCkge1xuICAgIGxldCBjaGlsZCA9IGVsLmZpcnN0RWxlbWVudENoaWxkO1xuICAgIHdoaWxlIChjaGlsZCkge1xuICAgICAgaWYgKHRoaXMuYXR0ZW1wdEZvY3VzKGNoaWxkLCB0cnVlKSB8fCB0aGlzLmZvY3VzRmlyc3RJbnRlcmFjdGl2ZShjaGlsZCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBjaGlsZCA9IGNoaWxkLm5leHRFbGVtZW50U2libGluZztcbiAgICB9XG4gIH0sXG5cbiAgZm9jdXNGaXJzdChlbCkge1xuICAgIGxldCBjaGlsZCA9IGVsLmZpcnN0RWxlbWVudENoaWxkO1xuICAgIHdoaWxlIChjaGlsZCkge1xuICAgICAgaWYgKHRoaXMuYXR0ZW1wdEZvY3VzKGNoaWxkKSB8fCB0aGlzLmZvY3VzRmlyc3QoY2hpbGQpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgY2hpbGQgPSBjaGlsZC5uZXh0RWxlbWVudFNpYmxpbmc7XG4gICAgfVxuICB9LFxuXG4gIGZvY3VzTGFzdChlbCkge1xuICAgIGxldCBjaGlsZCA9IGVsLmxhc3RFbGVtZW50Q2hpbGQ7XG4gICAgd2hpbGUgKGNoaWxkKSB7XG4gICAgICBpZiAodGhpcy5hdHRlbXB0Rm9jdXMoY2hpbGQpIHx8IHRoaXMuZm9jdXNMYXN0KGNoaWxkKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGNoaWxkID0gY2hpbGQucHJldmlvdXNFbGVtZW50U2libGluZztcbiAgICB9XG4gIH0sXG59O1xuZXhwb3J0IGRlZmF1bHQgQVJJQTtcbiIsICJpbXBvcnQge1xuICBQSFhfQUNUSVZFX0VOVFJZX1JFRlMsXG4gIFBIWF9MSVZFX0ZJTEVfVVBEQVRFRCxcbiAgUEhYX1BSRUZMSUdIVEVEX1JFRlMsXG4gIFBIWF9VUExPQURfUkVGLFxufSBmcm9tIFwiLi9jb25zdGFudHNcIjtcblxuaW1wb3J0IExpdmVVcGxvYWRlciBmcm9tIFwiLi9saXZlX3VwbG9hZGVyXCI7XG5pbXBvcnQgQVJJQSBmcm9tIFwiLi9hcmlhXCI7XG5cbmNvbnN0IEhvb2tzID0ge1xuICBMaXZlRmlsZVVwbG9hZDoge1xuICAgIGFjdGl2ZVJlZnMoKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbC5nZXRBdHRyaWJ1dGUoUEhYX0FDVElWRV9FTlRSWV9SRUZTKTtcbiAgICB9LFxuXG4gICAgcHJlZmxpZ2h0ZWRSZWZzKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZWwuZ2V0QXR0cmlidXRlKFBIWF9QUkVGTElHSFRFRF9SRUZTKTtcbiAgICB9LFxuXG4gICAgbW91bnRlZCgpIHtcbiAgICAgIHRoaXMucHJlZmxpZ2h0ZWRXYXMgPSB0aGlzLnByZWZsaWdodGVkUmVmcygpO1xuICAgIH0sXG5cbiAgICB1cGRhdGVkKCkge1xuICAgICAgY29uc3QgbmV3UHJlZmxpZ2h0cyA9IHRoaXMucHJlZmxpZ2h0ZWRSZWZzKCk7XG4gICAgICBpZiAodGhpcy5wcmVmbGlnaHRlZFdhcyAhPT0gbmV3UHJlZmxpZ2h0cykge1xuICAgICAgICB0aGlzLnByZWZsaWdodGVkV2FzID0gbmV3UHJlZmxpZ2h0cztcbiAgICAgICAgaWYgKG5ld1ByZWZsaWdodHMgPT09IFwiXCIpIHtcbiAgICAgICAgICB0aGlzLl9fdmlldygpLmNhbmNlbFN1Ym1pdCh0aGlzLmVsLmZvcm0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmFjdGl2ZVJlZnMoKSA9PT0gXCJcIikge1xuICAgICAgICB0aGlzLmVsLnZhbHVlID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIHRoaXMuZWwuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoUEhYX0xJVkVfRklMRV9VUERBVEVEKSk7XG4gICAgfSxcbiAgfSxcblxuICBMaXZlSW1nUHJldmlldzoge1xuICAgIG1vdW50ZWQoKSB7XG4gICAgICB0aGlzLnJlZiA9IHRoaXMuZWwuZ2V0QXR0cmlidXRlKFwiZGF0YS1waHgtZW50cnktcmVmXCIpO1xuICAgICAgdGhpcy5pbnB1dEVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXG4gICAgICAgIHRoaXMuZWwuZ2V0QXR0cmlidXRlKFBIWF9VUExPQURfUkVGKSxcbiAgICAgICk7XG4gICAgICBMaXZlVXBsb2FkZXIuZ2V0RW50cnlEYXRhVVJMKHRoaXMuaW5wdXRFbCwgdGhpcy5yZWYsICh1cmwpID0+IHtcbiAgICAgICAgdGhpcy51cmwgPSB1cmw7XG4gICAgICAgIHRoaXMuZWwuc3JjID0gdXJsO1xuICAgICAgfSk7XG4gICAgfSxcbiAgICBkZXN0cm95ZWQoKSB7XG4gICAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHRoaXMudXJsKTtcbiAgICB9LFxuICB9LFxuICBGb2N1c1dyYXA6IHtcbiAgICBtb3VudGVkKCkge1xuICAgICAgdGhpcy5mb2N1c1N0YXJ0ID0gdGhpcy5lbC5maXJzdEVsZW1lbnRDaGlsZDtcbiAgICAgIHRoaXMuZm9jdXNFbmQgPSB0aGlzLmVsLmxhc3RFbGVtZW50Q2hpbGQ7XG4gICAgICB0aGlzLmZvY3VzU3RhcnQuYWRkRXZlbnRMaXN0ZW5lcihcImZvY3VzXCIsIChlKSA9PiB7XG4gICAgICAgIGlmICghZS5yZWxhdGVkVGFyZ2V0IHx8ICF0aGlzLmVsLmNvbnRhaW5zKGUucmVsYXRlZFRhcmdldCkpIHtcbiAgICAgICAgICAvLyBIYW5kbGUgZm9jdXMgZW50ZXJpbmcgZnJvbSBvdXRzaWRlIChlLmcuIFRhYiB3aGVuIGJvZHkgaXMgZm9jdXNlZClcbiAgICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vcGhvZW5peGZyYW1ld29yay9waG9lbml4X2xpdmVfdmlldy9pc3N1ZXMvMzYzNlxuICAgICAgICAgIGNvbnN0IG5leHRGb2N1cyA9IGUudGFyZ2V0Lm5leHRFbGVtZW50U2libGluZztcbiAgICAgICAgICBBUklBLmF0dGVtcHRGb2N1cyhuZXh0Rm9jdXMpIHx8IEFSSUEuZm9jdXNGaXJzdChuZXh0Rm9jdXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIEFSSUEuZm9jdXNMYXN0KHRoaXMuZWwpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuZm9jdXNFbmQuYWRkRXZlbnRMaXN0ZW5lcihcImZvY3VzXCIsIChlKSA9PiB7XG4gICAgICAgIGlmICghZS5yZWxhdGVkVGFyZ2V0IHx8ICF0aGlzLmVsLmNvbnRhaW5zKGUucmVsYXRlZFRhcmdldCkpIHtcbiAgICAgICAgICAvLyBIYW5kbGUgZm9jdXMgZW50ZXJpbmcgZnJvbSBvdXRzaWRlIChlLmcuIFNoaWZ0K1RhYiB3aGVuIGJvZHkgaXMgZm9jdXNlZClcbiAgICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vcGhvZW5peGZyYW1ld29yay9waG9lbml4X2xpdmVfdmlldy9pc3N1ZXMvMzYzNlxuICAgICAgICAgIGNvbnN0IG5leHRGb2N1cyA9IGUudGFyZ2V0LnByZXZpb3VzRWxlbWVudFNpYmxpbmc7XG4gICAgICAgICAgQVJJQS5hdHRlbXB0Rm9jdXMobmV4dEZvY3VzKSB8fCBBUklBLmZvY3VzTGFzdChuZXh0Rm9jdXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIEFSSUEuZm9jdXNGaXJzdCh0aGlzLmVsKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICAvLyBvbmx5IHRyeSB0byBjaGFuZ2UgdGhlIGZvY3VzIGlmIGl0IGlzIG5vdCBhbHJlYWR5IGluc2lkZVxuICAgICAgaWYgKCF0aGlzLmVsLmNvbnRhaW5zKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpKSB7XG4gICAgICAgIHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcihcInBoeDpzaG93LWVuZFwiLCAoKSA9PiB0aGlzLmVsLmZvY3VzKCkpO1xuICAgICAgICBpZiAod2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5lbCkuZGlzcGxheSAhPT0gXCJub25lXCIpIHtcbiAgICAgICAgICBBUklBLmZvY3VzRmlyc3QodGhpcy5lbCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICB9LFxufTtcblxuY29uc3QgZmluZFNjcm9sbENvbnRhaW5lciA9IChlbCkgPT4ge1xuICAvLyB0aGUgc2Nyb2xsIGV2ZW50IHdvbid0IGJlIGZpcmVkIG9uIHRoZSBodG1sL2JvZHkgZWxlbWVudCBldmVuIGlmIG92ZXJmbG93IGlzIHNldFxuICAvLyB0aGVyZWZvcmUgd2UgcmV0dXJuIG51bGwgdG8gaW5zdGVhZCBsaXN0ZW4gZm9yIHNjcm9sbCBldmVudHMgb24gZG9jdW1lbnRcbiAgaWYgKFtcIkhUTUxcIiwgXCJCT0RZXCJdLmluZGV4T2YoZWwubm9kZU5hbWUudG9VcHBlckNhc2UoKSkgPj0gMCkgcmV0dXJuIG51bGw7XG4gIGlmIChbXCJzY3JvbGxcIiwgXCJhdXRvXCJdLmluZGV4T2YoZ2V0Q29tcHV0ZWRTdHlsZShlbCkub3ZlcmZsb3dZKSA+PSAwKVxuICAgIHJldHVybiBlbDtcbiAgcmV0dXJuIGZpbmRTY3JvbGxDb250YWluZXIoZWwucGFyZW50RWxlbWVudCk7XG59O1xuXG5jb25zdCBzY3JvbGxUb3AgPSAoc2Nyb2xsQ29udGFpbmVyKSA9PiB7XG4gIGlmIChzY3JvbGxDb250YWluZXIpIHtcbiAgICByZXR1cm4gc2Nyb2xsQ29udGFpbmVyLnNjcm9sbFRvcDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCB8fCBkb2N1bWVudC5ib2R5LnNjcm9sbFRvcDtcbiAgfVxufTtcblxuY29uc3QgYm90dG9tID0gKHNjcm9sbENvbnRhaW5lcikgPT4ge1xuICBpZiAoc2Nyb2xsQ29udGFpbmVyKSB7XG4gICAgcmV0dXJuIHNjcm9sbENvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5ib3R0b207XG4gIH0gZWxzZSB7XG4gICAgLy8gd2hlbiB3ZSBoYXZlIG5vIGNvbnRhaW5lciwgdGhlIHdob2xlIHBhZ2Ugc2Nyb2xscyxcbiAgICAvLyB0aGVyZWZvcmUgdGhlIGJvdHRvbSBjb29yZGluYXRlIGlzIHRoZSB2aWV3cG9ydCBoZWlnaHRcbiAgICByZXR1cm4gd2luZG93LmlubmVySGVpZ2h0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQ7XG4gIH1cbn07XG5cbmNvbnN0IHRvcCA9IChzY3JvbGxDb250YWluZXIpID0+IHtcbiAgaWYgKHNjcm9sbENvbnRhaW5lcikge1xuICAgIHJldHVybiBzY3JvbGxDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wO1xuICB9IGVsc2Uge1xuICAgIC8vIHdoZW4gd2UgaGF2ZSBubyBjb250YWluZXIgdGhlIHdob2xlIHBhZ2Ugc2Nyb2xscyxcbiAgICAvLyB0aGVyZWZvcmUgdGhlIHRvcCBjb29yZGluYXRlIGlzIDBcbiAgICByZXR1cm4gMDtcbiAgfVxufTtcblxuY29uc3QgaXNBdFZpZXdwb3J0VG9wID0gKGVsLCBzY3JvbGxDb250YWluZXIpID0+IHtcbiAgY29uc3QgcmVjdCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICByZXR1cm4gKFxuICAgIE1hdGguY2VpbChyZWN0LnRvcCkgPj0gdG9wKHNjcm9sbENvbnRhaW5lcikgJiZcbiAgICBNYXRoLmNlaWwocmVjdC5sZWZ0KSA+PSAwICYmXG4gICAgTWF0aC5mbG9vcihyZWN0LnRvcCkgPD0gYm90dG9tKHNjcm9sbENvbnRhaW5lcilcbiAgKTtcbn07XG5cbmNvbnN0IGlzQXRWaWV3cG9ydEJvdHRvbSA9IChlbCwgc2Nyb2xsQ29udGFpbmVyKSA9PiB7XG4gIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgcmV0dXJuIChcbiAgICBNYXRoLmNlaWwocmVjdC5ib3R0b20pID49IHRvcChzY3JvbGxDb250YWluZXIpICYmXG4gICAgTWF0aC5jZWlsKHJlY3QubGVmdCkgPj0gMCAmJlxuICAgIE1hdGguZmxvb3IocmVjdC5ib3R0b20pIDw9IGJvdHRvbShzY3JvbGxDb250YWluZXIpXG4gICk7XG59O1xuXG5jb25zdCBpc1dpdGhpblZpZXdwb3J0ID0gKGVsLCBzY3JvbGxDb250YWluZXIpID0+IHtcbiAgY29uc3QgcmVjdCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICByZXR1cm4gKFxuICAgIE1hdGguY2VpbChyZWN0LnRvcCkgPj0gdG9wKHNjcm9sbENvbnRhaW5lcikgJiZcbiAgICBNYXRoLmNlaWwocmVjdC5sZWZ0KSA+PSAwICYmXG4gICAgTWF0aC5mbG9vcihyZWN0LnRvcCkgPD0gYm90dG9tKHNjcm9sbENvbnRhaW5lcilcbiAgKTtcbn07XG5cbkhvb2tzLkluZmluaXRlU2Nyb2xsID0ge1xuICBtb3VudGVkKCkge1xuICAgIHRoaXMuc2Nyb2xsQ29udGFpbmVyID0gZmluZFNjcm9sbENvbnRhaW5lcih0aGlzLmVsKTtcbiAgICBsZXQgc2Nyb2xsQmVmb3JlID0gc2Nyb2xsVG9wKHRoaXMuc2Nyb2xsQ29udGFpbmVyKTtcbiAgICBsZXQgdG9wT3ZlcnJhbiA9IGZhbHNlO1xuICAgIGNvbnN0IHRocm90dGxlSW50ZXJ2YWwgPSA1MDA7XG4gICAgbGV0IHBlbmRpbmdPcCA9IG51bGw7XG5cbiAgICBjb25zdCBvblRvcE92ZXJydW4gPSB0aGlzLnRocm90dGxlKFxuICAgICAgdGhyb3R0bGVJbnRlcnZhbCxcbiAgICAgICh0b3BFdmVudCwgZmlyc3RDaGlsZCkgPT4ge1xuICAgICAgICBwZW5kaW5nT3AgPSAoKSA9PiB0cnVlO1xuICAgICAgICB0aGlzLmxpdmVTb2NrZXQuanMoKS5wdXNoKHRoaXMuZWwsIHRvcEV2ZW50LCB7XG4gICAgICAgICAgdmFsdWU6IHsgaWQ6IGZpcnN0Q2hpbGQuaWQsIF9vdmVycmFuOiB0cnVlIH0sXG4gICAgICAgICAgY2FsbGJhY2s6ICgpID0+IHtcbiAgICAgICAgICAgIHBlbmRpbmdPcCA9IG51bGw7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICk7XG5cbiAgICBjb25zdCBvbkZpcnN0Q2hpbGRBdFRvcCA9IHRoaXMudGhyb3R0bGUoXG4gICAgICB0aHJvdHRsZUludGVydmFsLFxuICAgICAgKHRvcEV2ZW50LCBmaXJzdENoaWxkKSA9PiB7XG4gICAgICAgIHBlbmRpbmdPcCA9ICgpID0+IGZpcnN0Q2hpbGQuc2Nyb2xsSW50b1ZpZXcoeyBibG9jazogXCJzdGFydFwiIH0pO1xuICAgICAgICB0aGlzLmxpdmVTb2NrZXQuanMoKS5wdXNoKHRoaXMuZWwsIHRvcEV2ZW50LCB7XG4gICAgICAgICAgdmFsdWU6IHsgaWQ6IGZpcnN0Q2hpbGQuaWQgfSxcbiAgICAgICAgICBjYWxsYmFjazogKCkgPT4ge1xuICAgICAgICAgICAgcGVuZGluZ09wID0gbnVsbDtcbiAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGF0IHRoZSBET00gaXMgcGF0Y2hlZCBieSB3YWl0aW5nIGZvciB0aGUgbmV4dCB0aWNrXG4gICAgICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFpc1dpdGhpblZpZXdwb3J0KGZpcnN0Q2hpbGQsIHRoaXMuc2Nyb2xsQ29udGFpbmVyKSkge1xuICAgICAgICAgICAgICAgIGZpcnN0Q2hpbGQuc2Nyb2xsSW50b1ZpZXcoeyBibG9jazogXCJzdGFydFwiIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIGNvbnN0IG9uTGFzdENoaWxkQXRCb3R0b20gPSB0aGlzLnRocm90dGxlKFxuICAgICAgdGhyb3R0bGVJbnRlcnZhbCxcbiAgICAgIChib3R0b21FdmVudCwgbGFzdENoaWxkKSA9PiB7XG4gICAgICAgIHBlbmRpbmdPcCA9ICgpID0+IGxhc3RDaGlsZC5zY3JvbGxJbnRvVmlldyh7IGJsb2NrOiBcImVuZFwiIH0pO1xuICAgICAgICB0aGlzLmxpdmVTb2NrZXQuanMoKS5wdXNoKHRoaXMuZWwsIGJvdHRvbUV2ZW50LCB7XG4gICAgICAgICAgdmFsdWU6IHsgaWQ6IGxhc3RDaGlsZC5pZCB9LFxuICAgICAgICAgIGNhbGxiYWNrOiAoKSA9PiB7XG4gICAgICAgICAgICBwZW5kaW5nT3AgPSBudWxsO1xuICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgdGhlIERPTSBpcyBwYXRjaGVkIGJ5IHdhaXRpbmcgZm9yIHRoZSBuZXh0IHRpY2tcbiAgICAgICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgICAgICBpZiAoIWlzV2l0aGluVmlld3BvcnQobGFzdENoaWxkLCB0aGlzLnNjcm9sbENvbnRhaW5lcikpIHtcbiAgICAgICAgICAgICAgICBsYXN0Q2hpbGQuc2Nyb2xsSW50b1ZpZXcoeyBibG9jazogXCJlbmRcIiB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICk7XG5cbiAgICB0aGlzLm9uU2Nyb2xsID0gKF9lKSA9PiB7XG4gICAgICBjb25zdCBzY3JvbGxOb3cgPSBzY3JvbGxUb3AodGhpcy5zY3JvbGxDb250YWluZXIpO1xuXG4gICAgICBpZiAocGVuZGluZ09wKSB7XG4gICAgICAgIHNjcm9sbEJlZm9yZSA9IHNjcm9sbE5vdztcbiAgICAgICAgcmV0dXJuIHBlbmRpbmdPcCgpO1xuICAgICAgfVxuICAgICAgY29uc3QgcmVjdCA9IHRoaXMuZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBjb25zdCB0b3BFdmVudCA9IHRoaXMuZWwuZ2V0QXR0cmlidXRlKFxuICAgICAgICB0aGlzLmxpdmVTb2NrZXQuYmluZGluZyhcInZpZXdwb3J0LXRvcFwiKSxcbiAgICAgICk7XG4gICAgICBjb25zdCBib3R0b21FdmVudCA9IHRoaXMuZWwuZ2V0QXR0cmlidXRlKFxuICAgICAgICB0aGlzLmxpdmVTb2NrZXQuYmluZGluZyhcInZpZXdwb3J0LWJvdHRvbVwiKSxcbiAgICAgICk7XG4gICAgICBjb25zdCBsYXN0Q2hpbGQgPSB0aGlzLmVsLmxhc3RFbGVtZW50Q2hpbGQ7XG4gICAgICBjb25zdCBmaXJzdENoaWxkID0gdGhpcy5lbC5maXJzdEVsZW1lbnRDaGlsZDtcbiAgICAgIGNvbnN0IGlzU2Nyb2xsaW5nVXAgPSBzY3JvbGxOb3cgPCBzY3JvbGxCZWZvcmU7XG4gICAgICBjb25zdCBpc1Njcm9sbGluZ0Rvd24gPSBzY3JvbGxOb3cgPiBzY3JvbGxCZWZvcmU7XG5cbiAgICAgIC8vIGVsIG92ZXJyYW4gd2hpbGUgc2Nyb2xsaW5nIHVwXG4gICAgICBpZiAoaXNTY3JvbGxpbmdVcCAmJiB0b3BFdmVudCAmJiAhdG9wT3ZlcnJhbiAmJiByZWN0LnRvcCA+PSAwKSB7XG4gICAgICAgIHRvcE92ZXJyYW4gPSB0cnVlO1xuICAgICAgICBvblRvcE92ZXJydW4odG9wRXZlbnQsIGZpcnN0Q2hpbGQpO1xuICAgICAgfSBlbHNlIGlmIChpc1Njcm9sbGluZ0Rvd24gJiYgdG9wT3ZlcnJhbiAmJiByZWN0LnRvcCA8PSAwKSB7XG4gICAgICAgIHRvcE92ZXJyYW4gPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICB0b3BFdmVudCAmJlxuICAgICAgICBpc1Njcm9sbGluZ1VwICYmXG4gICAgICAgIGlzQXRWaWV3cG9ydFRvcChmaXJzdENoaWxkLCB0aGlzLnNjcm9sbENvbnRhaW5lcilcbiAgICAgICkge1xuICAgICAgICBvbkZpcnN0Q2hpbGRBdFRvcCh0b3BFdmVudCwgZmlyc3RDaGlsZCk7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBib3R0b21FdmVudCAmJlxuICAgICAgICBpc1Njcm9sbGluZ0Rvd24gJiZcbiAgICAgICAgaXNBdFZpZXdwb3J0Qm90dG9tKGxhc3RDaGlsZCwgdGhpcy5zY3JvbGxDb250YWluZXIpXG4gICAgICApIHtcbiAgICAgICAgb25MYXN0Q2hpbGRBdEJvdHRvbShib3R0b21FdmVudCwgbGFzdENoaWxkKTtcbiAgICAgIH1cbiAgICAgIHNjcm9sbEJlZm9yZSA9IHNjcm9sbE5vdztcbiAgICB9O1xuXG4gICAgaWYgKHRoaXMuc2Nyb2xsQ29udGFpbmVyKSB7XG4gICAgICB0aGlzLnNjcm9sbENvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsIHRoaXMub25TY3JvbGwpO1xuICAgIH0gZWxzZSB7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLCB0aGlzLm9uU2Nyb2xsKTtcbiAgICB9XG4gIH0sXG5cbiAgZGVzdHJveWVkKCkge1xuICAgIGlmICh0aGlzLnNjcm9sbENvbnRhaW5lcikge1xuICAgICAgdGhpcy5zY3JvbGxDb250YWluZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLCB0aGlzLm9uU2Nyb2xsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgdGhpcy5vblNjcm9sbCk7XG4gICAgfVxuICB9LFxuXG4gIHRocm90dGxlKGludGVydmFsLCBjYWxsYmFjaykge1xuICAgIGxldCBsYXN0Q2FsbEF0ID0gMDtcbiAgICBsZXQgdGltZXI7XG5cbiAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICBjb25zdCByZW1haW5pbmdUaW1lID0gaW50ZXJ2YWwgLSAobm93IC0gbGFzdENhbGxBdCk7XG5cbiAgICAgIGlmIChyZW1haW5pbmdUaW1lIDw9IDAgfHwgcmVtYWluaW5nVGltZSA+IGludGVydmFsKSB7XG4gICAgICAgIGlmICh0aW1lcikge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICAgICAgdGltZXIgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGxhc3RDYWxsQXQgPSBub3c7XG4gICAgICAgIGNhbGxiYWNrKC4uLmFyZ3MpO1xuICAgICAgfSBlbHNlIGlmICghdGltZXIpIHtcbiAgICAgICAgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICBsYXN0Q2FsbEF0ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICB0aW1lciA9IG51bGw7XG4gICAgICAgICAgY2FsbGJhY2soLi4uYXJncyk7XG4gICAgICAgIH0sIHJlbWFpbmluZ1RpbWUpO1xuICAgICAgfVxuICAgIH07XG4gIH0sXG59O1xuZXhwb3J0IGRlZmF1bHQgSG9va3M7XG4iLCAiaW1wb3J0IHtcbiAgUEhYX1JFRl9MT0FESU5HLFxuICBQSFhfUkVGX0xPQ0ssXG4gIFBIWF9SRUZfU1JDLFxuICBQSFhfUEVORElOR19SRUZTLFxuICBQSFhfRVZFTlRfQ0xBU1NFUyxcbiAgUEhYX0RJU0FCTEVELFxuICBQSFhfUkVBRE9OTFksXG4gIFBIWF9ESVNBQkxFX1dJVEhfUkVTVE9SRSxcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cbmltcG9ydCBET00gZnJvbSBcIi4vZG9tXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEVsZW1lbnRSZWYge1xuICBzdGF0aWMgb25VbmxvY2soZWwsIGNhbGxiYWNrKSB7XG4gICAgaWYgKCFET00uaXNMb2NrZWQoZWwpICYmICFlbC5jbG9zZXN0KGBbJHtQSFhfUkVGX0xPQ0t9XWApKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgICB9XG4gICAgY29uc3QgY2xvc2VzdExvY2sgPSBlbC5jbG9zZXN0KGBbJHtQSFhfUkVGX0xPQ0t9XWApO1xuICAgIGNvbnN0IHJlZiA9IGNsb3Nlc3RMb2NrXG4gICAgICAuY2xvc2VzdChgWyR7UEhYX1JFRl9MT0NLfV1gKVxuICAgICAgLmdldEF0dHJpYnV0ZShQSFhfUkVGX0xPQ0spO1xuICAgIGNsb3Nlc3RMb2NrLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBgcGh4OnVuZG8tbG9jazoke3JlZn1gLFxuICAgICAgKCkgPT4ge1xuICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgfSxcbiAgICAgIHsgb25jZTogdHJ1ZSB9LFxuICAgICk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihlbCkge1xuICAgIHRoaXMuZWwgPSBlbDtcbiAgICB0aGlzLmxvYWRpbmdSZWYgPSBlbC5oYXNBdHRyaWJ1dGUoUEhYX1JFRl9MT0FESU5HKVxuICAgICAgPyBwYXJzZUludChlbC5nZXRBdHRyaWJ1dGUoUEhYX1JFRl9MT0FESU5HKSwgMTApXG4gICAgICA6IG51bGw7XG4gICAgdGhpcy5sb2NrUmVmID0gZWwuaGFzQXR0cmlidXRlKFBIWF9SRUZfTE9DSylcbiAgICAgID8gcGFyc2VJbnQoZWwuZ2V0QXR0cmlidXRlKFBIWF9SRUZfTE9DSyksIDEwKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgLy8gcHVibGljXG5cbiAgbWF5YmVVbmRvKHJlZiwgcGh4RXZlbnQsIGVhY2hDbG9uZUNhbGxiYWNrKSB7XG4gICAgaWYgKCF0aGlzLmlzV2l0aGluKHJlZikpIHtcbiAgICAgIC8vIHdlIGNhbm5vdCB1bmRvIHRoZSBsb2NrIC8gbG9hZGluZyBub3csIGFzIHRoZXJlIGlzIGEgbmV3ZXIgb25lIGFscmVhZHkgc2V0O1xuICAgICAgLy8gd2UgbmVlZCB0byBzdG9yZSB0aGUgb3JpZ2luYWwgcmVmIHdlIHRyaWVkIHRvIHNlbmQgdGhlIHVuZG8gZXZlbnQgbGF0ZXJcbiAgICAgIERPTS51cGRhdGVQcml2YXRlKHRoaXMuZWwsIFBIWF9QRU5ESU5HX1JFRlMsIFtdLCAocGVuZGluZ1JlZnMpID0+IHtcbiAgICAgICAgcGVuZGluZ1JlZnMucHVzaChyZWYpO1xuICAgICAgICByZXR1cm4gcGVuZGluZ1JlZnM7XG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyB1bmRvIGxvY2tzIGFuZCBhcHBseSBjbG9uZXNcbiAgICB0aGlzLnVuZG9Mb2NrcyhyZWYsIHBoeEV2ZW50LCBlYWNoQ2xvbmVDYWxsYmFjayk7XG5cbiAgICAvLyB1bmRvIGxvYWRpbmcgc3RhdGVzXG4gICAgdGhpcy51bmRvTG9hZGluZyhyZWYsIHBoeEV2ZW50KTtcblxuICAgIC8vIGVuc3VyZSB1bmRvIGV2ZW50cyBhcmUgZmlyZWQgZm9yIHBlbmRpbmcgcmVmcyB0aGF0XG4gICAgLy8gYXJlIHJlc29sdmVkIGJ5IHRoZSBjdXJyZW50IHJlZiwgb3RoZXJ3aXNlIHdlJ2QgbGVhayBldmVudCBsaXN0ZW5lcnNcbiAgICBET00udXBkYXRlUHJpdmF0ZSh0aGlzLmVsLCBQSFhfUEVORElOR19SRUZTLCBbXSwgKHBlbmRpbmdSZWZzKSA9PiB7XG4gICAgICByZXR1cm4gcGVuZGluZ1JlZnMuZmlsdGVyKChwZW5kaW5nUmVmKSA9PiB7XG4gICAgICAgIGxldCBvcHRzID0ge1xuICAgICAgICAgIGRldGFpbDogeyByZWY6IHBlbmRpbmdSZWYsIGV2ZW50OiBwaHhFdmVudCB9LFxuICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgIH07XG4gICAgICAgIGlmICh0aGlzLmxvYWRpbmdSZWYgJiYgdGhpcy5sb2FkaW5nUmVmID4gcGVuZGluZ1JlZikge1xuICAgICAgICAgIHRoaXMuZWwuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICAgIG5ldyBDdXN0b21FdmVudChgcGh4OnVuZG8tbG9hZGluZzoke3BlbmRpbmdSZWZ9YCwgb3B0cyksXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5sb2NrUmVmICYmIHRoaXMubG9ja1JlZiA+IHBlbmRpbmdSZWYpIHtcbiAgICAgICAgICB0aGlzLmVsLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoYHBoeDp1bmRvLWxvY2s6JHtwZW5kaW5nUmVmfWAsIG9wdHMpLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBlbmRpbmdSZWYgPiByZWY7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8vIGNsZWFuIHVwIGlmIGZ1bGx5IHJlc29sdmVkXG4gICAgaWYgKHRoaXMuaXNGdWxseVJlc29sdmVkQnkocmVmKSkge1xuICAgICAgdGhpcy5lbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1JFRl9TUkMpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHByaXZhdGVcblxuICBpc1dpdGhpbihyZWYpIHtcbiAgICByZXR1cm4gIShcbiAgICAgIHRoaXMubG9hZGluZ1JlZiAhPT0gbnVsbCAmJlxuICAgICAgdGhpcy5sb2FkaW5nUmVmID4gcmVmICYmXG4gICAgICB0aGlzLmxvY2tSZWYgIT09IG51bGwgJiZcbiAgICAgIHRoaXMubG9ja1JlZiA+IHJlZlxuICAgICk7XG4gIH1cblxuICAvLyBDaGVjayBmb3IgY2xvbmVkIFBIWF9SRUZfTE9DSyBlbGVtZW50IHRoYXQgaGFzIGJlZW4gbW9ycGhlZCBiZWhpbmRcbiAgLy8gdGhlIHNjZW5lcyB3aGlsZSB0aGlzIGVsZW1lbnQgd2FzIGxvY2tlZCBpbiB0aGUgRE9NLlxuICAvLyBXaGVuIHdlIGFwcGx5IHRoZSBjbG9uZWQgdHJlZSB0byB0aGUgYWN0aXZlIERPTSBlbGVtZW50LCB3ZSBtdXN0XG4gIC8vXG4gIC8vICAgMS4gZXhlY3V0ZSBwZW5kaW5nIG1vdW50ZWQgaG9va3MgZm9yIG5vZGVzIG5vdyBpbiB0aGUgRE9NXG4gIC8vICAgMi4gdW5kbyBhbnkgcmVmIGluc2lkZSB0aGUgY2xvbmVkIHRyZWUgdGhhdCBoYXMgc2luY2UgYmVlbiBhY2snZFxuICB1bmRvTG9ja3MocmVmLCBwaHhFdmVudCwgZWFjaENsb25lQ2FsbGJhY2spIHtcbiAgICBpZiAoIXRoaXMuaXNMb2NrVW5kb25lQnkocmVmKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGNsb25lZFRyZWUgPSBET00ucHJpdmF0ZSh0aGlzLmVsLCBQSFhfUkVGX0xPQ0spO1xuICAgIGlmIChjbG9uZWRUcmVlKSB7XG4gICAgICBlYWNoQ2xvbmVDYWxsYmFjayhjbG9uZWRUcmVlKTtcbiAgICAgIERPTS5kZWxldGVQcml2YXRlKHRoaXMuZWwsIFBIWF9SRUZfTE9DSyk7XG4gICAgfVxuICAgIHRoaXMuZWwucmVtb3ZlQXR0cmlidXRlKFBIWF9SRUZfTE9DSyk7XG5cbiAgICBjb25zdCBvcHRzID0ge1xuICAgICAgZGV0YWlsOiB7IHJlZjogcmVmLCBldmVudDogcGh4RXZlbnQgfSxcbiAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICB9O1xuICAgIHRoaXMuZWwuZGlzcGF0Y2hFdmVudChcbiAgICAgIG5ldyBDdXN0b21FdmVudChgcGh4OnVuZG8tbG9jazoke3RoaXMubG9ja1JlZn1gLCBvcHRzKSxcbiAgICApO1xuICB9XG5cbiAgdW5kb0xvYWRpbmcocmVmLCBwaHhFdmVudCkge1xuICAgIGlmICghdGhpcy5pc0xvYWRpbmdVbmRvbmVCeShyZWYpKSB7XG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMuY2FuVW5kb0xvYWRpbmcocmVmKSAmJlxuICAgICAgICB0aGlzLmVsLmNsYXNzTGlzdC5jb250YWlucyhcInBoeC1zdWJtaXQtbG9hZGluZ1wiKVxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuZWwuY2xhc3NMaXN0LnJlbW92ZShcInBoeC1jaGFuZ2UtbG9hZGluZ1wiKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jYW5VbmRvTG9hZGluZyhyZWYpKSB7XG4gICAgICB0aGlzLmVsLnJlbW92ZUF0dHJpYnV0ZShQSFhfUkVGX0xPQURJTkcpO1xuICAgICAgY29uc3QgZGlzYWJsZWRWYWwgPSB0aGlzLmVsLmdldEF0dHJpYnV0ZShQSFhfRElTQUJMRUQpO1xuICAgICAgY29uc3QgcmVhZE9ubHlWYWwgPSB0aGlzLmVsLmdldEF0dHJpYnV0ZShQSFhfUkVBRE9OTFkpO1xuICAgICAgLy8gcmVzdG9yZSBpbnB1dHNcbiAgICAgIGlmIChyZWFkT25seVZhbCAhPT0gbnVsbCkge1xuICAgICAgICB0aGlzLmVsLnJlYWRPbmx5ID0gcmVhZE9ubHlWYWwgPT09IFwidHJ1ZVwiID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgICB0aGlzLmVsLnJlbW92ZUF0dHJpYnV0ZShQSFhfUkVBRE9OTFkpO1xuICAgICAgfVxuICAgICAgaWYgKGRpc2FibGVkVmFsICE9PSBudWxsKSB7XG4gICAgICAgIHRoaXMuZWwuZGlzYWJsZWQgPSBkaXNhYmxlZFZhbCA9PT0gXCJ0cnVlXCIgPyB0cnVlIDogZmFsc2U7XG4gICAgICAgIHRoaXMuZWwucmVtb3ZlQXR0cmlidXRlKFBIWF9ESVNBQkxFRCk7XG4gICAgICB9XG4gICAgICAvLyByZXN0b3JlIGRpc2FibGVzXG4gICAgICBjb25zdCBkaXNhYmxlUmVzdG9yZSA9IHRoaXMuZWwuZ2V0QXR0cmlidXRlKFBIWF9ESVNBQkxFX1dJVEhfUkVTVE9SRSk7XG4gICAgICBpZiAoZGlzYWJsZVJlc3RvcmUgIT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5lbC50ZXh0Q29udGVudCA9IGRpc2FibGVSZXN0b3JlO1xuICAgICAgICB0aGlzLmVsLnJlbW92ZUF0dHJpYnV0ZShQSFhfRElTQUJMRV9XSVRIX1JFU1RPUkUpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBvcHRzID0ge1xuICAgICAgICBkZXRhaWw6IHsgcmVmOiByZWYsIGV2ZW50OiBwaHhFdmVudCB9LFxuICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgIH07XG4gICAgICB0aGlzLmVsLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgIG5ldyBDdXN0b21FdmVudChgcGh4OnVuZG8tbG9hZGluZzoke3RoaXMubG9hZGluZ1JlZn1gLCBvcHRzKSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gcmVtb3ZlIGNsYXNzZXNcbiAgICBQSFhfRVZFTlRfQ0xBU1NFUy5mb3JFYWNoKChuYW1lKSA9PiB7XG4gICAgICBpZiAobmFtZSAhPT0gXCJwaHgtc3VibWl0LWxvYWRpbmdcIiB8fCB0aGlzLmNhblVuZG9Mb2FkaW5nKHJlZikpIHtcbiAgICAgICAgRE9NLnJlbW92ZUNsYXNzKHRoaXMuZWwsIG5hbWUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgaXNMb2FkaW5nVW5kb25lQnkocmVmKSB7XG4gICAgcmV0dXJuIHRoaXMubG9hZGluZ1JlZiA9PT0gbnVsbCA/IGZhbHNlIDogdGhpcy5sb2FkaW5nUmVmIDw9IHJlZjtcbiAgfVxuICBpc0xvY2tVbmRvbmVCeShyZWYpIHtcbiAgICByZXR1cm4gdGhpcy5sb2NrUmVmID09PSBudWxsID8gZmFsc2UgOiB0aGlzLmxvY2tSZWYgPD0gcmVmO1xuICB9XG5cbiAgaXNGdWxseVJlc29sdmVkQnkocmVmKSB7XG4gICAgcmV0dXJuIChcbiAgICAgICh0aGlzLmxvYWRpbmdSZWYgPT09IG51bGwgfHwgdGhpcy5sb2FkaW5nUmVmIDw9IHJlZikgJiZcbiAgICAgICh0aGlzLmxvY2tSZWYgPT09IG51bGwgfHwgdGhpcy5sb2NrUmVmIDw9IHJlZilcbiAgICApO1xuICB9XG5cbiAgLy8gb25seSByZW1vdmUgdGhlIHBoeC1zdWJtaXQtbG9hZGluZyBjbGFzcyBpZiB3ZSBhcmUgbm90IGxvY2tlZFxuICBjYW5VbmRvTG9hZGluZyhyZWYpIHtcbiAgICByZXR1cm4gdGhpcy5sb2NrUmVmID09PSBudWxsIHx8IHRoaXMubG9ja1JlZiA8PSByZWY7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBtYXliZSB9IGZyb20gXCIuL3V0aWxzXCI7XG5cbmltcG9ydCBET00gZnJvbSBcIi4vZG9tXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERPTVBvc3RNb3JwaFJlc3RvcmVyIHtcbiAgY29uc3RydWN0b3IoY29udGFpbmVyQmVmb3JlLCBjb250YWluZXJBZnRlciwgdXBkYXRlVHlwZSkge1xuICAgIGNvbnN0IGlkc0JlZm9yZSA9IG5ldyBTZXQoKTtcbiAgICBjb25zdCBpZHNBZnRlciA9IG5ldyBTZXQoXG4gICAgICBbLi4uY29udGFpbmVyQWZ0ZXIuY2hpbGRyZW5dLm1hcCgoY2hpbGQpID0+IGNoaWxkLmlkKSxcbiAgICApO1xuXG4gICAgY29uc3QgZWxlbWVudHNUb01vZGlmeSA9IFtdO1xuXG4gICAgQXJyYXkuZnJvbShjb250YWluZXJCZWZvcmUuY2hpbGRyZW4pLmZvckVhY2goKGNoaWxkKSA9PiB7XG4gICAgICBpZiAoY2hpbGQuaWQpIHtcbiAgICAgICAgLy8gYWxsIG9mIG91ciBjaGlsZHJlbiBzaG91bGQgYmUgZWxlbWVudHMgd2l0aCBpZHNcbiAgICAgICAgaWRzQmVmb3JlLmFkZChjaGlsZC5pZCk7XG4gICAgICAgIGlmIChpZHNBZnRlci5oYXMoY2hpbGQuaWQpKSB7XG4gICAgICAgICAgY29uc3QgcHJldmlvdXNFbGVtZW50SWQgPVxuICAgICAgICAgICAgY2hpbGQucHJldmlvdXNFbGVtZW50U2libGluZyAmJiBjaGlsZC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nLmlkO1xuICAgICAgICAgIGVsZW1lbnRzVG9Nb2RpZnkucHVzaCh7XG4gICAgICAgICAgICBlbGVtZW50SWQ6IGNoaWxkLmlkLFxuICAgICAgICAgICAgcHJldmlvdXNFbGVtZW50SWQ6IHByZXZpb3VzRWxlbWVudElkLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbnRhaW5lcklkID0gY29udGFpbmVyQWZ0ZXIuaWQ7XG4gICAgdGhpcy51cGRhdGVUeXBlID0gdXBkYXRlVHlwZTtcbiAgICB0aGlzLmVsZW1lbnRzVG9Nb2RpZnkgPSBlbGVtZW50c1RvTW9kaWZ5O1xuICAgIHRoaXMuZWxlbWVudElkc1RvQWRkID0gWy4uLmlkc0FmdGVyXS5maWx0ZXIoKGlkKSA9PiAhaWRzQmVmb3JlLmhhcyhpZCkpO1xuICB9XG5cbiAgLy8gV2UgZG8gdGhlIGZvbGxvd2luZyB0byBvcHRpbWl6ZSBhcHBlbmQvcHJlcGVuZCBvcGVyYXRpb25zOlxuICAvLyAgIDEpIFRyYWNrIGlkcyBvZiBtb2RpZmllZCBlbGVtZW50cyAmIG9mIG5ldyBlbGVtZW50c1xuICAvLyAgIDIpIEFsbCB0aGUgbW9kaWZpZWQgZWxlbWVudHMgYXJlIHB1dCBiYWNrIGluIHRoZSBjb3JyZWN0IHBvc2l0aW9uIGluIHRoZSBET00gdHJlZVxuICAvLyAgICAgIGJ5IHN0b3JpbmcgdGhlIGlkIG9mIHRoZWlyIHByZXZpb3VzIHNpYmxpbmdcbiAgLy8gICAzKSBOZXcgZWxlbWVudHMgYXJlIGdvaW5nIHRvIGJlIHB1dCBpbiB0aGUgcmlnaHQgcGxhY2UgYnkgbW9ycGhkb20gZHVyaW5nIGFwcGVuZC5cbiAgLy8gICAgICBGb3IgcHJlcGVuZCwgd2UgbW92ZSB0aGVtIHRvIHRoZSBmaXJzdCBwb3NpdGlvbiBpbiB0aGUgY29udGFpbmVyXG4gIHBlcmZvcm0oKSB7XG4gICAgY29uc3QgY29udGFpbmVyID0gRE9NLmJ5SWQodGhpcy5jb250YWluZXJJZCk7XG4gICAgaWYgKCFjb250YWluZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5lbGVtZW50c1RvTW9kaWZ5LmZvckVhY2goKGVsZW1lbnRUb01vZGlmeSkgPT4ge1xuICAgICAgaWYgKGVsZW1lbnRUb01vZGlmeS5wcmV2aW91c0VsZW1lbnRJZCkge1xuICAgICAgICBtYXliZShcbiAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbGVtZW50VG9Nb2RpZnkucHJldmlvdXNFbGVtZW50SWQpLFxuICAgICAgICAgIChwcmV2aW91c0VsZW0pID0+IHtcbiAgICAgICAgICAgIG1heWJlKFxuICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbGVtZW50VG9Nb2RpZnkuZWxlbWVudElkKSxcbiAgICAgICAgICAgICAgKGVsZW0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBpc0luUmlnaHRQbGFjZSA9XG4gICAgICAgICAgICAgICAgICBlbGVtLnByZXZpb3VzRWxlbWVudFNpYmxpbmcgJiZcbiAgICAgICAgICAgICAgICAgIGVsZW0ucHJldmlvdXNFbGVtZW50U2libGluZy5pZCA9PSBwcmV2aW91c0VsZW0uaWQ7XG4gICAgICAgICAgICAgICAgaWYgKCFpc0luUmlnaHRQbGFjZSkge1xuICAgICAgICAgICAgICAgICAgcHJldmlvdXNFbGVtLmluc2VydEFkamFjZW50RWxlbWVudChcImFmdGVyZW5kXCIsIGVsZW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRoaXMgaXMgdGhlIGZpcnN0IGVsZW1lbnQgaW4gdGhlIGNvbnRhaW5lclxuICAgICAgICBtYXliZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbGVtZW50VG9Nb2RpZnkuZWxlbWVudElkKSwgKGVsZW0pID0+IHtcbiAgICAgICAgICBjb25zdCBpc0luUmlnaHRQbGFjZSA9IGVsZW0ucHJldmlvdXNFbGVtZW50U2libGluZyA9PSBudWxsO1xuICAgICAgICAgIGlmICghaXNJblJpZ2h0UGxhY2UpIHtcbiAgICAgICAgICAgIGNvbnRhaW5lci5pbnNlcnRBZGphY2VudEVsZW1lbnQoXCJhZnRlcmJlZ2luXCIsIGVsZW0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy51cGRhdGVUeXBlID09IFwicHJlcGVuZFwiKSB7XG4gICAgICB0aGlzLmVsZW1lbnRJZHNUb0FkZC5yZXZlcnNlKCkuZm9yRWFjaCgoZWxlbUlkKSA9PiB7XG4gICAgICAgIG1heWJlKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZW1JZCksIChlbGVtKSA9PlxuICAgICAgICAgIGNvbnRhaW5lci5pbnNlcnRBZGphY2VudEVsZW1lbnQoXCJhZnRlcmJlZ2luXCIsIGVsZW0pLFxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG4iLCAidmFyIERPQ1VNRU5UX0ZSQUdNRU5UX05PREUgPSAxMTtcblxuZnVuY3Rpb24gbW9ycGhBdHRycyhmcm9tTm9kZSwgdG9Ob2RlKSB7XG4gICAgdmFyIHRvTm9kZUF0dHJzID0gdG9Ob2RlLmF0dHJpYnV0ZXM7XG4gICAgdmFyIGF0dHI7XG4gICAgdmFyIGF0dHJOYW1lO1xuICAgIHZhciBhdHRyTmFtZXNwYWNlVVJJO1xuICAgIHZhciBhdHRyVmFsdWU7XG4gICAgdmFyIGZyb21WYWx1ZTtcblxuICAgIC8vIGRvY3VtZW50LWZyYWdtZW50cyBkb250IGhhdmUgYXR0cmlidXRlcyBzbyBsZXRzIG5vdCBkbyBhbnl0aGluZ1xuICAgIGlmICh0b05vZGUubm9kZVR5cGUgPT09IERPQ1VNRU5UX0ZSQUdNRU5UX05PREUgfHwgZnJvbU5vZGUubm9kZVR5cGUgPT09IERPQ1VNRU5UX0ZSQUdNRU5UX05PREUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyB1cGRhdGUgYXR0cmlidXRlcyBvbiBvcmlnaW5hbCBET00gZWxlbWVudFxuICAgIGZvciAodmFyIGkgPSB0b05vZGVBdHRycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBhdHRyID0gdG9Ob2RlQXR0cnNbaV07XG4gICAgICAgIGF0dHJOYW1lID0gYXR0ci5uYW1lO1xuICAgICAgICBhdHRyTmFtZXNwYWNlVVJJID0gYXR0ci5uYW1lc3BhY2VVUkk7XG4gICAgICAgIGF0dHJWYWx1ZSA9IGF0dHIudmFsdWU7XG5cbiAgICAgICAgaWYgKGF0dHJOYW1lc3BhY2VVUkkpIHtcbiAgICAgICAgICAgIGF0dHJOYW1lID0gYXR0ci5sb2NhbE5hbWUgfHwgYXR0ck5hbWU7XG4gICAgICAgICAgICBmcm9tVmFsdWUgPSBmcm9tTm9kZS5nZXRBdHRyaWJ1dGVOUyhhdHRyTmFtZXNwYWNlVVJJLCBhdHRyTmFtZSk7XG5cbiAgICAgICAgICAgIGlmIChmcm9tVmFsdWUgIT09IGF0dHJWYWx1ZSkge1xuICAgICAgICAgICAgICAgIGlmIChhdHRyLnByZWZpeCA9PT0gJ3htbG5zJyl7XG4gICAgICAgICAgICAgICAgICAgIGF0dHJOYW1lID0gYXR0ci5uYW1lOyAvLyBJdCdzIG5vdCBhbGxvd2VkIHRvIHNldCBhbiBhdHRyaWJ1dGUgd2l0aCB0aGUgWE1MTlMgbmFtZXNwYWNlIHdpdGhvdXQgc3BlY2lmeWluZyB0aGUgYHhtbG5zYCBwcmVmaXhcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZnJvbU5vZGUuc2V0QXR0cmlidXRlTlMoYXR0ck5hbWVzcGFjZVVSSSwgYXR0ck5hbWUsIGF0dHJWYWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmcm9tVmFsdWUgPSBmcm9tTm9kZS5nZXRBdHRyaWJ1dGUoYXR0ck5hbWUpO1xuXG4gICAgICAgICAgICBpZiAoZnJvbVZhbHVlICE9PSBhdHRyVmFsdWUpIHtcbiAgICAgICAgICAgICAgICBmcm9tTm9kZS5zZXRBdHRyaWJ1dGUoYXR0ck5hbWUsIGF0dHJWYWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZW1vdmUgYW55IGV4dHJhIGF0dHJpYnV0ZXMgZm91bmQgb24gdGhlIG9yaWdpbmFsIERPTSBlbGVtZW50IHRoYXRcbiAgICAvLyB3ZXJlbid0IGZvdW5kIG9uIHRoZSB0YXJnZXQgZWxlbWVudC5cbiAgICB2YXIgZnJvbU5vZGVBdHRycyA9IGZyb21Ob2RlLmF0dHJpYnV0ZXM7XG5cbiAgICBmb3IgKHZhciBkID0gZnJvbU5vZGVBdHRycy5sZW5ndGggLSAxOyBkID49IDA7IGQtLSkge1xuICAgICAgICBhdHRyID0gZnJvbU5vZGVBdHRyc1tkXTtcbiAgICAgICAgYXR0ck5hbWUgPSBhdHRyLm5hbWU7XG4gICAgICAgIGF0dHJOYW1lc3BhY2VVUkkgPSBhdHRyLm5hbWVzcGFjZVVSSTtcblxuICAgICAgICBpZiAoYXR0ck5hbWVzcGFjZVVSSSkge1xuICAgICAgICAgICAgYXR0ck5hbWUgPSBhdHRyLmxvY2FsTmFtZSB8fCBhdHRyTmFtZTtcblxuICAgICAgICAgICAgaWYgKCF0b05vZGUuaGFzQXR0cmlidXRlTlMoYXR0ck5hbWVzcGFjZVVSSSwgYXR0ck5hbWUpKSB7XG4gICAgICAgICAgICAgICAgZnJvbU5vZGUucmVtb3ZlQXR0cmlidXRlTlMoYXR0ck5hbWVzcGFjZVVSSSwgYXR0ck5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCF0b05vZGUuaGFzQXR0cmlidXRlKGF0dHJOYW1lKSkge1xuICAgICAgICAgICAgICAgIGZyb21Ob2RlLnJlbW92ZUF0dHJpYnV0ZShhdHRyTmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbnZhciByYW5nZTsgLy8gQ3JlYXRlIGEgcmFuZ2Ugb2JqZWN0IGZvciBlZmZpY2VudGx5IHJlbmRlcmluZyBzdHJpbmdzIHRvIGVsZW1lbnRzLlxudmFyIE5TX1hIVE1MID0gJ2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwnO1xuXG52YXIgZG9jID0gdHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJyA/IHVuZGVmaW5lZCA6IGRvY3VtZW50O1xudmFyIEhBU19URU1QTEFURV9TVVBQT1JUID0gISFkb2MgJiYgJ2NvbnRlbnQnIGluIGRvYy5jcmVhdGVFbGVtZW50KCd0ZW1wbGF0ZScpO1xudmFyIEhBU19SQU5HRV9TVVBQT1JUID0gISFkb2MgJiYgZG9jLmNyZWF0ZVJhbmdlICYmICdjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQnIGluIGRvYy5jcmVhdGVSYW5nZSgpO1xuXG5mdW5jdGlvbiBjcmVhdGVGcmFnbWVudEZyb21UZW1wbGF0ZShzdHIpIHtcbiAgICB2YXIgdGVtcGxhdGUgPSBkb2MuY3JlYXRlRWxlbWVudCgndGVtcGxhdGUnKTtcbiAgICB0ZW1wbGF0ZS5pbm5lckhUTUwgPSBzdHI7XG4gICAgcmV0dXJuIHRlbXBsYXRlLmNvbnRlbnQuY2hpbGROb2Rlc1swXTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlRnJhZ21lbnRGcm9tUmFuZ2Uoc3RyKSB7XG4gICAgaWYgKCFyYW5nZSkge1xuICAgICAgICByYW5nZSA9IGRvYy5jcmVhdGVSYW5nZSgpO1xuICAgICAgICByYW5nZS5zZWxlY3ROb2RlKGRvYy5ib2R5KTtcbiAgICB9XG5cbiAgICB2YXIgZnJhZ21lbnQgPSByYW5nZS5jcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQoc3RyKTtcbiAgICByZXR1cm4gZnJhZ21lbnQuY2hpbGROb2Rlc1swXTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlRnJhZ21lbnRGcm9tV3JhcChzdHIpIHtcbiAgICB2YXIgZnJhZ21lbnQgPSBkb2MuY3JlYXRlRWxlbWVudCgnYm9keScpO1xuICAgIGZyYWdtZW50LmlubmVySFRNTCA9IHN0cjtcbiAgICByZXR1cm4gZnJhZ21lbnQuY2hpbGROb2Rlc1swXTtcbn1cblxuLyoqXG4gKiBUaGlzIGlzIGFib3V0IHRoZSBzYW1lXG4gKiB2YXIgaHRtbCA9IG5ldyBET01QYXJzZXIoKS5wYXJzZUZyb21TdHJpbmcoc3RyLCAndGV4dC9odG1sJyk7XG4gKiByZXR1cm4gaHRtbC5ib2R5LmZpcnN0Q2hpbGQ7XG4gKlxuICogQG1ldGhvZCB0b0VsZW1lbnRcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqL1xuZnVuY3Rpb24gdG9FbGVtZW50KHN0cikge1xuICAgIHN0ciA9IHN0ci50cmltKCk7XG4gICAgaWYgKEhBU19URU1QTEFURV9TVVBQT1JUKSB7XG4gICAgICAvLyBhdm9pZCByZXN0cmljdGlvbnMgb24gY29udGVudCBmb3IgdGhpbmdzIGxpa2UgYDx0cj48dGg+SGk8L3RoPjwvdHI+YCB3aGljaFxuICAgICAgLy8gY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IGRvZXNuJ3Qgc3VwcG9ydFxuICAgICAgLy8gPHRlbXBsYXRlPiBzdXBwb3J0IG5vdCBhdmFpbGFibGUgaW4gSUVcbiAgICAgIHJldHVybiBjcmVhdGVGcmFnbWVudEZyb21UZW1wbGF0ZShzdHIpO1xuICAgIH0gZWxzZSBpZiAoSEFTX1JBTkdFX1NVUFBPUlQpIHtcbiAgICAgIHJldHVybiBjcmVhdGVGcmFnbWVudEZyb21SYW5nZShzdHIpO1xuICAgIH1cblxuICAgIHJldHVybiBjcmVhdGVGcmFnbWVudEZyb21XcmFwKHN0cik7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHR3byBub2RlJ3MgbmFtZXMgYXJlIHRoZSBzYW1lLlxuICpcbiAqIE5PVEU6IFdlIGRvbid0IGJvdGhlciBjaGVja2luZyBgbmFtZXNwYWNlVVJJYCBiZWNhdXNlIHlvdSB3aWxsIG5ldmVyIGZpbmQgdHdvIEhUTUwgZWxlbWVudHMgd2l0aCB0aGUgc2FtZVxuICogICAgICAgbm9kZU5hbWUgYW5kIGRpZmZlcmVudCBuYW1lc3BhY2UgVVJJcy5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGFcbiAqIEBwYXJhbSB7RWxlbWVudH0gYiBUaGUgdGFyZ2V0IGVsZW1lbnRcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGNvbXBhcmVOb2RlTmFtZXMoZnJvbUVsLCB0b0VsKSB7XG4gICAgdmFyIGZyb21Ob2RlTmFtZSA9IGZyb21FbC5ub2RlTmFtZTtcbiAgICB2YXIgdG9Ob2RlTmFtZSA9IHRvRWwubm9kZU5hbWU7XG4gICAgdmFyIGZyb21Db2RlU3RhcnQsIHRvQ29kZVN0YXJ0O1xuXG4gICAgaWYgKGZyb21Ob2RlTmFtZSA9PT0gdG9Ob2RlTmFtZSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBmcm9tQ29kZVN0YXJ0ID0gZnJvbU5vZGVOYW1lLmNoYXJDb2RlQXQoMCk7XG4gICAgdG9Db2RlU3RhcnQgPSB0b05vZGVOYW1lLmNoYXJDb2RlQXQoMCk7XG5cbiAgICAvLyBJZiB0aGUgdGFyZ2V0IGVsZW1lbnQgaXMgYSB2aXJ0dWFsIERPTSBub2RlIG9yIFNWRyBub2RlIHRoZW4gd2UgbWF5XG4gICAgLy8gbmVlZCB0byBub3JtYWxpemUgdGhlIHRhZyBuYW1lIGJlZm9yZSBjb21wYXJpbmcuIE5vcm1hbCBIVE1MIGVsZW1lbnRzIHRoYXQgYXJlXG4gICAgLy8gaW4gdGhlIFwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiXG4gICAgLy8gYXJlIGNvbnZlcnRlZCB0byB1cHBlciBjYXNlXG4gICAgaWYgKGZyb21Db2RlU3RhcnQgPD0gOTAgJiYgdG9Db2RlU3RhcnQgPj0gOTcpIHsgLy8gZnJvbSBpcyB1cHBlciBhbmQgdG8gaXMgbG93ZXJcbiAgICAgICAgcmV0dXJuIGZyb21Ob2RlTmFtZSA9PT0gdG9Ob2RlTmFtZS50b1VwcGVyQ2FzZSgpO1xuICAgIH0gZWxzZSBpZiAodG9Db2RlU3RhcnQgPD0gOTAgJiYgZnJvbUNvZGVTdGFydCA+PSA5NykgeyAvLyB0byBpcyB1cHBlciBhbmQgZnJvbSBpcyBsb3dlclxuICAgICAgICByZXR1cm4gdG9Ob2RlTmFtZSA9PT0gZnJvbU5vZGVOYW1lLnRvVXBwZXJDYXNlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cblxuLyoqXG4gKiBDcmVhdGUgYW4gZWxlbWVudCwgb3B0aW9uYWxseSB3aXRoIGEga25vd24gbmFtZXNwYWNlIFVSSS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSB0aGUgZWxlbWVudCBuYW1lLCBlLmcuICdkaXYnIG9yICdzdmcnXG4gKiBAcGFyYW0ge3N0cmluZ30gW25hbWVzcGFjZVVSSV0gdGhlIGVsZW1lbnQncyBuYW1lc3BhY2UgVVJJLCBpLmUuIHRoZSB2YWx1ZSBvZlxuICogaXRzIGB4bWxuc2AgYXR0cmlidXRlIG9yIGl0cyBpbmZlcnJlZCBuYW1lc3BhY2UuXG4gKlxuICogQHJldHVybiB7RWxlbWVudH1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRWxlbWVudE5TKG5hbWUsIG5hbWVzcGFjZVVSSSkge1xuICAgIHJldHVybiAhbmFtZXNwYWNlVVJJIHx8IG5hbWVzcGFjZVVSSSA9PT0gTlNfWEhUTUwgP1xuICAgICAgICBkb2MuY3JlYXRlRWxlbWVudChuYW1lKSA6XG4gICAgICAgIGRvYy5jcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlVVJJLCBuYW1lKTtcbn1cblxuLyoqXG4gKiBDb3BpZXMgdGhlIGNoaWxkcmVuIG9mIG9uZSBET00gZWxlbWVudCB0byBhbm90aGVyIERPTSBlbGVtZW50XG4gKi9cbmZ1bmN0aW9uIG1vdmVDaGlsZHJlbihmcm9tRWwsIHRvRWwpIHtcbiAgICB2YXIgY3VyQ2hpbGQgPSBmcm9tRWwuZmlyc3RDaGlsZDtcbiAgICB3aGlsZSAoY3VyQ2hpbGQpIHtcbiAgICAgICAgdmFyIG5leHRDaGlsZCA9IGN1ckNoaWxkLm5leHRTaWJsaW5nO1xuICAgICAgICB0b0VsLmFwcGVuZENoaWxkKGN1ckNoaWxkKTtcbiAgICAgICAgY3VyQ2hpbGQgPSBuZXh0Q2hpbGQ7XG4gICAgfVxuICAgIHJldHVybiB0b0VsO1xufVxuXG5mdW5jdGlvbiBzeW5jQm9vbGVhbkF0dHJQcm9wKGZyb21FbCwgdG9FbCwgbmFtZSkge1xuICAgIGlmIChmcm9tRWxbbmFtZV0gIT09IHRvRWxbbmFtZV0pIHtcbiAgICAgICAgZnJvbUVsW25hbWVdID0gdG9FbFtuYW1lXTtcbiAgICAgICAgaWYgKGZyb21FbFtuYW1lXSkge1xuICAgICAgICAgICAgZnJvbUVsLnNldEF0dHJpYnV0ZShuYW1lLCAnJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmcm9tRWwucmVtb3ZlQXR0cmlidXRlKG5hbWUpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG52YXIgc3BlY2lhbEVsSGFuZGxlcnMgPSB7XG4gICAgT1BUSU9OOiBmdW5jdGlvbihmcm9tRWwsIHRvRWwpIHtcbiAgICAgICAgdmFyIHBhcmVudE5vZGUgPSBmcm9tRWwucGFyZW50Tm9kZTtcbiAgICAgICAgaWYgKHBhcmVudE5vZGUpIHtcbiAgICAgICAgICAgIHZhciBwYXJlbnROYW1lID0gcGFyZW50Tm9kZS5ub2RlTmFtZS50b1VwcGVyQ2FzZSgpO1xuICAgICAgICAgICAgaWYgKHBhcmVudE5hbWUgPT09ICdPUFRHUk9VUCcpIHtcbiAgICAgICAgICAgICAgICBwYXJlbnROb2RlID0gcGFyZW50Tm9kZS5wYXJlbnROb2RlO1xuICAgICAgICAgICAgICAgIHBhcmVudE5hbWUgPSBwYXJlbnROb2RlICYmIHBhcmVudE5vZGUubm9kZU5hbWUudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwYXJlbnROYW1lID09PSAnU0VMRUNUJyAmJiAhcGFyZW50Tm9kZS5oYXNBdHRyaWJ1dGUoJ211bHRpcGxlJykpIHtcbiAgICAgICAgICAgICAgICBpZiAoZnJvbUVsLmhhc0F0dHJpYnV0ZSgnc2VsZWN0ZWQnKSAmJiAhdG9FbC5zZWxlY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXb3JrYXJvdW5kIGZvciBNUyBFZGdlIGJ1ZyB3aGVyZSB0aGUgJ3NlbGVjdGVkJyBhdHRyaWJ1dGUgY2FuIG9ubHkgYmVcbiAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZlZCBpZiBzZXQgdG8gYSBub24tZW1wdHkgdmFsdWU6XG4gICAgICAgICAgICAgICAgICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1pY3Jvc29mdC5jb20vZW4tdXMvbWljcm9zb2Z0LWVkZ2UvcGxhdGZvcm0vaXNzdWVzLzEyMDg3Njc5L1xuICAgICAgICAgICAgICAgICAgICBmcm9tRWwuc2V0QXR0cmlidXRlKCdzZWxlY3RlZCcsICdzZWxlY3RlZCcpO1xuICAgICAgICAgICAgICAgICAgICBmcm9tRWwucmVtb3ZlQXR0cmlidXRlKCdzZWxlY3RlZCcpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBXZSBoYXZlIHRvIHJlc2V0IHNlbGVjdCBlbGVtZW50J3Mgc2VsZWN0ZWRJbmRleCB0byAtMSwgb3RoZXJ3aXNlIHNldHRpbmdcbiAgICAgICAgICAgICAgICAvLyBmcm9tRWwuc2VsZWN0ZWQgdXNpbmcgdGhlIHN5bmNCb29sZWFuQXR0clByb3AgYmVsb3cgaGFzIG5vIGVmZmVjdC5cbiAgICAgICAgICAgICAgICAvLyBUaGUgY29ycmVjdCBzZWxlY3RlZEluZGV4IHdpbGwgYmUgc2V0IGluIHRoZSBTRUxFQ1Qgc3BlY2lhbCBoYW5kbGVyIGJlbG93LlxuICAgICAgICAgICAgICAgIHBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleCA9IC0xO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN5bmNCb29sZWFuQXR0clByb3AoZnJvbUVsLCB0b0VsLCAnc2VsZWN0ZWQnKTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFRoZSBcInZhbHVlXCIgYXR0cmlidXRlIGlzIHNwZWNpYWwgZm9yIHRoZSA8aW5wdXQ+IGVsZW1lbnQgc2luY2UgaXQgc2V0c1xuICAgICAqIHRoZSBpbml0aWFsIHZhbHVlLiBDaGFuZ2luZyB0aGUgXCJ2YWx1ZVwiIGF0dHJpYnV0ZSB3aXRob3V0IGNoYW5naW5nIHRoZVxuICAgICAqIFwidmFsdWVcIiBwcm9wZXJ0eSB3aWxsIGhhdmUgbm8gZWZmZWN0IHNpbmNlIGl0IGlzIG9ubHkgdXNlZCB0byB0aGUgc2V0IHRoZVxuICAgICAqIGluaXRpYWwgdmFsdWUuICBTaW1pbGFyIGZvciB0aGUgXCJjaGVja2VkXCIgYXR0cmlidXRlLCBhbmQgXCJkaXNhYmxlZFwiLlxuICAgICAqL1xuICAgIElOUFVUOiBmdW5jdGlvbihmcm9tRWwsIHRvRWwpIHtcbiAgICAgICAgc3luY0Jvb2xlYW5BdHRyUHJvcChmcm9tRWwsIHRvRWwsICdjaGVja2VkJyk7XG4gICAgICAgIHN5bmNCb29sZWFuQXR0clByb3AoZnJvbUVsLCB0b0VsLCAnZGlzYWJsZWQnKTtcblxuICAgICAgICBpZiAoZnJvbUVsLnZhbHVlICE9PSB0b0VsLnZhbHVlKSB7XG4gICAgICAgICAgICBmcm9tRWwudmFsdWUgPSB0b0VsLnZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0b0VsLmhhc0F0dHJpYnV0ZSgndmFsdWUnKSkge1xuICAgICAgICAgICAgZnJvbUVsLnJlbW92ZUF0dHJpYnV0ZSgndmFsdWUnKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBURVhUQVJFQTogZnVuY3Rpb24oZnJvbUVsLCB0b0VsKSB7XG4gICAgICAgIHZhciBuZXdWYWx1ZSA9IHRvRWwudmFsdWU7XG4gICAgICAgIGlmIChmcm9tRWwudmFsdWUgIT09IG5ld1ZhbHVlKSB7XG4gICAgICAgICAgICBmcm9tRWwudmFsdWUgPSBuZXdWYWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBmaXJzdENoaWxkID0gZnJvbUVsLmZpcnN0Q2hpbGQ7XG4gICAgICAgIGlmIChmaXJzdENoaWxkKSB7XG4gICAgICAgICAgICAvLyBOZWVkZWQgZm9yIElFLiBBcHBhcmVudGx5IElFIHNldHMgdGhlIHBsYWNlaG9sZGVyIGFzIHRoZVxuICAgICAgICAgICAgLy8gbm9kZSB2YWx1ZSBhbmQgdmlzZSB2ZXJzYS4gVGhpcyBpZ25vcmVzIGFuIGVtcHR5IHVwZGF0ZS5cbiAgICAgICAgICAgIHZhciBvbGRWYWx1ZSA9IGZpcnN0Q2hpbGQubm9kZVZhbHVlO1xuXG4gICAgICAgICAgICBpZiAob2xkVmFsdWUgPT0gbmV3VmFsdWUgfHwgKCFuZXdWYWx1ZSAmJiBvbGRWYWx1ZSA9PSBmcm9tRWwucGxhY2Vob2xkZXIpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmaXJzdENoaWxkLm5vZGVWYWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBTRUxFQ1Q6IGZ1bmN0aW9uKGZyb21FbCwgdG9FbCkge1xuICAgICAgICBpZiAoIXRvRWwuaGFzQXR0cmlidXRlKCdtdWx0aXBsZScpKSB7XG4gICAgICAgICAgICB2YXIgc2VsZWN0ZWRJbmRleCA9IC0xO1xuICAgICAgICAgICAgdmFyIGkgPSAwO1xuICAgICAgICAgICAgLy8gV2UgaGF2ZSB0byBsb29wIHRocm91Z2ggY2hpbGRyZW4gb2YgZnJvbUVsLCBub3QgdG9FbCBzaW5jZSBub2RlcyBjYW4gYmUgbW92ZWRcbiAgICAgICAgICAgIC8vIGZyb20gdG9FbCB0byBmcm9tRWwgZGlyZWN0bHkgd2hlbiBtb3JwaGluZy5cbiAgICAgICAgICAgIC8vIEF0IHRoZSB0aW1lIHRoaXMgc3BlY2lhbCBoYW5kbGVyIGlzIGludm9rZWQsIGFsbCBjaGlsZHJlbiBoYXZlIGFscmVhZHkgYmVlbiBtb3JwaGVkXG4gICAgICAgICAgICAvLyBhbmQgYXBwZW5kZWQgdG8gLyByZW1vdmVkIGZyb20gZnJvbUVsLCBzbyB1c2luZyBmcm9tRWwgaGVyZSBpcyBzYWZlIGFuZCBjb3JyZWN0LlxuICAgICAgICAgICAgdmFyIGN1ckNoaWxkID0gZnJvbUVsLmZpcnN0Q2hpbGQ7XG4gICAgICAgICAgICB2YXIgb3B0Z3JvdXA7XG4gICAgICAgICAgICB2YXIgbm9kZU5hbWU7XG4gICAgICAgICAgICB3aGlsZShjdXJDaGlsZCkge1xuICAgICAgICAgICAgICAgIG5vZGVOYW1lID0gY3VyQ2hpbGQubm9kZU5hbWUgJiYgY3VyQ2hpbGQubm9kZU5hbWUudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICAgICAgICBpZiAobm9kZU5hbWUgPT09ICdPUFRHUk9VUCcpIHtcbiAgICAgICAgICAgICAgICAgICAgb3B0Z3JvdXAgPSBjdXJDaGlsZDtcbiAgICAgICAgICAgICAgICAgICAgY3VyQ2hpbGQgPSBvcHRncm91cC5maXJzdENoaWxkO1xuICAgICAgICAgICAgICAgICAgICAvLyBoYW5kbGUgZW1wdHkgb3B0Z3JvdXBzXG4gICAgICAgICAgICAgICAgICAgIGlmICghY3VyQ2hpbGQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1ckNoaWxkID0gb3B0Z3JvdXAubmV4dFNpYmxpbmc7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRncm91cCA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAobm9kZU5hbWUgPT09ICdPUFRJT04nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VyQ2hpbGQuaGFzQXR0cmlidXRlKCdzZWxlY3RlZCcpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRJbmRleCA9IGk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpKys7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY3VyQ2hpbGQgPSBjdXJDaGlsZC5uZXh0U2libGluZztcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjdXJDaGlsZCAmJiBvcHRncm91cCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY3VyQ2hpbGQgPSBvcHRncm91cC5uZXh0U2libGluZztcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGdyb3VwID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZnJvbUVsLnNlbGVjdGVkSW5kZXggPSBzZWxlY3RlZEluZGV4O1xuICAgICAgICB9XG4gICAgfVxufTtcblxudmFyIEVMRU1FTlRfTk9ERSA9IDE7XG52YXIgRE9DVU1FTlRfRlJBR01FTlRfTk9ERSQxID0gMTE7XG52YXIgVEVYVF9OT0RFID0gMztcbnZhciBDT01NRU5UX05PREUgPSA4O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxuZnVuY3Rpb24gZGVmYXVsdEdldE5vZGVLZXkobm9kZSkge1xuICBpZiAobm9kZSkge1xuICAgIHJldHVybiAobm9kZS5nZXRBdHRyaWJ1dGUgJiYgbm9kZS5nZXRBdHRyaWJ1dGUoJ2lkJykpIHx8IG5vZGUuaWQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gbW9ycGhkb21GYWN0b3J5KG1vcnBoQXR0cnMpIHtcblxuICByZXR1cm4gZnVuY3Rpb24gbW9ycGhkb20oZnJvbU5vZGUsIHRvTm9kZSwgb3B0aW9ucykge1xuICAgIGlmICghb3B0aW9ucykge1xuICAgICAgb3B0aW9ucyA9IHt9O1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdG9Ob2RlID09PSAnc3RyaW5nJykge1xuICAgICAgaWYgKGZyb21Ob2RlLm5vZGVOYW1lID09PSAnI2RvY3VtZW50JyB8fCBmcm9tTm9kZS5ub2RlTmFtZSA9PT0gJ0hUTUwnIHx8IGZyb21Ob2RlLm5vZGVOYW1lID09PSAnQk9EWScpIHtcbiAgICAgICAgdmFyIHRvTm9kZUh0bWwgPSB0b05vZGU7XG4gICAgICAgIHRvTm9kZSA9IGRvYy5jcmVhdGVFbGVtZW50KCdodG1sJyk7XG4gICAgICAgIHRvTm9kZS5pbm5lckhUTUwgPSB0b05vZGVIdG1sO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdG9Ob2RlID0gdG9FbGVtZW50KHRvTm9kZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0b05vZGUubm9kZVR5cGUgPT09IERPQ1VNRU5UX0ZSQUdNRU5UX05PREUkMSkge1xuICAgICAgdG9Ob2RlID0gdG9Ob2RlLmZpcnN0RWxlbWVudENoaWxkO1xuICAgIH1cblxuICAgIHZhciBnZXROb2RlS2V5ID0gb3B0aW9ucy5nZXROb2RlS2V5IHx8IGRlZmF1bHRHZXROb2RlS2V5O1xuICAgIHZhciBvbkJlZm9yZU5vZGVBZGRlZCA9IG9wdGlvbnMub25CZWZvcmVOb2RlQWRkZWQgfHwgbm9vcDtcbiAgICB2YXIgb25Ob2RlQWRkZWQgPSBvcHRpb25zLm9uTm9kZUFkZGVkIHx8IG5vb3A7XG4gICAgdmFyIG9uQmVmb3JlRWxVcGRhdGVkID0gb3B0aW9ucy5vbkJlZm9yZUVsVXBkYXRlZCB8fCBub29wO1xuICAgIHZhciBvbkVsVXBkYXRlZCA9IG9wdGlvbnMub25FbFVwZGF0ZWQgfHwgbm9vcDtcbiAgICB2YXIgb25CZWZvcmVOb2RlRGlzY2FyZGVkID0gb3B0aW9ucy5vbkJlZm9yZU5vZGVEaXNjYXJkZWQgfHwgbm9vcDtcbiAgICB2YXIgb25Ob2RlRGlzY2FyZGVkID0gb3B0aW9ucy5vbk5vZGVEaXNjYXJkZWQgfHwgbm9vcDtcbiAgICB2YXIgb25CZWZvcmVFbENoaWxkcmVuVXBkYXRlZCA9IG9wdGlvbnMub25CZWZvcmVFbENoaWxkcmVuVXBkYXRlZCB8fCBub29wO1xuICAgIHZhciBza2lwRnJvbUNoaWxkcmVuID0gb3B0aW9ucy5za2lwRnJvbUNoaWxkcmVuIHx8IG5vb3A7XG4gICAgdmFyIGFkZENoaWxkID0gb3B0aW9ucy5hZGRDaGlsZCB8fCBmdW5jdGlvbihwYXJlbnQsIGNoaWxkKXsgcmV0dXJuIHBhcmVudC5hcHBlbmRDaGlsZChjaGlsZCk7IH07XG4gICAgdmFyIGNoaWxkcmVuT25seSA9IG9wdGlvbnMuY2hpbGRyZW5Pbmx5ID09PSB0cnVlO1xuXG4gICAgLy8gVGhpcyBvYmplY3QgaXMgdXNlZCBhcyBhIGxvb2t1cCB0byBxdWlja2x5IGZpbmQgYWxsIGtleWVkIGVsZW1lbnRzIGluIHRoZSBvcmlnaW5hbCBET00gdHJlZS5cbiAgICB2YXIgZnJvbU5vZGVzTG9va3VwID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICB2YXIga2V5ZWRSZW1vdmFsTGlzdCA9IFtdO1xuXG4gICAgZnVuY3Rpb24gYWRkS2V5ZWRSZW1vdmFsKGtleSkge1xuICAgICAga2V5ZWRSZW1vdmFsTGlzdC5wdXNoKGtleSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gd2Fsa0Rpc2NhcmRlZENoaWxkTm9kZXMobm9kZSwgc2tpcEtleWVkTm9kZXMpIHtcbiAgICAgIGlmIChub2RlLm5vZGVUeXBlID09PSBFTEVNRU5UX05PREUpIHtcbiAgICAgICAgdmFyIGN1ckNoaWxkID0gbm9kZS5maXJzdENoaWxkO1xuICAgICAgICB3aGlsZSAoY3VyQ2hpbGQpIHtcblxuICAgICAgICAgIHZhciBrZXkgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgICBpZiAoc2tpcEtleWVkTm9kZXMgJiYgKGtleSA9IGdldE5vZGVLZXkoY3VyQ2hpbGQpKSkge1xuICAgICAgICAgICAgLy8gSWYgd2UgYXJlIHNraXBwaW5nIGtleWVkIG5vZGVzIHRoZW4gd2UgYWRkIHRoZSBrZXlcbiAgICAgICAgICAgIC8vIHRvIGEgbGlzdCBzbyB0aGF0IGl0IGNhbiBiZSBoYW5kbGVkIGF0IHRoZSB2ZXJ5IGVuZC5cbiAgICAgICAgICAgIGFkZEtleWVkUmVtb3ZhbChrZXkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBPbmx5IHJlcG9ydCB0aGUgbm9kZSBhcyBkaXNjYXJkZWQgaWYgaXQgaXMgbm90IGtleWVkLiBXZSBkbyB0aGlzIGJlY2F1c2VcbiAgICAgICAgICAgIC8vIGF0IHRoZSBlbmQgd2UgbG9vcCB0aHJvdWdoIGFsbCBrZXllZCBlbGVtZW50cyB0aGF0IHdlcmUgdW5tYXRjaGVkXG4gICAgICAgICAgICAvLyBhbmQgdGhlbiBkaXNjYXJkIHRoZW0gaW4gb25lIGZpbmFsIHBhc3MuXG4gICAgICAgICAgICBvbk5vZGVEaXNjYXJkZWQoY3VyQ2hpbGQpO1xuICAgICAgICAgICAgaWYgKGN1ckNoaWxkLmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgd2Fsa0Rpc2NhcmRlZENoaWxkTm9kZXMoY3VyQ2hpbGQsIHNraXBLZXllZE5vZGVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjdXJDaGlsZCA9IGN1ckNoaWxkLm5leHRTaWJsaW5nO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBSZW1vdmVzIGEgRE9NIG5vZGUgb3V0IG9mIHRoZSBvcmlnaW5hbCBET01cbiAgICAqXG4gICAgKiBAcGFyYW0gIHtOb2RlfSBub2RlIFRoZSBub2RlIHRvIHJlbW92ZVxuICAgICogQHBhcmFtICB7Tm9kZX0gcGFyZW50Tm9kZSBUaGUgbm9kZXMgcGFyZW50XG4gICAgKiBAcGFyYW0gIHtCb29sZWFufSBza2lwS2V5ZWROb2RlcyBJZiB0cnVlIHRoZW4gZWxlbWVudHMgd2l0aCBrZXlzIHdpbGwgYmUgc2tpcHBlZCBhbmQgbm90IGRpc2NhcmRlZC5cbiAgICAqIEByZXR1cm4ge3VuZGVmaW5lZH1cbiAgICAqL1xuICAgIGZ1bmN0aW9uIHJlbW92ZU5vZGUobm9kZSwgcGFyZW50Tm9kZSwgc2tpcEtleWVkTm9kZXMpIHtcbiAgICAgIGlmIChvbkJlZm9yZU5vZGVEaXNjYXJkZWQobm9kZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHBhcmVudE5vZGUpIHtcbiAgICAgICAgcGFyZW50Tm9kZS5yZW1vdmVDaGlsZChub2RlKTtcbiAgICAgIH1cblxuICAgICAgb25Ob2RlRGlzY2FyZGVkKG5vZGUpO1xuICAgICAgd2Fsa0Rpc2NhcmRlZENoaWxkTm9kZXMobm9kZSwgc2tpcEtleWVkTm9kZXMpO1xuICAgIH1cblxuICAgIC8vIC8vIFRyZWVXYWxrZXIgaW1wbGVtZW50YXRpb24gaXMgbm8gZmFzdGVyLCBidXQga2VlcGluZyB0aGlzIGFyb3VuZCBpbiBjYXNlIHRoaXMgY2hhbmdlcyBpbiB0aGUgZnV0dXJlXG4gICAgLy8gZnVuY3Rpb24gaW5kZXhUcmVlKHJvb3QpIHtcbiAgICAvLyAgICAgdmFyIHRyZWVXYWxrZXIgPSBkb2N1bWVudC5jcmVhdGVUcmVlV2Fsa2VyKFxuICAgIC8vICAgICAgICAgcm9vdCxcbiAgICAvLyAgICAgICAgIE5vZGVGaWx0ZXIuU0hPV19FTEVNRU5UKTtcbiAgICAvL1xuICAgIC8vICAgICB2YXIgZWw7XG4gICAgLy8gICAgIHdoaWxlKChlbCA9IHRyZWVXYWxrZXIubmV4dE5vZGUoKSkpIHtcbiAgICAvLyAgICAgICAgIHZhciBrZXkgPSBnZXROb2RlS2V5KGVsKTtcbiAgICAvLyAgICAgICAgIGlmIChrZXkpIHtcbiAgICAvLyAgICAgICAgICAgICBmcm9tTm9kZXNMb29rdXBba2V5XSA9IGVsO1xuICAgIC8vICAgICAgICAgfVxuICAgIC8vICAgICB9XG4gICAgLy8gfVxuXG4gICAgLy8gLy8gTm9kZUl0ZXJhdG9yIGltcGxlbWVudGF0aW9uIGlzIG5vIGZhc3RlciwgYnV0IGtlZXBpbmcgdGhpcyBhcm91bmQgaW4gY2FzZSB0aGlzIGNoYW5nZXMgaW4gdGhlIGZ1dHVyZVxuICAgIC8vXG4gICAgLy8gZnVuY3Rpb24gaW5kZXhUcmVlKG5vZGUpIHtcbiAgICAvLyAgICAgdmFyIG5vZGVJdGVyYXRvciA9IGRvY3VtZW50LmNyZWF0ZU5vZGVJdGVyYXRvcihub2RlLCBOb2RlRmlsdGVyLlNIT1dfRUxFTUVOVCk7XG4gICAgLy8gICAgIHZhciBlbDtcbiAgICAvLyAgICAgd2hpbGUoKGVsID0gbm9kZUl0ZXJhdG9yLm5leHROb2RlKCkpKSB7XG4gICAgLy8gICAgICAgICB2YXIga2V5ID0gZ2V0Tm9kZUtleShlbCk7XG4gICAgLy8gICAgICAgICBpZiAoa2V5KSB7XG4gICAgLy8gICAgICAgICAgICAgZnJvbU5vZGVzTG9va3VwW2tleV0gPSBlbDtcbiAgICAvLyAgICAgICAgIH1cbiAgICAvLyAgICAgfVxuICAgIC8vIH1cblxuICAgIGZ1bmN0aW9uIGluZGV4VHJlZShub2RlKSB7XG4gICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFIHx8IG5vZGUubm9kZVR5cGUgPT09IERPQ1VNRU5UX0ZSQUdNRU5UX05PREUkMSkge1xuICAgICAgICB2YXIgY3VyQ2hpbGQgPSBub2RlLmZpcnN0Q2hpbGQ7XG4gICAgICAgIHdoaWxlIChjdXJDaGlsZCkge1xuICAgICAgICAgIHZhciBrZXkgPSBnZXROb2RlS2V5KGN1ckNoaWxkKTtcbiAgICAgICAgICBpZiAoa2V5KSB7XG4gICAgICAgICAgICBmcm9tTm9kZXNMb29rdXBba2V5XSA9IGN1ckNoaWxkO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIFdhbGsgcmVjdXJzaXZlbHlcbiAgICAgICAgICBpbmRleFRyZWUoY3VyQ2hpbGQpO1xuXG4gICAgICAgICAgY3VyQ2hpbGQgPSBjdXJDaGlsZC5uZXh0U2libGluZztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGluZGV4VHJlZShmcm9tTm9kZSk7XG5cbiAgICBmdW5jdGlvbiBoYW5kbGVOb2RlQWRkZWQoZWwpIHtcbiAgICAgIG9uTm9kZUFkZGVkKGVsKTtcblxuICAgICAgdmFyIGN1ckNoaWxkID0gZWwuZmlyc3RDaGlsZDtcbiAgICAgIHdoaWxlIChjdXJDaGlsZCkge1xuICAgICAgICB2YXIgbmV4dFNpYmxpbmcgPSBjdXJDaGlsZC5uZXh0U2libGluZztcblxuICAgICAgICB2YXIga2V5ID0gZ2V0Tm9kZUtleShjdXJDaGlsZCk7XG4gICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICB2YXIgdW5tYXRjaGVkRnJvbUVsID0gZnJvbU5vZGVzTG9va3VwW2tleV07XG4gICAgICAgICAgLy8gaWYgd2UgZmluZCBhIGR1cGxpY2F0ZSAjaWQgbm9kZSBpbiBjYWNoZSwgcmVwbGFjZSBgZWxgIHdpdGggY2FjaGUgdmFsdWVcbiAgICAgICAgICAvLyBhbmQgbW9ycGggaXQgdG8gdGhlIGNoaWxkIG5vZGUuXG4gICAgICAgICAgaWYgKHVubWF0Y2hlZEZyb21FbCAmJiBjb21wYXJlTm9kZU5hbWVzKGN1ckNoaWxkLCB1bm1hdGNoZWRGcm9tRWwpKSB7XG4gICAgICAgICAgICBjdXJDaGlsZC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZCh1bm1hdGNoZWRGcm9tRWwsIGN1ckNoaWxkKTtcbiAgICAgICAgICAgIG1vcnBoRWwodW5tYXRjaGVkRnJvbUVsLCBjdXJDaGlsZCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGhhbmRsZU5vZGVBZGRlZChjdXJDaGlsZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIHJlY3Vyc2l2ZWx5IGNhbGwgZm9yIGN1ckNoaWxkIGFuZCBpdCdzIGNoaWxkcmVuIHRvIHNlZSBpZiB3ZSBmaW5kIHNvbWV0aGluZyBpblxuICAgICAgICAgIC8vIGZyb21Ob2Rlc0xvb2t1cFxuICAgICAgICAgIGhhbmRsZU5vZGVBZGRlZChjdXJDaGlsZCk7XG4gICAgICAgIH1cblxuICAgICAgICBjdXJDaGlsZCA9IG5leHRTaWJsaW5nO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNsZWFudXBGcm9tRWwoZnJvbUVsLCBjdXJGcm9tTm9kZUNoaWxkLCBjdXJGcm9tTm9kZUtleSkge1xuICAgICAgLy8gV2UgaGF2ZSBwcm9jZXNzZWQgYWxsIG9mIHRoZSBcInRvIG5vZGVzXCIuIElmIGN1ckZyb21Ob2RlQ2hpbGQgaXNcbiAgICAgIC8vIG5vbi1udWxsIHRoZW4gd2Ugc3RpbGwgaGF2ZSBzb21lIGZyb20gbm9kZXMgbGVmdCBvdmVyIHRoYXQgbmVlZFxuICAgICAgLy8gdG8gYmUgcmVtb3ZlZFxuICAgICAgd2hpbGUgKGN1ckZyb21Ob2RlQ2hpbGQpIHtcbiAgICAgICAgdmFyIGZyb21OZXh0U2libGluZyA9IGN1ckZyb21Ob2RlQ2hpbGQubmV4dFNpYmxpbmc7XG4gICAgICAgIGlmICgoY3VyRnJvbU5vZGVLZXkgPSBnZXROb2RlS2V5KGN1ckZyb21Ob2RlQ2hpbGQpKSkge1xuICAgICAgICAgIC8vIFNpbmNlIHRoZSBub2RlIGlzIGtleWVkIGl0IG1pZ2h0IGJlIG1hdGNoZWQgdXAgbGF0ZXIgc28gd2UgZGVmZXJcbiAgICAgICAgICAvLyB0aGUgYWN0dWFsIHJlbW92YWwgdG8gbGF0ZXJcbiAgICAgICAgICBhZGRLZXllZFJlbW92YWwoY3VyRnJvbU5vZGVLZXkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE5PVEU6IHdlIHNraXAgbmVzdGVkIGtleWVkIG5vZGVzIGZyb20gYmVpbmcgcmVtb3ZlZCBzaW5jZSB0aGVyZSBpc1xuICAgICAgICAgIC8vICAgICAgIHN0aWxsIGEgY2hhbmNlIHRoZXkgd2lsbCBiZSBtYXRjaGVkIHVwIGxhdGVyXG4gICAgICAgICAgcmVtb3ZlTm9kZShjdXJGcm9tTm9kZUNoaWxkLCBmcm9tRWwsIHRydWUgLyogc2tpcCBrZXllZCBub2RlcyAqLyk7XG4gICAgICAgIH1cbiAgICAgICAgY3VyRnJvbU5vZGVDaGlsZCA9IGZyb21OZXh0U2libGluZztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb3JwaEVsKGZyb21FbCwgdG9FbCwgY2hpbGRyZW5Pbmx5KSB7XG4gICAgICB2YXIgdG9FbEtleSA9IGdldE5vZGVLZXkodG9FbCk7XG5cbiAgICAgIGlmICh0b0VsS2V5KSB7XG4gICAgICAgIC8vIElmIGFuIGVsZW1lbnQgd2l0aCBhbiBJRCBpcyBiZWluZyBtb3JwaGVkIHRoZW4gaXQgd2lsbCBiZSBpbiB0aGUgZmluYWxcbiAgICAgICAgLy8gRE9NIHNvIGNsZWFyIGl0IG91dCBvZiB0aGUgc2F2ZWQgZWxlbWVudHMgY29sbGVjdGlvblxuICAgICAgICBkZWxldGUgZnJvbU5vZGVzTG9va3VwW3RvRWxLZXldO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWNoaWxkcmVuT25seSkge1xuICAgICAgICAvLyBvcHRpb25hbFxuICAgICAgICB2YXIgYmVmb3JlVXBkYXRlUmVzdWx0ID0gb25CZWZvcmVFbFVwZGF0ZWQoZnJvbUVsLCB0b0VsKTtcbiAgICAgICAgaWYgKGJlZm9yZVVwZGF0ZVJlc3VsdCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSBpZiAoYmVmb3JlVXBkYXRlUmVzdWx0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICBmcm9tRWwgPSBiZWZvcmVVcGRhdGVSZXN1bHQ7XG4gICAgICAgICAgLy8gcmVpbmRleCB0aGUgbmV3IGZyb21FbCBpbiBjYXNlIGl0J3Mgbm90IGluIHRoZSBzYW1lXG4gICAgICAgICAgLy8gdHJlZSBhcyB0aGUgb3JpZ2luYWwgZnJvbUVsXG4gICAgICAgICAgLy8gKFBob2VuaXggTGl2ZVZpZXcgc29tZXRpbWVzIHJldHVybnMgYSBjbG9uZWQgdHJlZSxcbiAgICAgICAgICAvLyAgYnV0IGtleWVkIGxvb2t1cHMgd291bGQgc3RpbGwgcG9pbnQgdG8gdGhlIG9yaWdpbmFsIHRyZWUpXG4gICAgICAgICAgaW5kZXhUcmVlKGZyb21FbCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB1cGRhdGUgYXR0cmlidXRlcyBvbiBvcmlnaW5hbCBET00gZWxlbWVudCBmaXJzdFxuICAgICAgICBtb3JwaEF0dHJzKGZyb21FbCwgdG9FbCk7XG4gICAgICAgIC8vIG9wdGlvbmFsXG4gICAgICAgIG9uRWxVcGRhdGVkKGZyb21FbCk7XG5cbiAgICAgICAgaWYgKG9uQmVmb3JlRWxDaGlsZHJlblVwZGF0ZWQoZnJvbUVsLCB0b0VsKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGZyb21FbC5ub2RlTmFtZSAhPT0gJ1RFWFRBUkVBJykge1xuICAgICAgICBtb3JwaENoaWxkcmVuKGZyb21FbCwgdG9FbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzcGVjaWFsRWxIYW5kbGVycy5URVhUQVJFQShmcm9tRWwsIHRvRWwpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1vcnBoQ2hpbGRyZW4oZnJvbUVsLCB0b0VsKSB7XG4gICAgICB2YXIgc2tpcEZyb20gPSBza2lwRnJvbUNoaWxkcmVuKGZyb21FbCwgdG9FbCk7XG4gICAgICB2YXIgY3VyVG9Ob2RlQ2hpbGQgPSB0b0VsLmZpcnN0Q2hpbGQ7XG4gICAgICB2YXIgY3VyRnJvbU5vZGVDaGlsZCA9IGZyb21FbC5maXJzdENoaWxkO1xuICAgICAgdmFyIGN1clRvTm9kZUtleTtcbiAgICAgIHZhciBjdXJGcm9tTm9kZUtleTtcblxuICAgICAgdmFyIGZyb21OZXh0U2libGluZztcbiAgICAgIHZhciB0b05leHRTaWJsaW5nO1xuICAgICAgdmFyIG1hdGNoaW5nRnJvbUVsO1xuXG4gICAgICAvLyB3YWxrIHRoZSBjaGlsZHJlblxuICAgICAgb3V0ZXI6IHdoaWxlIChjdXJUb05vZGVDaGlsZCkge1xuICAgICAgICB0b05leHRTaWJsaW5nID0gY3VyVG9Ob2RlQ2hpbGQubmV4dFNpYmxpbmc7XG4gICAgICAgIGN1clRvTm9kZUtleSA9IGdldE5vZGVLZXkoY3VyVG9Ob2RlQ2hpbGQpO1xuXG4gICAgICAgIC8vIHdhbGsgdGhlIGZyb21Ob2RlIGNoaWxkcmVuIGFsbCB0aGUgd2F5IHRocm91Z2hcbiAgICAgICAgd2hpbGUgKCFza2lwRnJvbSAmJiBjdXJGcm9tTm9kZUNoaWxkKSB7XG4gICAgICAgICAgZnJvbU5leHRTaWJsaW5nID0gY3VyRnJvbU5vZGVDaGlsZC5uZXh0U2libGluZztcblxuICAgICAgICAgIGlmIChjdXJUb05vZGVDaGlsZC5pc1NhbWVOb2RlICYmIGN1clRvTm9kZUNoaWxkLmlzU2FtZU5vZGUoY3VyRnJvbU5vZGVDaGlsZCkpIHtcbiAgICAgICAgICAgIGN1clRvTm9kZUNoaWxkID0gdG9OZXh0U2libGluZztcbiAgICAgICAgICAgIGN1ckZyb21Ob2RlQ2hpbGQgPSBmcm9tTmV4dFNpYmxpbmc7XG4gICAgICAgICAgICBjb250aW51ZSBvdXRlcjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjdXJGcm9tTm9kZUtleSA9IGdldE5vZGVLZXkoY3VyRnJvbU5vZGVDaGlsZCk7XG5cbiAgICAgICAgICB2YXIgY3VyRnJvbU5vZGVUeXBlID0gY3VyRnJvbU5vZGVDaGlsZC5ub2RlVHlwZTtcblxuICAgICAgICAgIC8vIHRoaXMgbWVhbnMgaWYgdGhlIGN1ckZyb21Ob2RlQ2hpbGQgZG9lc250IGhhdmUgYSBtYXRjaCB3aXRoIHRoZSBjdXJUb05vZGVDaGlsZFxuICAgICAgICAgIHZhciBpc0NvbXBhdGlibGUgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgICBpZiAoY3VyRnJvbU5vZGVUeXBlID09PSBjdXJUb05vZGVDaGlsZC5ub2RlVHlwZSkge1xuICAgICAgICAgICAgaWYgKGN1ckZyb21Ob2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgICAgICAgIC8vIEJvdGggbm9kZXMgYmVpbmcgY29tcGFyZWQgYXJlIEVsZW1lbnQgbm9kZXNcblxuICAgICAgICAgICAgICBpZiAoY3VyVG9Ob2RlS2V5KSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlIHRhcmdldCBub2RlIGhhcyBhIGtleSBzbyB3ZSB3YW50IHRvIG1hdGNoIGl0IHVwIHdpdGggdGhlIGNvcnJlY3QgZWxlbWVudFxuICAgICAgICAgICAgICAgIC8vIGluIHRoZSBvcmlnaW5hbCBET00gdHJlZVxuICAgICAgICAgICAgICAgIGlmIChjdXJUb05vZGVLZXkgIT09IGN1ckZyb21Ob2RlS2V5KSB7XG4gICAgICAgICAgICAgICAgICAvLyBUaGUgY3VycmVudCBlbGVtZW50IGluIHRoZSBvcmlnaW5hbCBET00gdHJlZSBkb2VzIG5vdCBoYXZlIGEgbWF0Y2hpbmcga2V5IHNvXG4gICAgICAgICAgICAgICAgICAvLyBsZXQncyBjaGVjayBvdXIgbG9va3VwIHRvIHNlZSBpZiB0aGVyZSBpcyBhIG1hdGNoaW5nIGVsZW1lbnQgaW4gdGhlIG9yaWdpbmFsXG4gICAgICAgICAgICAgICAgICAvLyBET00gdHJlZVxuICAgICAgICAgICAgICAgICAgaWYgKChtYXRjaGluZ0Zyb21FbCA9IGZyb21Ob2Rlc0xvb2t1cFtjdXJUb05vZGVLZXldKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZnJvbU5leHRTaWJsaW5nID09PSBtYXRjaGluZ0Zyb21FbCkge1xuICAgICAgICAgICAgICAgICAgICAgIC8vIFNwZWNpYWwgY2FzZSBmb3Igc2luZ2xlIGVsZW1lbnQgcmVtb3ZhbHMuIFRvIGF2b2lkIHJlbW92aW5nIHRoZSBvcmlnaW5hbFxuICAgICAgICAgICAgICAgICAgICAgIC8vIERPTSBub2RlIG91dCBvZiB0aGUgdHJlZSAoc2luY2UgdGhhdCBjYW4gYnJlYWsgQ1NTIHRyYW5zaXRpb25zLCBldGMuKSxcbiAgICAgICAgICAgICAgICAgICAgICAvLyB3ZSB3aWxsIGluc3RlYWQgZGlzY2FyZCB0aGUgY3VycmVudCBub2RlIGFuZCB3YWl0IHVudGlsIHRoZSBuZXh0XG4gICAgICAgICAgICAgICAgICAgICAgLy8gaXRlcmF0aW9uIHRvIHByb3Blcmx5IG1hdGNoIHVwIHRoZSBrZXllZCB0YXJnZXQgZWxlbWVudCB3aXRoIGl0cyBtYXRjaGluZ1xuICAgICAgICAgICAgICAgICAgICAgIC8vIGVsZW1lbnQgaW4gdGhlIG9yaWdpbmFsIHRyZWVcbiAgICAgICAgICAgICAgICAgICAgICBpc0NvbXBhdGlibGUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBmb3VuZCBhIG1hdGNoaW5nIGtleWVkIGVsZW1lbnQgc29tZXdoZXJlIGluIHRoZSBvcmlnaW5hbCBET00gdHJlZS5cbiAgICAgICAgICAgICAgICAgICAgICAvLyBMZXQncyBtb3ZlIHRoZSBvcmlnaW5hbCBET00gbm9kZSBpbnRvIHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCBtb3JwaFxuICAgICAgICAgICAgICAgICAgICAgIC8vIGl0LlxuXG4gICAgICAgICAgICAgICAgICAgICAgLy8gTk9URTogV2UgdXNlIGluc2VydEJlZm9yZSBpbnN0ZWFkIG9mIHJlcGxhY2VDaGlsZCBiZWNhdXNlIHdlIHdhbnQgdG8gZ28gdGhyb3VnaFxuICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBgcmVtb3ZlTm9kZSgpYCBmdW5jdGlvbiBmb3IgdGhlIG5vZGUgdGhhdCBpcyBiZWluZyBkaXNjYXJkZWQgc28gdGhhdFxuICAgICAgICAgICAgICAgICAgICAgIC8vIGFsbCBsaWZlY3ljbGUgaG9va3MgYXJlIGNvcnJlY3RseSBpbnZva2VkXG4gICAgICAgICAgICAgICAgICAgICAgZnJvbUVsLmluc2VydEJlZm9yZShtYXRjaGluZ0Zyb21FbCwgY3VyRnJvbU5vZGVDaGlsZCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAvLyBmcm9tTmV4dFNpYmxpbmcgPSBjdXJGcm9tTm9kZUNoaWxkLm5leHRTaWJsaW5nO1xuXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKGN1ckZyb21Ob2RlS2V5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBTaW5jZSB0aGUgbm9kZSBpcyBrZXllZCBpdCBtaWdodCBiZSBtYXRjaGVkIHVwIGxhdGVyIHNvIHdlIGRlZmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgYWN0dWFsIHJlbW92YWwgdG8gbGF0ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZEtleWVkUmVtb3ZhbChjdXJGcm9tTm9kZUtleSk7XG4gICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5PVEU6IHdlIHNraXAgbmVzdGVkIGtleWVkIG5vZGVzIGZyb20gYmVpbmcgcmVtb3ZlZCBzaW5jZSB0aGVyZSBpc1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgc3RpbGwgYSBjaGFuY2UgdGhleSB3aWxsIGJlIG1hdGNoZWQgdXAgbGF0ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZU5vZGUoY3VyRnJvbU5vZGVDaGlsZCwgZnJvbUVsLCB0cnVlIC8qIHNraXAga2V5ZWQgbm9kZXMgKi8pO1xuICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgIGN1ckZyb21Ob2RlQ2hpbGQgPSBtYXRjaGluZ0Zyb21FbDtcbiAgICAgICAgICAgICAgICAgICAgICBjdXJGcm9tTm9kZUtleSA9IGdldE5vZGVLZXkoY3VyRnJvbU5vZGVDaGlsZCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZSBub2RlcyBhcmUgbm90IGNvbXBhdGlibGUgc2luY2UgdGhlIFwidG9cIiBub2RlIGhhcyBhIGtleSBhbmQgdGhlcmVcbiAgICAgICAgICAgICAgICAgICAgLy8gaXMgbm8gbWF0Y2hpbmcga2V5ZWQgbm9kZSBpbiB0aGUgc291cmNlIHRyZWVcbiAgICAgICAgICAgICAgICAgICAgaXNDb21wYXRpYmxlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGN1ckZyb21Ob2RlS2V5KSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlIG9yaWdpbmFsIGhhcyBhIGtleVxuICAgICAgICAgICAgICAgIGlzQ29tcGF0aWJsZSA9IGZhbHNlO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaXNDb21wYXRpYmxlID0gaXNDb21wYXRpYmxlICE9PSBmYWxzZSAmJiBjb21wYXJlTm9kZU5hbWVzKGN1ckZyb21Ob2RlQ2hpbGQsIGN1clRvTm9kZUNoaWxkKTtcbiAgICAgICAgICAgICAgaWYgKGlzQ29tcGF0aWJsZSkge1xuICAgICAgICAgICAgICAgIC8vIFdlIGZvdW5kIGNvbXBhdGlibGUgRE9NIGVsZW1lbnRzIHNvIHRyYW5zZm9ybVxuICAgICAgICAgICAgICAgIC8vIHRoZSBjdXJyZW50IFwiZnJvbVwiIG5vZGUgdG8gbWF0Y2ggdGhlIGN1cnJlbnRcbiAgICAgICAgICAgICAgICAvLyB0YXJnZXQgRE9NIG5vZGUuXG4gICAgICAgICAgICAgICAgLy8gTU9SUEhcbiAgICAgICAgICAgICAgICBtb3JwaEVsKGN1ckZyb21Ob2RlQ2hpbGQsIGN1clRvTm9kZUNoaWxkKTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGN1ckZyb21Ob2RlVHlwZSA9PT0gVEVYVF9OT0RFIHx8IGN1ckZyb21Ob2RlVHlwZSA9PSBDT01NRU5UX05PREUpIHtcbiAgICAgICAgICAgICAgLy8gQm90aCBub2RlcyBiZWluZyBjb21wYXJlZCBhcmUgVGV4dCBvciBDb21tZW50IG5vZGVzXG4gICAgICAgICAgICAgIGlzQ29tcGF0aWJsZSA9IHRydWU7XG4gICAgICAgICAgICAgIC8vIFNpbXBseSB1cGRhdGUgbm9kZVZhbHVlIG9uIHRoZSBvcmlnaW5hbCBub2RlIHRvXG4gICAgICAgICAgICAgIC8vIGNoYW5nZSB0aGUgdGV4dCB2YWx1ZVxuICAgICAgICAgICAgICBpZiAoY3VyRnJvbU5vZGVDaGlsZC5ub2RlVmFsdWUgIT09IGN1clRvTm9kZUNoaWxkLm5vZGVWYWx1ZSkge1xuICAgICAgICAgICAgICAgIGN1ckZyb21Ob2RlQ2hpbGQubm9kZVZhbHVlID0gY3VyVG9Ob2RlQ2hpbGQubm9kZVZhbHVlO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaXNDb21wYXRpYmxlKSB7XG4gICAgICAgICAgICAvLyBBZHZhbmNlIGJvdGggdGhlIFwidG9cIiBjaGlsZCBhbmQgdGhlIFwiZnJvbVwiIGNoaWxkIHNpbmNlIHdlIGZvdW5kIGEgbWF0Y2hcbiAgICAgICAgICAgIC8vIE5vdGhpbmcgZWxzZSB0byBkbyBhcyB3ZSBhbHJlYWR5IHJlY3Vyc2l2ZWx5IGNhbGxlZCBtb3JwaENoaWxkcmVuIGFib3ZlXG4gICAgICAgICAgICBjdXJUb05vZGVDaGlsZCA9IHRvTmV4dFNpYmxpbmc7XG4gICAgICAgICAgICBjdXJGcm9tTm9kZUNoaWxkID0gZnJvbU5leHRTaWJsaW5nO1xuICAgICAgICAgICAgY29udGludWUgb3V0ZXI7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gTm8gY29tcGF0aWJsZSBtYXRjaCBzbyByZW1vdmUgdGhlIG9sZCBub2RlIGZyb20gdGhlIERPTSBhbmQgY29udGludWUgdHJ5aW5nIHRvIGZpbmQgYVxuICAgICAgICAgIC8vIG1hdGNoIGluIHRoZSBvcmlnaW5hbCBET00uIEhvd2V2ZXIsIHdlIG9ubHkgZG8gdGhpcyBpZiB0aGUgZnJvbSBub2RlIGlzIG5vdCBrZXllZFxuICAgICAgICAgIC8vIHNpbmNlIGl0IGlzIHBvc3NpYmxlIHRoYXQgYSBrZXllZCBub2RlIG1pZ2h0IG1hdGNoIHVwIHdpdGggYSBub2RlIHNvbWV3aGVyZSBlbHNlIGluIHRoZVxuICAgICAgICAgIC8vIHRhcmdldCB0cmVlIGFuZCB3ZSBkb24ndCB3YW50IHRvIGRpc2NhcmQgaXQganVzdCB5ZXQgc2luY2UgaXQgc3RpbGwgbWlnaHQgZmluZCBhXG4gICAgICAgICAgLy8gaG9tZSBpbiB0aGUgZmluYWwgRE9NIHRyZWUuIEFmdGVyIGV2ZXJ5dGhpbmcgaXMgZG9uZSB3ZSB3aWxsIHJlbW92ZSBhbnkga2V5ZWQgbm9kZXNcbiAgICAgICAgICAvLyB0aGF0IGRpZG4ndCBmaW5kIGEgaG9tZVxuICAgICAgICAgIGlmIChjdXJGcm9tTm9kZUtleSkge1xuICAgICAgICAgICAgLy8gU2luY2UgdGhlIG5vZGUgaXMga2V5ZWQgaXQgbWlnaHQgYmUgbWF0Y2hlZCB1cCBsYXRlciBzbyB3ZSBkZWZlclxuICAgICAgICAgICAgLy8gdGhlIGFjdHVhbCByZW1vdmFsIHRvIGxhdGVyXG4gICAgICAgICAgICBhZGRLZXllZFJlbW92YWwoY3VyRnJvbU5vZGVLZXkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBOT1RFOiB3ZSBza2lwIG5lc3RlZCBrZXllZCBub2RlcyBmcm9tIGJlaW5nIHJlbW92ZWQgc2luY2UgdGhlcmUgaXNcbiAgICAgICAgICAgIC8vICAgICAgIHN0aWxsIGEgY2hhbmNlIHRoZXkgd2lsbCBiZSBtYXRjaGVkIHVwIGxhdGVyXG4gICAgICAgICAgICByZW1vdmVOb2RlKGN1ckZyb21Ob2RlQ2hpbGQsIGZyb21FbCwgdHJ1ZSAvKiBza2lwIGtleWVkIG5vZGVzICovKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjdXJGcm9tTm9kZUNoaWxkID0gZnJvbU5leHRTaWJsaW5nO1xuICAgICAgICB9IC8vIEVORDogd2hpbGUoY3VyRnJvbU5vZGVDaGlsZCkge31cblxuICAgICAgICAvLyBJZiB3ZSBnb3QgdGhpcyBmYXIgdGhlbiB3ZSBkaWQgbm90IGZpbmQgYSBjYW5kaWRhdGUgbWF0Y2ggZm9yXG4gICAgICAgIC8vIG91ciBcInRvIG5vZGVcIiBhbmQgd2UgZXhoYXVzdGVkIGFsbCBvZiB0aGUgY2hpbGRyZW4gXCJmcm9tXCJcbiAgICAgICAgLy8gbm9kZXMuIFRoZXJlZm9yZSwgd2Ugd2lsbCBqdXN0IGFwcGVuZCB0aGUgY3VycmVudCBcInRvXCIgbm9kZVxuICAgICAgICAvLyB0byB0aGUgZW5kXG4gICAgICAgIGlmIChjdXJUb05vZGVLZXkgJiYgKG1hdGNoaW5nRnJvbUVsID0gZnJvbU5vZGVzTG9va3VwW2N1clRvTm9kZUtleV0pICYmIGNvbXBhcmVOb2RlTmFtZXMobWF0Y2hpbmdGcm9tRWwsIGN1clRvTm9kZUNoaWxkKSkge1xuICAgICAgICAgIC8vIE1PUlBIXG4gICAgICAgICAgaWYoIXNraXBGcm9tKXsgYWRkQ2hpbGQoZnJvbUVsLCBtYXRjaGluZ0Zyb21FbCk7IH1cbiAgICAgICAgICBtb3JwaEVsKG1hdGNoaW5nRnJvbUVsLCBjdXJUb05vZGVDaGlsZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIG9uQmVmb3JlTm9kZUFkZGVkUmVzdWx0ID0gb25CZWZvcmVOb2RlQWRkZWQoY3VyVG9Ob2RlQ2hpbGQpO1xuICAgICAgICAgIGlmIChvbkJlZm9yZU5vZGVBZGRlZFJlc3VsdCAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGlmIChvbkJlZm9yZU5vZGVBZGRlZFJlc3VsdCkge1xuICAgICAgICAgICAgICBjdXJUb05vZGVDaGlsZCA9IG9uQmVmb3JlTm9kZUFkZGVkUmVzdWx0O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoY3VyVG9Ob2RlQ2hpbGQuYWN0dWFsaXplKSB7XG4gICAgICAgICAgICAgIGN1clRvTm9kZUNoaWxkID0gY3VyVG9Ob2RlQ2hpbGQuYWN0dWFsaXplKGZyb21FbC5vd25lckRvY3VtZW50IHx8IGRvYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhZGRDaGlsZChmcm9tRWwsIGN1clRvTm9kZUNoaWxkKTtcbiAgICAgICAgICAgIGhhbmRsZU5vZGVBZGRlZChjdXJUb05vZGVDaGlsZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY3VyVG9Ob2RlQ2hpbGQgPSB0b05leHRTaWJsaW5nO1xuICAgICAgICBjdXJGcm9tTm9kZUNoaWxkID0gZnJvbU5leHRTaWJsaW5nO1xuICAgICAgfVxuXG4gICAgICBjbGVhbnVwRnJvbUVsKGZyb21FbCwgY3VyRnJvbU5vZGVDaGlsZCwgY3VyRnJvbU5vZGVLZXkpO1xuXG4gICAgICB2YXIgc3BlY2lhbEVsSGFuZGxlciA9IHNwZWNpYWxFbEhhbmRsZXJzW2Zyb21FbC5ub2RlTmFtZV07XG4gICAgICBpZiAoc3BlY2lhbEVsSGFuZGxlcikge1xuICAgICAgICBzcGVjaWFsRWxIYW5kbGVyKGZyb21FbCwgdG9FbCk7XG4gICAgICB9XG4gICAgfSAvLyBFTkQ6IG1vcnBoQ2hpbGRyZW4oLi4uKVxuXG4gICAgdmFyIG1vcnBoZWROb2RlID0gZnJvbU5vZGU7XG4gICAgdmFyIG1vcnBoZWROb2RlVHlwZSA9IG1vcnBoZWROb2RlLm5vZGVUeXBlO1xuICAgIHZhciB0b05vZGVUeXBlID0gdG9Ob2RlLm5vZGVUeXBlO1xuXG4gICAgaWYgKCFjaGlsZHJlbk9ubHkpIHtcbiAgICAgIC8vIEhhbmRsZSB0aGUgY2FzZSB3aGVyZSB3ZSBhcmUgZ2l2ZW4gdHdvIERPTSBub2RlcyB0aGF0IGFyZSBub3RcbiAgICAgIC8vIGNvbXBhdGlibGUgKGUuZy4gPGRpdj4gLS0+IDxzcGFuPiBvciA8ZGl2PiAtLT4gVEVYVClcbiAgICAgIGlmIChtb3JwaGVkTm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSkge1xuICAgICAgICBpZiAodG9Ob2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgICAgaWYgKCFjb21wYXJlTm9kZU5hbWVzKGZyb21Ob2RlLCB0b05vZGUpKSB7XG4gICAgICAgICAgICBvbk5vZGVEaXNjYXJkZWQoZnJvbU5vZGUpO1xuICAgICAgICAgICAgbW9ycGhlZE5vZGUgPSBtb3ZlQ2hpbGRyZW4oZnJvbU5vZGUsIGNyZWF0ZUVsZW1lbnROUyh0b05vZGUubm9kZU5hbWUsIHRvTm9kZS5uYW1lc3BhY2VVUkkpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gR29pbmcgZnJvbSBhbiBlbGVtZW50IG5vZGUgdG8gYSB0ZXh0IG5vZGVcbiAgICAgICAgICBtb3JwaGVkTm9kZSA9IHRvTm9kZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChtb3JwaGVkTm9kZVR5cGUgPT09IFRFWFRfTk9ERSB8fCBtb3JwaGVkTm9kZVR5cGUgPT09IENPTU1FTlRfTk9ERSkgeyAvLyBUZXh0IG9yIGNvbW1lbnQgbm9kZVxuICAgICAgICBpZiAodG9Ob2RlVHlwZSA9PT0gbW9ycGhlZE5vZGVUeXBlKSB7XG4gICAgICAgICAgaWYgKG1vcnBoZWROb2RlLm5vZGVWYWx1ZSAhPT0gdG9Ob2RlLm5vZGVWYWx1ZSkge1xuICAgICAgICAgICAgbW9ycGhlZE5vZGUubm9kZVZhbHVlID0gdG9Ob2RlLm5vZGVWYWx1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gbW9ycGhlZE5vZGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gVGV4dCBub2RlIHRvIHNvbWV0aGluZyBlbHNlXG4gICAgICAgICAgbW9ycGhlZE5vZGUgPSB0b05vZGU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobW9ycGhlZE5vZGUgPT09IHRvTm9kZSkge1xuICAgICAgLy8gVGhlIFwidG8gbm9kZVwiIHdhcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoZSBcImZyb20gbm9kZVwiIHNvIHdlIGhhZCB0b1xuICAgICAgLy8gdG9zcyBvdXQgdGhlIFwiZnJvbSBub2RlXCIgYW5kIHVzZSB0aGUgXCJ0byBub2RlXCJcbiAgICAgIG9uTm9kZURpc2NhcmRlZChmcm9tTm9kZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0b05vZGUuaXNTYW1lTm9kZSAmJiB0b05vZGUuaXNTYW1lTm9kZShtb3JwaGVkTm9kZSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBtb3JwaEVsKG1vcnBoZWROb2RlLCB0b05vZGUsIGNoaWxkcmVuT25seSk7XG5cbiAgICAgIC8vIFdlIG5vdyBuZWVkIHRvIGxvb3Agb3ZlciBhbnkga2V5ZWQgbm9kZXMgdGhhdCBtaWdodCBuZWVkIHRvIGJlXG4gICAgICAvLyByZW1vdmVkLiBXZSBvbmx5IGRvIHRoZSByZW1vdmFsIGlmIHdlIGtub3cgdGhhdCB0aGUga2V5ZWQgbm9kZVxuICAgICAgLy8gbmV2ZXIgZm91bmQgYSBtYXRjaC4gV2hlbiBhIGtleWVkIG5vZGUgaXMgbWF0Y2hlZCB1cCB3ZSByZW1vdmVcbiAgICAgIC8vIGl0IG91dCBvZiBmcm9tTm9kZXNMb29rdXAgYW5kIHdlIHVzZSBmcm9tTm9kZXNMb29rdXAgdG8gZGV0ZXJtaW5lXG4gICAgICAvLyBpZiBhIGtleWVkIG5vZGUgaGFzIGJlZW4gbWF0Y2hlZCB1cCBvciBub3RcbiAgICAgIGlmIChrZXllZFJlbW92YWxMaXN0KSB7XG4gICAgICAgIGZvciAodmFyIGk9MCwgbGVuPWtleWVkUmVtb3ZhbExpc3QubGVuZ3RoOyBpPGxlbjsgaSsrKSB7XG4gICAgICAgICAgdmFyIGVsVG9SZW1vdmUgPSBmcm9tTm9kZXNMb29rdXBba2V5ZWRSZW1vdmFsTGlzdFtpXV07XG4gICAgICAgICAgaWYgKGVsVG9SZW1vdmUpIHtcbiAgICAgICAgICAgIHJlbW92ZU5vZGUoZWxUb1JlbW92ZSwgZWxUb1JlbW92ZS5wYXJlbnROb2RlLCBmYWxzZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFjaGlsZHJlbk9ubHkgJiYgbW9ycGhlZE5vZGUgIT09IGZyb21Ob2RlICYmIGZyb21Ob2RlLnBhcmVudE5vZGUpIHtcbiAgICAgIGlmIChtb3JwaGVkTm9kZS5hY3R1YWxpemUpIHtcbiAgICAgICAgbW9ycGhlZE5vZGUgPSBtb3JwaGVkTm9kZS5hY3R1YWxpemUoZnJvbU5vZGUub3duZXJEb2N1bWVudCB8fCBkb2MpO1xuICAgICAgfVxuICAgICAgLy8gSWYgd2UgaGFkIHRvIHN3YXAgb3V0IHRoZSBmcm9tIG5vZGUgd2l0aCBhIG5ldyBub2RlIGJlY2F1c2UgdGhlIG9sZFxuICAgICAgLy8gbm9kZSB3YXMgbm90IGNvbXBhdGlibGUgd2l0aCB0aGUgdGFyZ2V0IG5vZGUgdGhlbiB3ZSBuZWVkIHRvXG4gICAgICAvLyByZXBsYWNlIHRoZSBvbGQgRE9NIG5vZGUgaW4gdGhlIG9yaWdpbmFsIERPTSB0cmVlLiBUaGlzIGlzIG9ubHlcbiAgICAgIC8vIHBvc3NpYmxlIGlmIHRoZSBvcmlnaW5hbCBET00gbm9kZSB3YXMgcGFydCBvZiBhIERPTSB0cmVlIHdoaWNoXG4gICAgICAvLyB3ZSBrbm93IGlzIHRoZSBjYXNlIGlmIGl0IGhhcyBhIHBhcmVudCBub2RlLlxuICAgICAgZnJvbU5vZGUucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQobW9ycGhlZE5vZGUsIGZyb21Ob2RlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbW9ycGhlZE5vZGU7XG4gIH07XG59XG5cbnZhciBtb3JwaGRvbSA9IG1vcnBoZG9tRmFjdG9yeShtb3JwaEF0dHJzKTtcblxuZXhwb3J0IGRlZmF1bHQgbW9ycGhkb207XG4iLCAiaW1wb3J0IHtcbiAgUEhYX0NPTVBPTkVOVCxcbiAgUEhYX1BSVU5FLFxuICBQSFhfUk9PVF9JRCxcbiAgUEhYX1NFU1NJT04sXG4gIFBIWF9TS0lQLFxuICBQSFhfTUFHSUNfSUQsXG4gIFBIWF9TVEFUSUMsXG4gIFBIWF9UUklHR0VSX0FDVElPTixcbiAgUEhYX1VQREFURSxcbiAgUEhYX1JFRl9TUkMsXG4gIFBIWF9SRUZfTE9DSyxcbiAgUEhYX1NUUkVBTSxcbiAgUEhYX1NUUkVBTV9SRUYsXG4gIFBIWF9WSUVXUE9SVF9UT1AsXG4gIFBIWF9WSUVXUE9SVF9CT1RUT00sXG4gIFBIWF9QT1JUQUwsXG4gIFBIWF9URUxFUE9SVEVEX1JFRixcbiAgUEhYX1RFTEVQT1JURURfU1JDLFxuICBQSFhfUlVOVElNRV9IT09LLFxufSBmcm9tIFwiLi9jb25zdGFudHNcIjtcblxuaW1wb3J0IHsgZGV0ZWN0RHVwbGljYXRlSWRzLCBkZXRlY3RJbnZhbGlkU3RyZWFtSW5zZXJ0cywgaXNDaWQgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IEVsZW1lbnRSZWYgZnJvbSBcIi4vZWxlbWVudF9yZWZcIjtcbmltcG9ydCBET00gZnJvbSBcIi4vZG9tXCI7XG5pbXBvcnQgRE9NUG9zdE1vcnBoUmVzdG9yZXIgZnJvbSBcIi4vZG9tX3Bvc3RfbW9ycGhfcmVzdG9yZXJcIjtcbmltcG9ydCBtb3JwaGRvbSBmcm9tIFwibW9ycGhkb21cIjtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRE9NUGF0Y2gge1xuICBjb25zdHJ1Y3Rvcih2aWV3LCBjb250YWluZXIsIGlkLCBodG1sLCBzdHJlYW1zLCB0YXJnZXRDSUQsIG9wdHMgPSB7fSkge1xuICAgIHRoaXMudmlldyA9IHZpZXc7XG4gICAgdGhpcy5saXZlU29ja2V0ID0gdmlldy5saXZlU29ja2V0O1xuICAgIHRoaXMuY29udGFpbmVyID0gY29udGFpbmVyO1xuICAgIHRoaXMuaWQgPSBpZDtcbiAgICB0aGlzLnJvb3RJRCA9IHZpZXcucm9vdC5pZDtcbiAgICB0aGlzLmh0bWwgPSBodG1sO1xuICAgIHRoaXMuc3RyZWFtcyA9IHN0cmVhbXM7XG4gICAgdGhpcy5zdHJlYW1JbnNlcnRzID0ge307XG4gICAgdGhpcy5zdHJlYW1Db21wb25lbnRSZXN0b3JlID0ge307XG4gICAgdGhpcy50YXJnZXRDSUQgPSB0YXJnZXRDSUQ7XG4gICAgdGhpcy5jaWRQYXRjaCA9IGlzQ2lkKHRoaXMudGFyZ2V0Q0lEKTtcbiAgICB0aGlzLnBlbmRpbmdSZW1vdmVzID0gW107XG4gICAgdGhpcy5waHhSZW1vdmUgPSB0aGlzLmxpdmVTb2NrZXQuYmluZGluZyhcInJlbW92ZVwiKTtcbiAgICB0aGlzLnRhcmdldENvbnRhaW5lciA9IHRoaXMuaXNDSURQYXRjaCgpXG4gICAgICA/IHRoaXMudGFyZ2V0Q0lEQ29udGFpbmVyKGh0bWwpXG4gICAgICA6IGNvbnRhaW5lcjtcbiAgICB0aGlzLmNhbGxiYWNrcyA9IHtcbiAgICAgIGJlZm9yZWFkZGVkOiBbXSxcbiAgICAgIGJlZm9yZXVwZGF0ZWQ6IFtdLFxuICAgICAgYmVmb3JlcGh4Q2hpbGRBZGRlZDogW10sXG4gICAgICBhZnRlcmFkZGVkOiBbXSxcbiAgICAgIGFmdGVydXBkYXRlZDogW10sXG4gICAgICBhZnRlcmRpc2NhcmRlZDogW10sXG4gICAgICBhZnRlcnBoeENoaWxkQWRkZWQ6IFtdLFxuICAgICAgYWZ0ZXJ0cmFuc2l0aW9uc0Rpc2NhcmRlZDogW10sXG4gICAgfTtcbiAgICB0aGlzLndpdGhDaGlsZHJlbiA9IG9wdHMud2l0aENoaWxkcmVuIHx8IG9wdHMudW5kb1JlZiB8fCBmYWxzZTtcbiAgICB0aGlzLnVuZG9SZWYgPSBvcHRzLnVuZG9SZWY7XG4gIH1cblxuICBiZWZvcmUoa2luZCwgY2FsbGJhY2spIHtcbiAgICB0aGlzLmNhbGxiYWNrc1tgYmVmb3JlJHtraW5kfWBdLnB1c2goY2FsbGJhY2spO1xuICB9XG4gIGFmdGVyKGtpbmQsIGNhbGxiYWNrKSB7XG4gICAgdGhpcy5jYWxsYmFja3NbYGFmdGVyJHtraW5kfWBdLnB1c2goY2FsbGJhY2spO1xuICB9XG5cbiAgdHJhY2tCZWZvcmUoa2luZCwgLi4uYXJncykge1xuICAgIHRoaXMuY2FsbGJhY2tzW2BiZWZvcmUke2tpbmR9YF0uZm9yRWFjaCgoY2FsbGJhY2spID0+IGNhbGxiYWNrKC4uLmFyZ3MpKTtcbiAgfVxuXG4gIHRyYWNrQWZ0ZXIoa2luZCwgLi4uYXJncykge1xuICAgIHRoaXMuY2FsbGJhY2tzW2BhZnRlciR7a2luZH1gXS5mb3JFYWNoKChjYWxsYmFjaykgPT4gY2FsbGJhY2soLi4uYXJncykpO1xuICB9XG5cbiAgbWFya1BydW5hYmxlQ29udGVudEZvclJlbW92YWwoKSB7XG4gICAgY29uc3QgcGh4VXBkYXRlID0gdGhpcy5saXZlU29ja2V0LmJpbmRpbmcoUEhYX1VQREFURSk7XG4gICAgRE9NLmFsbChcbiAgICAgIHRoaXMuY29udGFpbmVyLFxuICAgICAgYFske3BoeFVwZGF0ZX09YXBwZW5kXSA+ICosIFske3BoeFVwZGF0ZX09cHJlcGVuZF0gPiAqYCxcbiAgICAgIChlbCkgPT4ge1xuICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoUEhYX1BSVU5FLCBcIlwiKTtcbiAgICAgIH0sXG4gICAgKTtcbiAgfVxuXG4gIHBlcmZvcm0oaXNKb2luUGF0Y2gpIHtcbiAgICBjb25zdCB7IHZpZXcsIGxpdmVTb2NrZXQsIGh0bWwsIGNvbnRhaW5lciB9ID0gdGhpcztcbiAgICBsZXQgdGFyZ2V0Q29udGFpbmVyID0gdGhpcy50YXJnZXRDb250YWluZXI7XG5cbiAgICBpZiAodGhpcy5pc0NJRFBhdGNoKCkgJiYgIXRoaXMudGFyZ2V0Q29udGFpbmVyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNDSURQYXRjaCgpKSB7XG4gICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vcGhvZW5peGZyYW1ld29yay9waG9lbml4X2xpdmVfdmlldy9wdWxsLzM5NDJcbiAgICAgIC8vIHdlIG5lZWQgdG8gZW5zdXJlIHRoYXQgbm8gcGFyZW50IGlzIGxvY2tlZFxuICAgICAgY29uc3QgY2xvc2VzdExvY2sgPSB0YXJnZXRDb250YWluZXIuY2xvc2VzdChgWyR7UEhYX1JFRl9MT0NLfV1gKTtcbiAgICAgIGlmIChjbG9zZXN0TG9jaykge1xuICAgICAgICBjb25zdCBjbG9uZWRUcmVlID0gRE9NLnByaXZhdGUoY2xvc2VzdExvY2ssIFBIWF9SRUZfTE9DSyk7XG4gICAgICAgIGlmIChjbG9uZWRUcmVlKSB7XG4gICAgICAgICAgLy8gaWYgYSBwYXJlbnQgaXMgbG9ja2VkIHdpdGggYSBjbG9uZWQgdHJlZSwgd2UgbmVlZCB0byBwYXRjaCB0aGUgY2xvbmVkIHRyZWUgaW5zdGVhZFxuICAgICAgICAgIHRhcmdldENvbnRhaW5lciA9IGNsb25lZFRyZWUucXVlcnlTZWxlY3RvcihcbiAgICAgICAgICAgIGBbZGF0YS1waHgtY29tcG9uZW50PVwiJHt0aGlzLnRhcmdldENJRH1cIl1gLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBmb2N1c2VkID0gbGl2ZVNvY2tldC5nZXRBY3RpdmVFbGVtZW50KCk7XG4gICAgY29uc3QgeyBzZWxlY3Rpb25TdGFydCwgc2VsZWN0aW9uRW5kIH0gPVxuICAgICAgZm9jdXNlZCAmJiBET00uaGFzU2VsZWN0aW9uUmFuZ2UoZm9jdXNlZCkgPyBmb2N1c2VkIDoge307XG4gICAgY29uc3QgcGh4VXBkYXRlID0gbGl2ZVNvY2tldC5iaW5kaW5nKFBIWF9VUERBVEUpO1xuICAgIGNvbnN0IHBoeFZpZXdwb3J0VG9wID0gbGl2ZVNvY2tldC5iaW5kaW5nKFBIWF9WSUVXUE9SVF9UT1ApO1xuICAgIGNvbnN0IHBoeFZpZXdwb3J0Qm90dG9tID0gbGl2ZVNvY2tldC5iaW5kaW5nKFBIWF9WSUVXUE9SVF9CT1RUT00pO1xuICAgIGNvbnN0IHBoeFRyaWdnZXJFeHRlcm5hbCA9IGxpdmVTb2NrZXQuYmluZGluZyhQSFhfVFJJR0dFUl9BQ1RJT04pO1xuICAgIGNvbnN0IGFkZGVkID0gW107XG4gICAgY29uc3QgdXBkYXRlcyA9IFtdO1xuICAgIGNvbnN0IGFwcGVuZFByZXBlbmRVcGRhdGVzID0gW107XG5cbiAgICAvLyBhcyB0aGUgcG9ydGFsIHRhcmdldCBpdHNlbGYgY291bGQgYmUgYXQgdGhlIGVuZCBvZiB0aGUgRE9NLFxuICAgIC8vIGl0IG1heSBub3QgYmUgcHJlc2VudCB3aGlsZSBtb3JwaGluZyBwcmV2aW91cyBwYXJ0cztcbiAgICAvLyB0aGVyZWZvcmUgd2UgYXBwbHkgYWxsIHRlbGVwb3J0cyBhZnRlciB0aGUgbW9ycGhpbmcgaXMgZG9uZStcbiAgICBjb25zdCBwb3J0YWxDYWxsYmFja3MgPSBbXTtcblxuICAgIGxldCBleHRlcm5hbEZvcm1UcmlnZ2VyZWQgPSBudWxsO1xuXG4gICAgY29uc3QgbW9ycGggPSAoXG4gICAgICB0YXJnZXRDb250YWluZXIsXG4gICAgICBzb3VyY2UsXG4gICAgICB3aXRoQ2hpbGRyZW4gPSB0aGlzLndpdGhDaGlsZHJlbixcbiAgICApID0+IHtcbiAgICAgIGNvbnN0IG1vcnBoQ2FsbGJhY2tzID0ge1xuICAgICAgICAvLyBub3JtYWxseSwgd2UgYXJlIHJ1bm5pbmcgd2l0aCBjaGlsZHJlbk9ubHksIGFzIHRoZSBwYXRjaCBIVE1MIGZvciBhIExWXG4gICAgICAgIC8vIGRvZXMgbm90IGluY2x1ZGUgdGhlIExWIGF0dHJzIChkYXRhLXBoeC1zZXNzaW9uLCBldGMuKVxuICAgICAgICAvLyB3aGVuIHdlIGFyZSBwYXRjaGluZyBhIGxpdmUgY29tcG9uZW50LCB3ZSBkbyB3YW50IHRvIHBhdGNoIHRoZSByb290IGVsZW1lbnQgYXMgd2VsbDtcbiAgICAgICAgLy8gYW5vdGhlciBjYXNlIGlzIHRoZSByZWN1cnNpdmUgcGF0Y2ggb2YgYSBzdHJlYW0gaXRlbSB0aGF0IHdhcyBrZXB0IG9uIHJlc2V0ICgtPiBvbkJlZm9yZU5vZGVBZGRlZClcbiAgICAgICAgY2hpbGRyZW5Pbmx5OlxuICAgICAgICAgIHRhcmdldENvbnRhaW5lci5nZXRBdHRyaWJ1dGUoUEhYX0NPTVBPTkVOVCkgPT09IG51bGwgJiYgIXdpdGhDaGlsZHJlbixcbiAgICAgICAgZ2V0Tm9kZUtleTogKG5vZGUpID0+IHtcbiAgICAgICAgICBpZiAoRE9NLmlzUGh4RGVzdHJveWVkKG5vZGUpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gSWYgd2UgaGF2ZSBhIGpvaW4gcGF0Y2gsIHRoZW4gYnkgZGVmaW5pdGlvbiB0aGVyZSB3YXMgbm8gUEhYX01BR0lDX0lELlxuICAgICAgICAgIC8vIFRoaXMgaXMgaW1wb3J0YW50IHRvIHJlZHVjZSB0aGUgYW1vdW50IG9mIGVsZW1lbnRzIG1vcnBoZG9tIGRpc2NhcmRzLlxuICAgICAgICAgIGlmIChpc0pvaW5QYXRjaCkge1xuICAgICAgICAgICAgcmV0dXJuIG5vZGUuaWQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBub2RlLmlkIHx8IChub2RlLmdldEF0dHJpYnV0ZSAmJiBub2RlLmdldEF0dHJpYnV0ZShQSFhfTUFHSUNfSUQpKVxuICAgICAgICAgICk7XG4gICAgICAgIH0sXG4gICAgICAgIC8vIHNraXAgaW5kZXhpbmcgZnJvbSBjaGlsZHJlbiB3aGVuIGNvbnRhaW5lciBpcyBzdHJlYW1cbiAgICAgICAgc2tpcEZyb21DaGlsZHJlbjogKGZyb20pID0+IHtcbiAgICAgICAgICByZXR1cm4gZnJvbS5nZXRBdHRyaWJ1dGUocGh4VXBkYXRlKSA9PT0gUEhYX1NUUkVBTTtcbiAgICAgICAgfSxcbiAgICAgICAgLy8gdGVsbCBtb3JwaGRvbSBob3cgdG8gYWRkIGEgY2hpbGRcbiAgICAgICAgYWRkQ2hpbGQ6IChwYXJlbnQsIGNoaWxkKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyByZWYsIHN0cmVhbUF0IH0gPSB0aGlzLmdldFN0cmVhbUluc2VydChjaGlsZCk7XG4gICAgICAgICAgaWYgKHJlZiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFyZW50LmFwcGVuZENoaWxkKGNoaWxkKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLnNldFN0cmVhbVJlZihjaGlsZCwgcmVmKTtcblxuICAgICAgICAgIC8vIHN0cmVhbWluZ1xuICAgICAgICAgIGlmIChzdHJlYW1BdCA9PT0gMCkge1xuICAgICAgICAgICAgcGFyZW50Lmluc2VydEFkamFjZW50RWxlbWVudChcImFmdGVyYmVnaW5cIiwgY2hpbGQpO1xuICAgICAgICAgIH0gZWxzZSBpZiAoc3RyZWFtQXQgPT09IC0xKSB7XG4gICAgICAgICAgICBjb25zdCBsYXN0Q2hpbGQgPSBwYXJlbnQubGFzdEVsZW1lbnRDaGlsZDtcbiAgICAgICAgICAgIGlmIChsYXN0Q2hpbGQgJiYgIWxhc3RDaGlsZC5oYXNBdHRyaWJ1dGUoUEhYX1NUUkVBTV9SRUYpKSB7XG4gICAgICAgICAgICAgIGNvbnN0IG5vblN0cmVhbUNoaWxkID0gQXJyYXkuZnJvbShwYXJlbnQuY2hpbGRyZW4pLmZpbmQoXG4gICAgICAgICAgICAgICAgKGMpID0+ICFjLmhhc0F0dHJpYnV0ZShQSFhfU1RSRUFNX1JFRiksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoY2hpbGQsIG5vblN0cmVhbUNoaWxkKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHBhcmVudC5hcHBlbmRDaGlsZChjaGlsZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChzdHJlYW1BdCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IHNpYmxpbmcgPSBBcnJheS5mcm9tKHBhcmVudC5jaGlsZHJlbilbc3RyZWFtQXRdO1xuICAgICAgICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShjaGlsZCwgc2libGluZyk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBvbkJlZm9yZU5vZGVBZGRlZDogKGVsKSA9PiB7XG4gICAgICAgICAgLy8gZG9uJ3QgYWRkIHVwZGF0ZV9vbmx5IG5vZGVzIGlmIHRoZXkgZGlkIG5vdCBhbHJlYWR5IGV4aXN0XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5nZXRTdHJlYW1JbnNlcnQoZWwpPy51cGRhdGVPbmx5ICYmXG4gICAgICAgICAgICAhdGhpcy5zdHJlYW1Db21wb25lbnRSZXN0b3JlW2VsLmlkXVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIERPTS5tYWludGFpblByaXZhdGVIb29rcyhlbCwgZWwsIHBoeFZpZXdwb3J0VG9wLCBwaHhWaWV3cG9ydEJvdHRvbSk7XG4gICAgICAgICAgdGhpcy50cmFja0JlZm9yZShcImFkZGVkXCIsIGVsKTtcblxuICAgICAgICAgIGxldCBtb3JwaGVkRWwgPSBlbDtcbiAgICAgICAgICAvLyB0aGlzIGlzIGEgc3RyZWFtIGl0ZW0gdGhhdCB3YXMga2VwdCBvbiByZXNldCwgcmVjdXJzaXZlbHkgbW9ycGggaXRcbiAgICAgICAgICBpZiAodGhpcy5zdHJlYW1Db21wb25lbnRSZXN0b3JlW2VsLmlkXSkge1xuICAgICAgICAgICAgbW9ycGhlZEVsID0gdGhpcy5zdHJlYW1Db21wb25lbnRSZXN0b3JlW2VsLmlkXTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbUNvbXBvbmVudFJlc3RvcmVbZWwuaWRdO1xuICAgICAgICAgICAgbW9ycGgobW9ycGhlZEVsLCBlbCwgdHJ1ZSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIG1vcnBoZWRFbDtcbiAgICAgICAgfSxcbiAgICAgICAgb25Ob2RlQWRkZWQ6IChlbCkgPT4ge1xuICAgICAgICAgIGlmIChlbC5nZXRBdHRyaWJ1dGUpIHtcbiAgICAgICAgICAgIHRoaXMubWF5YmVSZU9yZGVyU3RyZWFtKGVsLCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gcGh4LXBvcnRhbCBoYW5kbGluZ1xuICAgICAgICAgIGlmIChET00uaXNQb3J0YWxUZW1wbGF0ZShlbCkpIHtcbiAgICAgICAgICAgIHBvcnRhbENhbGxiYWNrcy5wdXNoKCgpID0+IHRoaXMudGVsZXBvcnQoZWwsIG1vcnBoKSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gaGFjayB0byBmaXggU2FmYXJpIGhhbmRsaW5nIG9mIGltZyBzcmNzZXQgYW5kIHZpZGVvIHRhZ3NcbiAgICAgICAgICBpZiAoZWwgaW5zdGFuY2VvZiBIVE1MSW1hZ2VFbGVtZW50ICYmIGVsLnNyY3NldCkge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtYXNzaWduXG4gICAgICAgICAgICBlbC5zcmNzZXQgPSBlbC5zcmNzZXQ7XG4gICAgICAgICAgfSBlbHNlIGlmIChlbCBpbnN0YW5jZW9mIEhUTUxWaWRlb0VsZW1lbnQgJiYgZWwuYXV0b3BsYXkpIHtcbiAgICAgICAgICAgIGVsLnBsYXkoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKERPTS5pc05vd1RyaWdnZXJGb3JtRXh0ZXJuYWwoZWwsIHBoeFRyaWdnZXJFeHRlcm5hbCkpIHtcbiAgICAgICAgICAgIGV4dGVybmFsRm9ybVRyaWdnZXJlZCA9IGVsO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIG5lc3RlZCB2aWV3IGhhbmRsaW5nXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgKERPTS5pc1BoeENoaWxkKGVsKSAmJiB2aWV3Lm93bnNFbGVtZW50KGVsKSkgfHxcbiAgICAgICAgICAgIChET00uaXNQaHhTdGlja3koZWwpICYmIHZpZXcub3duc0VsZW1lbnQoZWwucGFyZW50Tm9kZSkpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aGlzLnRyYWNrQWZ0ZXIoXCJwaHhDaGlsZEFkZGVkXCIsIGVsKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBkYXRhLXBoeC1ydW50aW1lLWhvb2tcbiAgICAgICAgICBpZiAoZWwubm9kZU5hbWUgPT09IFwiU0NSSVBUXCIgJiYgZWwuaGFzQXR0cmlidXRlKFBIWF9SVU5USU1FX0hPT0spKSB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZVJ1bnRpbWVIb29rKGVsLCBzb3VyY2UpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGFkZGVkLnB1c2goZWwpO1xuICAgICAgICB9LFxuICAgICAgICBvbk5vZGVEaXNjYXJkZWQ6IChlbCkgPT4gdGhpcy5vbk5vZGVEaXNjYXJkZWQoZWwpLFxuICAgICAgICBvbkJlZm9yZU5vZGVEaXNjYXJkZWQ6IChlbCkgPT4ge1xuICAgICAgICAgIGlmIChlbC5nZXRBdHRyaWJ1dGUgJiYgZWwuZ2V0QXR0cmlidXRlKFBIWF9QUlVORSkgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBlbC5wYXJlbnRFbGVtZW50ICE9PSBudWxsICYmXG4gICAgICAgICAgICBlbC5pZCAmJlxuICAgICAgICAgICAgRE9NLmlzUGh4VXBkYXRlKGVsLnBhcmVudEVsZW1lbnQsIHBoeFVwZGF0ZSwgW1xuICAgICAgICAgICAgICBQSFhfU1RSRUFNLFxuICAgICAgICAgICAgICBcImFwcGVuZFwiLFxuICAgICAgICAgICAgICBcInByZXBlbmRcIixcbiAgICAgICAgICAgIF0pXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIGRvbid0IHJlbW92ZSB0ZWxlcG9ydGVkIGVsZW1lbnRzXG4gICAgICAgICAgaWYgKGVsLmdldEF0dHJpYnV0ZSAmJiBlbC5nZXRBdHRyaWJ1dGUoUEhYX1RFTEVQT1JURURfUkVGKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodGhpcy5tYXliZVBlbmRpbmdSZW1vdmUoZWwpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh0aGlzLnNraXBDSURTaWJsaW5nKGVsKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChET00uaXNQb3J0YWxUZW1wbGF0ZShlbCkpIHtcbiAgICAgICAgICAgIC8vIGlmIHRoZSBwb3J0YWwgdGVtcGxhdGUgaXRzZWxmIGlzIHJlbW92ZWQsIHJlbW92ZSB0aGUgdGVsZXBvcnRlZCBlbGVtZW50IGFzIHdlbGw7XG4gICAgICAgICAgICAvLyB3ZSBhbHNvIHBlcmZvcm0gYSBjaGVjayBhZnRlciBtb3JwaGRvbSBpcyBmaW5pc2hlZCB0byBjYXRjaCBwYXJlbnQgcmVtb3ZhbHNcbiAgICAgICAgICAgIGNvbnN0IHRlbGVwb3J0ZWRFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFxuICAgICAgICAgICAgICBlbC5jb250ZW50LmZpcnN0RWxlbWVudENoaWxkLmlkLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmICh0ZWxlcG9ydGVkRWwpIHtcbiAgICAgICAgICAgICAgdGVsZXBvcnRlZEVsLnJlbW92ZSgpO1xuICAgICAgICAgICAgICBtb3JwaENhbGxiYWNrcy5vbk5vZGVEaXNjYXJkZWQodGVsZXBvcnRlZEVsKTtcbiAgICAgICAgICAgICAgdGhpcy52aWV3LmRyb3BQb3J0YWxFbGVtZW50SWQodGVsZXBvcnRlZEVsLmlkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSxcbiAgICAgICAgb25FbFVwZGF0ZWQ6IChlbCkgPT4ge1xuICAgICAgICAgIGlmIChET00uaXNOb3dUcmlnZ2VyRm9ybUV4dGVybmFsKGVsLCBwaHhUcmlnZ2VyRXh0ZXJuYWwpKSB7XG4gICAgICAgICAgICBleHRlcm5hbEZvcm1UcmlnZ2VyZWQgPSBlbDtcbiAgICAgICAgICB9XG4gICAgICAgICAgdXBkYXRlcy5wdXNoKGVsKTtcbiAgICAgICAgICB0aGlzLm1heWJlUmVPcmRlclN0cmVhbShlbCwgZmFsc2UpO1xuICAgICAgICB9LFxuICAgICAgICBvbkJlZm9yZUVsVXBkYXRlZDogKGZyb21FbCwgdG9FbCkgPT4ge1xuICAgICAgICAgIC8vIGlmIHdlIGFyZSBwYXRjaGluZyB0aGUgcm9vdCB0YXJnZXQgY29udGFpbmVyIGFuZCB0aGUgaWQgaGFzIGNoYW5nZWQsIHRyZWF0IGl0IGFzIGEgbmV3IG5vZGVcbiAgICAgICAgICAvLyBieSByZXBsYWNpbmcgdGhlIGZyb21FbCB3aXRoIHRoZSB0b0VsLCB3aGljaCBlbnN1cmVzIGhvb2tzIGFyZSB0b3JuIGRvd24gYW5kIHJlLWNyZWF0ZWRcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBmcm9tRWwuaWQgJiZcbiAgICAgICAgICAgIGZyb21FbC5pc1NhbWVOb2RlKHRhcmdldENvbnRhaW5lcikgJiZcbiAgICAgICAgICAgIGZyb21FbC5pZCAhPT0gdG9FbC5pZFxuICAgICAgICAgICkge1xuICAgICAgICAgICAgbW9ycGhDYWxsYmFja3Mub25Ob2RlRGlzY2FyZGVkKGZyb21FbCk7XG4gICAgICAgICAgICBmcm9tRWwucmVwbGFjZVdpdGgodG9FbCk7XG4gICAgICAgICAgICByZXR1cm4gbW9ycGhDYWxsYmFja3Mub25Ob2RlQWRkZWQodG9FbCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIERPTS5zeW5jUGVuZGluZ0F0dHJzKGZyb21FbCwgdG9FbCk7XG4gICAgICAgICAgRE9NLm1haW50YWluUHJpdmF0ZUhvb2tzKFxuICAgICAgICAgICAgZnJvbUVsLFxuICAgICAgICAgICAgdG9FbCxcbiAgICAgICAgICAgIHBoeFZpZXdwb3J0VG9wLFxuICAgICAgICAgICAgcGh4Vmlld3BvcnRCb3R0b20sXG4gICAgICAgICAgKTtcbiAgICAgICAgICBET00uY2xlYW5DaGlsZE5vZGVzKHRvRWwsIHBoeFVwZGF0ZSk7XG4gICAgICAgICAgaWYgKHRoaXMuc2tpcENJRFNpYmxpbmcodG9FbCkpIHtcbiAgICAgICAgICAgIC8vIGlmIHRoaXMgaXMgYSBsaXZlIGNvbXBvbmVudCB1c2VkIGluIGEgc3RyZWFtLCB3ZSBtYXkgbmVlZCB0byByZW9yZGVyIGl0XG4gICAgICAgICAgICB0aGlzLm1heWJlUmVPcmRlclN0cmVhbShmcm9tRWwpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoRE9NLmlzUGh4U3RpY2t5KGZyb21FbCkpIHtcbiAgICAgICAgICAgIFtQSFhfU0VTU0lPTiwgUEhYX1NUQVRJQywgUEhYX1JPT1RfSURdXG4gICAgICAgICAgICAgIC5tYXAoKGF0dHIpID0+IFtcbiAgICAgICAgICAgICAgICBhdHRyLFxuICAgICAgICAgICAgICAgIGZyb21FbC5nZXRBdHRyaWJ1dGUoYXR0ciksXG4gICAgICAgICAgICAgICAgdG9FbC5nZXRBdHRyaWJ1dGUoYXR0ciksXG4gICAgICAgICAgICAgIF0pXG4gICAgICAgICAgICAgIC5mb3JFYWNoKChbYXR0ciwgZnJvbVZhbCwgdG9WYWxdKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRvVmFsICYmIGZyb21WYWwgIT09IHRvVmFsKSB7XG4gICAgICAgICAgICAgICAgICBmcm9tRWwuc2V0QXR0cmlidXRlKGF0dHIsIHRvVmFsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIERPTS5pc0lnbm9yZWQoZnJvbUVsLCBwaHhVcGRhdGUpIHx8XG4gICAgICAgICAgICAoZnJvbUVsLmZvcm0gJiYgZnJvbUVsLmZvcm0uaXNTYW1lTm9kZShleHRlcm5hbEZvcm1UcmlnZ2VyZWQpKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy50cmFja0JlZm9yZShcInVwZGF0ZWRcIiwgZnJvbUVsLCB0b0VsKTtcbiAgICAgICAgICAgIERPTS5tZXJnZUF0dHJzKGZyb21FbCwgdG9FbCwge1xuICAgICAgICAgICAgICBpc0lnbm9yZWQ6IERPTS5pc0lnbm9yZWQoZnJvbUVsLCBwaHhVcGRhdGUpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB1cGRhdGVzLnB1c2goZnJvbUVsKTtcbiAgICAgICAgICAgIERPTS5hcHBseVN0aWNreU9wZXJhdGlvbnMoZnJvbUVsKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgZnJvbUVsLnR5cGUgPT09IFwibnVtYmVyXCIgJiZcbiAgICAgICAgICAgIGZyb21FbC52YWxpZGl0eSAmJlxuICAgICAgICAgICAgZnJvbUVsLnZhbGlkaXR5LmJhZElucHV0XG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIElmIHRoZSBlbGVtZW50IGhhcyBQSFhfUkVGX1NSQywgaXQgaXMgbG9hZGluZyBvciBsb2NrZWQgYW5kIGF3YWl0aW5nIGFuIGFjay5cbiAgICAgICAgICAvLyBJZiBpdCdzIGxvY2tlZCwgd2UgY2xvbmUgdGhlIGZyb21FbCB0cmVlIGFuZCBpbnN0cnVjdCBtb3JwaGRvbSB0byB1c2VcbiAgICAgICAgICAvLyB0aGUgY2xvbmVkIHRyZWUgYXMgdGhlIHNvdXJjZSBvZiB0aGUgbW9ycGggZm9yIHRoaXMgYnJhbmNoIGZyb20gaGVyZSBvbiBvdXQuXG4gICAgICAgICAgLy8gV2Uga2VlcCBhIHJlZmVyZW5jZSB0byB0aGUgY2xvbmVkIHRyZWUgaW4gdGhlIGVsZW1lbnQncyBwcml2YXRlIGRhdGEsIGFuZFxuICAgICAgICAgIC8vIG9uIGFjayAodmlldy51bmRvUmVmcyksIHdlIG1vcnBoIHRoZSBjbG9uZWQgdHJlZSB3aXRoIHRoZSB0cnVlIGZyb21FbCBpbiB0aGUgRE9NIHRvXG4gICAgICAgICAgLy8gYXBwbHkgYW55IGNoYW5nZXMgdGhhdCBoYXBwZW5lZCB3aGlsZSB0aGUgZWxlbWVudCB3YXMgbG9ja2VkLlxuICAgICAgICAgIGNvbnN0IGlzRm9jdXNlZEZvcm1FbCA9XG4gICAgICAgICAgICBmb2N1c2VkICYmIGZyb21FbC5pc1NhbWVOb2RlKGZvY3VzZWQpICYmIERPTS5pc0Zvcm1JbnB1dChmcm9tRWwpO1xuICAgICAgICAgIGNvbnN0IGZvY3VzZWRTZWxlY3RDaGFuZ2VkID1cbiAgICAgICAgICAgIGlzRm9jdXNlZEZvcm1FbCAmJiB0aGlzLmlzQ2hhbmdlZFNlbGVjdChmcm9tRWwsIHRvRWwpO1xuICAgICAgICAgIGlmIChmcm9tRWwuaGFzQXR0cmlidXRlKFBIWF9SRUZfU1JDKSkge1xuICAgICAgICAgICAgY29uc3QgcmVmID0gbmV3IEVsZW1lbnRSZWYoZnJvbUVsKTtcbiAgICAgICAgICAgIC8vIG9ubHkgcGVyZm9ybSB0aGUgY2xvbmUgc3RlcCBpZiB0aGlzIGlzIG5vdCBhIHBhdGNoIHRoYXQgdW5sb2Nrc1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICByZWYubG9ja1JlZiAmJlxuICAgICAgICAgICAgICAoIXRoaXMudW5kb1JlZiB8fCAhcmVmLmlzTG9ja1VuZG9uZUJ5KHRoaXMudW5kb1JlZikpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgaWYgKERPTS5pc1VwbG9hZElucHV0KGZyb21FbCkpIHtcbiAgICAgICAgICAgICAgICBET00ubWVyZ2VBdHRycyhmcm9tRWwsIHRvRWwsIHsgaXNJZ25vcmVkOiB0cnVlIH0pO1xuICAgICAgICAgICAgICAgIHRoaXMudHJhY2tCZWZvcmUoXCJ1cGRhdGVkXCIsIGZyb21FbCwgdG9FbCk7XG4gICAgICAgICAgICAgICAgdXBkYXRlcy5wdXNoKGZyb21FbCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgRE9NLmFwcGx5U3RpY2t5T3BlcmF0aW9ucyhmcm9tRWwpO1xuICAgICAgICAgICAgICBjb25zdCBpc0xvY2tlZCA9IGZyb21FbC5oYXNBdHRyaWJ1dGUoUEhYX1JFRl9MT0NLKTtcbiAgICAgICAgICAgICAgY29uc3QgY2xvbmUgPSBpc0xvY2tlZFxuICAgICAgICAgICAgICAgID8gRE9NLnByaXZhdGUoZnJvbUVsLCBQSFhfUkVGX0xPQ0spIHx8IGZyb21FbC5jbG9uZU5vZGUodHJ1ZSlcbiAgICAgICAgICAgICAgICA6IG51bGw7XG4gICAgICAgICAgICAgIGlmIChjbG9uZSkge1xuICAgICAgICAgICAgICAgIERPTS5wdXRQcml2YXRlKGZyb21FbCwgUEhYX1JFRl9MT0NLLCBjbG9uZSk7XG4gICAgICAgICAgICAgICAgaWYgKCFpc0ZvY3VzZWRGb3JtRWwpIHtcbiAgICAgICAgICAgICAgICAgIGZyb21FbCA9IGNsb25lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIG5lc3RlZCB2aWV3IGhhbmRsaW5nXG4gICAgICAgICAgaWYgKERPTS5pc1BoeENoaWxkKHRvRWwpKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2U2Vzc2lvbiA9IGZyb21FbC5nZXRBdHRyaWJ1dGUoUEhYX1NFU1NJT04pO1xuICAgICAgICAgICAgRE9NLm1lcmdlQXR0cnMoZnJvbUVsLCB0b0VsLCB7IGV4Y2x1ZGU6IFtQSFhfU1RBVElDXSB9KTtcbiAgICAgICAgICAgIGlmIChwcmV2U2Vzc2lvbiAhPT0gXCJcIikge1xuICAgICAgICAgICAgICBmcm9tRWwuc2V0QXR0cmlidXRlKFBIWF9TRVNTSU9OLCBwcmV2U2Vzc2lvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmcm9tRWwuc2V0QXR0cmlidXRlKFBIWF9ST09UX0lELCB0aGlzLnJvb3RJRCk7XG4gICAgICAgICAgICBET00uYXBwbHlTdGlja3lPcGVyYXRpb25zKGZyb21FbCk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gaWYgd2UgYXJlIHVuZG9pbmcgYSBsb2NrLCBjb3B5IHBvdGVudGlhbGx5IG5lc3RlZCBjbG9uZXMgb3ZlclxuICAgICAgICAgIGlmICh0aGlzLnVuZG9SZWYgJiYgRE9NLnByaXZhdGUodG9FbCwgUEhYX1JFRl9MT0NLKSkge1xuICAgICAgICAgICAgRE9NLnB1dFByaXZhdGUoXG4gICAgICAgICAgICAgIGZyb21FbCxcbiAgICAgICAgICAgICAgUEhYX1JFRl9MT0NLLFxuICAgICAgICAgICAgICBET00ucHJpdmF0ZSh0b0VsLCBQSFhfUkVGX0xPQ0spLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gbm93IGNvcHkgcmVndWxhciBET00ucHJpdmF0ZSBkYXRhXG4gICAgICAgICAgRE9NLmNvcHlQcml2YXRlcyh0b0VsLCBmcm9tRWwpO1xuXG4gICAgICAgICAgLy8gcGh4LXBvcnRhbCBoYW5kbGluZ1xuICAgICAgICAgIGlmIChET00uaXNQb3J0YWxUZW1wbGF0ZSh0b0VsKSkge1xuICAgICAgICAgICAgcG9ydGFsQ2FsbGJhY2tzLnB1c2goKCkgPT4gdGhpcy50ZWxlcG9ydCh0b0VsLCBtb3JwaCkpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIHNraXAgcGF0Y2hpbmcgZm9jdXNlZCBpbnB1dHMgdW5sZXNzIGZvY3VzIGlzIGEgc2VsZWN0IHRoYXQgaGFzIGNoYW5nZWQgb3B0aW9uc1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGlzRm9jdXNlZEZvcm1FbCAmJlxuICAgICAgICAgICAgZnJvbUVsLnR5cGUgIT09IFwiaGlkZGVuXCIgJiZcbiAgICAgICAgICAgICFmb2N1c2VkU2VsZWN0Q2hhbmdlZFxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy50cmFja0JlZm9yZShcInVwZGF0ZWRcIiwgZnJvbUVsLCB0b0VsKTtcbiAgICAgICAgICAgIERPTS5tZXJnZUZvY3VzZWRJbnB1dChmcm9tRWwsIHRvRWwpO1xuICAgICAgICAgICAgRE9NLnN5bmNBdHRyc1RvUHJvcHMoZnJvbUVsKTtcbiAgICAgICAgICAgIHVwZGF0ZXMucHVzaChmcm9tRWwpO1xuICAgICAgICAgICAgRE9NLmFwcGx5U3RpY2t5T3BlcmF0aW9ucyhmcm9tRWwpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBibHVyIGZvY3VzZWQgc2VsZWN0IGlmIGl0IGNoYW5nZWQgc28gbmF0aXZlIFVJIGlzIHVwZGF0ZWQgKGllIHNhZmFyaSB3b24ndCB1cGRhdGUgdmlzaWJsZSBvcHRpb25zKVxuICAgICAgICAgICAgaWYgKGZvY3VzZWRTZWxlY3RDaGFuZ2VkKSB7XG4gICAgICAgICAgICAgIGZyb21FbC5ibHVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoRE9NLmlzUGh4VXBkYXRlKHRvRWwsIHBoeFVwZGF0ZSwgW1wiYXBwZW5kXCIsIFwicHJlcGVuZFwiXSkpIHtcbiAgICAgICAgICAgICAgYXBwZW5kUHJlcGVuZFVwZGF0ZXMucHVzaChcbiAgICAgICAgICAgICAgICBuZXcgRE9NUG9zdE1vcnBoUmVzdG9yZXIoXG4gICAgICAgICAgICAgICAgICBmcm9tRWwsXG4gICAgICAgICAgICAgICAgICB0b0VsLFxuICAgICAgICAgICAgICAgICAgdG9FbC5nZXRBdHRyaWJ1dGUocGh4VXBkYXRlKSxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBET00uc3luY0F0dHJzVG9Qcm9wcyh0b0VsKTtcbiAgICAgICAgICAgIERPTS5hcHBseVN0aWNreU9wZXJhdGlvbnModG9FbCk7XG4gICAgICAgICAgICB0aGlzLnRyYWNrQmVmb3JlKFwidXBkYXRlZFwiLCBmcm9tRWwsIHRvRWwpO1xuICAgICAgICAgICAgcmV0dXJuIGZyb21FbDtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBtb3JwaGRvbSh0YXJnZXRDb250YWluZXIsIHNvdXJjZSwgbW9ycGhDYWxsYmFja3MpO1xuICAgIH07XG5cbiAgICB0aGlzLnRyYWNrQmVmb3JlKFwiYWRkZWRcIiwgY29udGFpbmVyKTtcbiAgICB0aGlzLnRyYWNrQmVmb3JlKFwidXBkYXRlZFwiLCBjb250YWluZXIsIGNvbnRhaW5lcik7XG5cbiAgICBsaXZlU29ja2V0LnRpbWUoXCJtb3JwaGRvbVwiLCAoKSA9PiB7XG4gICAgICB0aGlzLnN0cmVhbXMuZm9yRWFjaCgoW3JlZiwgaW5zZXJ0cywgZGVsZXRlSWRzLCByZXNldF0pID0+IHtcbiAgICAgICAgaW5zZXJ0cy5mb3JFYWNoKChba2V5LCBzdHJlYW1BdCwgbGltaXQsIHVwZGF0ZU9ubHldKSA9PiB7XG4gICAgICAgICAgdGhpcy5zdHJlYW1JbnNlcnRzW2tleV0gPSB7IHJlZiwgc3RyZWFtQXQsIGxpbWl0LCByZXNldCwgdXBkYXRlT25seSB9O1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHJlc2V0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBET00uYWxsKGNvbnRhaW5lciwgYFske1BIWF9TVFJFQU1fUkVGfT1cIiR7cmVmfVwiXWAsIChjaGlsZCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVTdHJlYW1DaGlsZEVsZW1lbnQoY2hpbGQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGRlbGV0ZUlkcy5mb3JFYWNoKChpZCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNoaWxkID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoYFtpZD1cIiR7aWR9XCJdYCk7XG4gICAgICAgICAgaWYgKGNoaWxkKSB7XG4gICAgICAgICAgICB0aGlzLnJlbW92ZVN0cmVhbUNoaWxkRWxlbWVudChjaGlsZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBjbGVhciBzdHJlYW0gaXRlbXMgZnJvbSB0aGUgZGVhZCByZW5kZXIgaWYgdGhleSBhcmUgbm90IGluc2VydGVkIGFnYWluXG4gICAgICBpZiAoaXNKb2luUGF0Y2gpIHtcbiAgICAgICAgRE9NLmFsbCh0aGlzLmNvbnRhaW5lciwgYFske3BoeFVwZGF0ZX09JHtQSFhfU1RSRUFNfV1gKVxuICAgICAgICAgIC8vIGl0IGlzIGltcG9ydGFudCB0byBmaWx0ZXIgdGhlIGVsZW1lbnQgYmVmb3JlIHJlbW92aW5nIHRoZW0sIGFzXG4gICAgICAgICAgLy8gaXQgbWF5IGhhcHBlbiB0aGF0IHN0cmVhbXMgYXJlIG5lc3RlZCBhbmQgdGhlIG93bmVyIGNoZWNrIGZhaWxzIGlmXG4gICAgICAgICAgLy8gYSBwYXJlbnQgaXMgcmVtb3ZlZCBiZWZvcmUgYSBjaGlsZFxuICAgICAgICAgIC5maWx0ZXIoKGVsKSA9PiB0aGlzLnZpZXcub3duc0VsZW1lbnQoZWwpKVxuICAgICAgICAgIC5mb3JFYWNoKChlbCkgPT4ge1xuICAgICAgICAgICAgQXJyYXkuZnJvbShlbC5jaGlsZHJlbikuZm9yRWFjaCgoY2hpbGQpID0+IHtcbiAgICAgICAgICAgICAgLy8gd2UgYWxyZWFkeSBwZXJmb3JtZWQgdGhlIG93bmVyIGNoZWNrLCBlYWNoIGNoaWxkIGlzIGd1YXJhbnRlZWQgdG8gYmUgb3duZWRcbiAgICAgICAgICAgICAgLy8gYnkgdGhlIHZpZXcuIFRvIHByZXZlbnQgdGhlIG5lc3RlZCBvd25lciBjaGVjayBmcm9tIGZhaWxpbmcgaW4gY2FzZSBvZiBuZXN0ZWRcbiAgICAgICAgICAgICAgLy8gc3RyZWFtcyB3aGVyZSB0aGUgcGFyZW50IGlzIHJlbW92ZWQgYmVmb3JlIHRoZSBjaGlsZCwgd2UgZm9yY2UgdGhlIHJlbW92YWxcbiAgICAgICAgICAgICAgdGhpcy5yZW1vdmVTdHJlYW1DaGlsZEVsZW1lbnQoY2hpbGQsIHRydWUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIG1vcnBoKHRhcmdldENvbnRhaW5lciwgaHRtbCk7XG4gICAgICAvLyBub3JtYWwgcGF0Y2ggY29tcGxldGUsIHRlbGVwb3J0IGVsZW1lbnRzIG5vd1xuICAgICAgcG9ydGFsQ2FsbGJhY2tzLmZvckVhY2goKGNhbGxiYWNrKSA9PiBjYWxsYmFjaygpKTtcbiAgICAgIC8vIGNoZWNrIGZvciBhbnkgdGVsZXBvcnRlZCBlbGVtZW50cyB0aGF0IGFyZSBub3QgaW4gdGhlIHZpZXcgYW55IG1vcmVcbiAgICAgIC8vIGFuZCByZW1vdmUgdGhlbVxuICAgICAgdGhpcy52aWV3LnBvcnRhbEVsZW1lbnRJZHMuZm9yRWFjaCgoaWQpID0+IHtcbiAgICAgICAgY29uc3QgZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7XG4gICAgICAgIGlmIChlbCkge1xuICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFxuICAgICAgICAgICAgZWwuZ2V0QXR0cmlidXRlKFBIWF9URUxFUE9SVEVEX1NSQyksXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoIXNvdXJjZSkge1xuICAgICAgICAgICAgZWwucmVtb3ZlKCk7XG4gICAgICAgICAgICB0aGlzLm9uTm9kZURpc2NhcmRlZChlbCk7XG4gICAgICAgICAgICB0aGlzLnZpZXcuZHJvcFBvcnRhbEVsZW1lbnRJZChpZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGlmIChsaXZlU29ja2V0LmlzRGVidWdFbmFibGVkKCkpIHtcbiAgICAgIGRldGVjdER1cGxpY2F0ZUlkcygpO1xuICAgICAgZGV0ZWN0SW52YWxpZFN0cmVhbUluc2VydHModGhpcy5zdHJlYW1JbnNlcnRzKTtcbiAgICAgIC8vIHdhcm4gaWYgdGhlcmUgYXJlIGFueSBpbnB1dHMgbmFtZWQgXCJpZFwiXG4gICAgICBBcnJheS5mcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJpbnB1dFtuYW1lPWlkXVwiKSkuZm9yRWFjaChcbiAgICAgICAgKG5vZGUpID0+IHtcbiAgICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQgJiYgbm9kZS5mb3JtKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICAgICAnRGV0ZWN0ZWQgYW4gaW5wdXQgd2l0aCBuYW1lPVwiaWRcIiBpbnNpZGUgYSBmb3JtISBUaGlzIHdpbGwgY2F1c2UgcHJvYmxlbXMgd2hlbiBwYXRjaGluZyB0aGUgRE9NLlxcbicsXG4gICAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGFwcGVuZFByZXBlbmRVcGRhdGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGxpdmVTb2NrZXQudGltZShcInBvc3QtbW9ycGggYXBwZW5kL3ByZXBlbmQgcmVzdG9yYXRpb25cIiwgKCkgPT4ge1xuICAgICAgICBhcHBlbmRQcmVwZW5kVXBkYXRlcy5mb3JFYWNoKCh1cGRhdGUpID0+IHVwZGF0ZS5wZXJmb3JtKCkpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgbGl2ZVNvY2tldC5zaWxlbmNlRXZlbnRzKCgpID0+XG4gICAgICBET00ucmVzdG9yZUZvY3VzKGZvY3VzZWQsIHNlbGVjdGlvblN0YXJ0LCBzZWxlY3Rpb25FbmQpLFxuICAgICk7XG4gICAgRE9NLmRpc3BhdGNoRXZlbnQoZG9jdW1lbnQsIFwicGh4OnVwZGF0ZVwiKTtcbiAgICBhZGRlZC5mb3JFYWNoKChlbCkgPT4gdGhpcy50cmFja0FmdGVyKFwiYWRkZWRcIiwgZWwpKTtcbiAgICB1cGRhdGVzLmZvckVhY2goKGVsKSA9PiB0aGlzLnRyYWNrQWZ0ZXIoXCJ1cGRhdGVkXCIsIGVsKSk7XG5cbiAgICB0aGlzLnRyYW5zaXRpb25QZW5kaW5nUmVtb3ZlcygpO1xuXG4gICAgaWYgKGV4dGVybmFsRm9ybVRyaWdnZXJlZCkge1xuICAgICAgbGl2ZVNvY2tldC51bmxvYWQoKTtcbiAgICAgIC8vIGNoZWNrIGZvciBzdWJtaXR0ZXIgYW5kIGluamVjdCBpdCBhcyBoaWRkZW4gaW5wdXQgZm9yIGV4dGVybmFsIHN1Ym1pdDtcbiAgICAgIC8vIEluIHRoZW9yeSwgaXQgY291bGQgaGFwcGVuIHRoYXQgdGhlIHN0b3JlZCBzdWJtaXR0ZXIgaXMgb3V0ZGF0ZWQgYW5kIGRvZXNuJ3RcbiAgICAgIC8vIGV4aXN0IGluIHRoZSBET00gYW55IG1vcmUsIGJ1dCB0aGlzIGlzIHVubGlrZWx5LCBzbyB3ZSBqdXN0IGFjY2VwdCBpdCBmb3Igbm93LlxuICAgICAgY29uc3Qgc3VibWl0dGVyID0gRE9NLnByaXZhdGUoZXh0ZXJuYWxGb3JtVHJpZ2dlcmVkLCBcInN1Ym1pdHRlclwiKTtcbiAgICAgIGlmIChzdWJtaXR0ZXIgJiYgc3VibWl0dGVyLm5hbWUgJiYgdGFyZ2V0Q29udGFpbmVyLmNvbnRhaW5zKHN1Ym1pdHRlcikpIHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIik7XG4gICAgICAgIGlucHV0LnR5cGUgPSBcImhpZGRlblwiO1xuICAgICAgICBjb25zdCBmb3JtSWQgPSBzdWJtaXR0ZXIuZ2V0QXR0cmlidXRlKFwiZm9ybVwiKTtcbiAgICAgICAgaWYgKGZvcm1JZCkge1xuICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZShcImZvcm1cIiwgZm9ybUlkKTtcbiAgICAgICAgfVxuICAgICAgICBpbnB1dC5uYW1lID0gc3VibWl0dGVyLm5hbWU7XG4gICAgICAgIGlucHV0LnZhbHVlID0gc3VibWl0dGVyLnZhbHVlO1xuICAgICAgICBzdWJtaXR0ZXIucGFyZW50RWxlbWVudC5pbnNlcnRCZWZvcmUoaW5wdXQsIHN1Ym1pdHRlcik7XG4gICAgICB9XG4gICAgICAvLyB1c2UgcHJvdG90eXBlJ3Mgc3VibWl0IGluIGNhc2UgdGhlcmUncyBhIGZvcm0gY29udHJvbCB3aXRoIG5hbWUgb3IgaWQgb2YgXCJzdWJtaXRcIlxuICAgICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0hUTUxGb3JtRWxlbWVudC9zdWJtaXRcbiAgICAgIE9iamVjdC5nZXRQcm90b3R5cGVPZihleHRlcm5hbEZvcm1UcmlnZ2VyZWQpLnN1Ym1pdC5jYWxsKFxuICAgICAgICBleHRlcm5hbEZvcm1UcmlnZ2VyZWQsXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIG9uTm9kZURpc2NhcmRlZChlbCkge1xuICAgIC8vIG5lc3RlZCB2aWV3IGhhbmRsaW5nXG4gICAgaWYgKERPTS5pc1BoeENoaWxkKGVsKSB8fCBET00uaXNQaHhTdGlja3koZWwpKSB7XG4gICAgICB0aGlzLmxpdmVTb2NrZXQuZGVzdHJveVZpZXdCeUVsKGVsKTtcbiAgICB9XG4gICAgdGhpcy50cmFja0FmdGVyKFwiZGlzY2FyZGVkXCIsIGVsKTtcbiAgfVxuXG4gIG1heWJlUGVuZGluZ1JlbW92ZShub2RlKSB7XG4gICAgaWYgKG5vZGUuZ2V0QXR0cmlidXRlICYmIG5vZGUuZ2V0QXR0cmlidXRlKHRoaXMucGh4UmVtb3ZlKSAhPT0gbnVsbCkge1xuICAgICAgdGhpcy5wZW5kaW5nUmVtb3Zlcy5wdXNoKG5vZGUpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZW1vdmVTdHJlYW1DaGlsZEVsZW1lbnQoY2hpbGQsIGZvcmNlID0gZmFsc2UpIHtcbiAgICAvLyBtYWtlIHN1cmUgdG8gb25seSByZW1vdmUgZWxlbWVudHMgb3duZWQgYnkgdGhlIGN1cnJlbnQgdmlld1xuICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vcGhvZW5peGZyYW1ld29yay9waG9lbml4X2xpdmVfdmlldy9pc3N1ZXMvMzA0N1xuICAgIC8vIGFuZCBodHRwczovL2dpdGh1Yi5jb20vcGhvZW5peGZyYW1ld29yay9waG9lbml4X2xpdmVfdmlldy9pc3N1ZXMvMzY4MVxuICAgIGlmICghZm9yY2UgJiYgIXRoaXMudmlldy5vd25zRWxlbWVudChjaGlsZCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyB3ZSBuZWVkIHRvIHN0b3JlIHRoZSBub2RlIGlmIGl0IGlzIGFjdHVhbGx5IHJlLWFkZGVkIGluIHRoZSBzYW1lIHBhdGNoXG4gICAgLy8gd2UgZG8gTk9UIHdhbnQgdG8gZXhlY3V0ZSBwaHgtcmVtb3ZlLCB3ZSBkbyBOT1Qgd2FudCB0byBjYWxsIG9uTm9kZURpc2NhcmRlZFxuICAgIGlmICh0aGlzLnN0cmVhbUluc2VydHNbY2hpbGQuaWRdKSB7XG4gICAgICB0aGlzLnN0cmVhbUNvbXBvbmVudFJlc3RvcmVbY2hpbGQuaWRdID0gY2hpbGQ7XG4gICAgICBjaGlsZC5yZW1vdmUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gb25seSByZW1vdmUgdGhlIGVsZW1lbnQgbm93IGlmIGl0IGhhcyBubyBwaHgtcmVtb3ZlIGJpbmRpbmdcbiAgICAgIGlmICghdGhpcy5tYXliZVBlbmRpbmdSZW1vdmUoY2hpbGQpKSB7XG4gICAgICAgIGNoaWxkLnJlbW92ZSgpO1xuICAgICAgICB0aGlzLm9uTm9kZURpc2NhcmRlZChjaGlsZCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0U3RyZWFtSW5zZXJ0KGVsKSB7XG4gICAgY29uc3QgaW5zZXJ0ID0gZWwuaWQgPyB0aGlzLnN0cmVhbUluc2VydHNbZWwuaWRdIDoge307XG4gICAgcmV0dXJuIGluc2VydCB8fCB7fTtcbiAgfVxuXG4gIHNldFN0cmVhbVJlZihlbCwgcmVmKSB7XG4gICAgRE9NLnB1dFN0aWNreShlbCwgUEhYX1NUUkVBTV9SRUYsIChlbCkgPT5cbiAgICAgIGVsLnNldEF0dHJpYnV0ZShQSFhfU1RSRUFNX1JFRiwgcmVmKSxcbiAgICApO1xuICB9XG5cbiAgbWF5YmVSZU9yZGVyU3RyZWFtKGVsLCBpc05ldykge1xuICAgIGNvbnN0IHsgcmVmLCBzdHJlYW1BdCwgcmVzZXQgfSA9IHRoaXMuZ2V0U3RyZWFtSW5zZXJ0KGVsKTtcbiAgICBpZiAoc3RyZWFtQXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHdlIG5lZWQgdG8gc2V0IHRoZSBQSFhfU1RSRUFNX1JFRiBoZXJlIGFzIHdlbGwgYXMgYWRkQ2hpbGQgaXMgaW52b2tlZCBvbmx5IGZvciBwYXJlbnRzXG4gICAgdGhpcy5zZXRTdHJlYW1SZWYoZWwsIHJlZik7XG5cbiAgICBpZiAoIXJlc2V0ICYmICFpc05ldykge1xuICAgICAgLy8gd2Ugb25seSByZW9yZGVyIGlmIHRoZSBlbGVtZW50IGlzIG5ldyBvciBpdCdzIGEgc3RyZWFtIHJlc2V0XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gY2hlY2sgaWYgdGhlIGVsZW1lbnQgaGFzIGEgcGFyZW50IGVsZW1lbnQ7XG4gICAgLy8gaXQgZG9lc24ndCBpZiB3ZSBhcmUgY3VycmVudGx5IHJlY3Vyc2l2ZWx5IG1vcnBoaW5nIChyZXN0b3JpbmcgYSBzYXZlZCBzdHJlYW0gY2hpbGQpXG4gICAgLy8gYmVjYXVzZSB0aGUgZWxlbWVudCBpcyBub3QgeWV0IGFkZGVkIHRvIHRoZSByZWFsIGRvbTtcbiAgICAvLyByZW9yZGVyaW5nIGRvZXMgbm90IG1ha2Ugc2Vuc2UgaW4gdGhhdCBjYXNlIGFueXdheVxuICAgIGlmICghZWwucGFyZW50RWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChzdHJlYW1BdCA9PT0gMCkge1xuICAgICAgZWwucGFyZW50RWxlbWVudC5pbnNlcnRCZWZvcmUoZWwsIGVsLnBhcmVudEVsZW1lbnQuZmlyc3RFbGVtZW50Q2hpbGQpO1xuICAgIH0gZWxzZSBpZiAoc3RyZWFtQXQgPiAwKSB7XG4gICAgICBjb25zdCBjaGlsZHJlbiA9IEFycmF5LmZyb20oZWwucGFyZW50RWxlbWVudC5jaGlsZHJlbik7XG4gICAgICBjb25zdCBvbGRJbmRleCA9IGNoaWxkcmVuLmluZGV4T2YoZWwpO1xuICAgICAgaWYgKHN0cmVhbUF0ID49IGNoaWxkcmVuLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgZWwucGFyZW50RWxlbWVudC5hcHBlbmRDaGlsZChlbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBzaWJsaW5nID0gY2hpbGRyZW5bc3RyZWFtQXRdO1xuICAgICAgICBpZiAob2xkSW5kZXggPiBzdHJlYW1BdCkge1xuICAgICAgICAgIGVsLnBhcmVudEVsZW1lbnQuaW5zZXJ0QmVmb3JlKGVsLCBzaWJsaW5nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBlbC5wYXJlbnRFbGVtZW50Lmluc2VydEJlZm9yZShlbCwgc2libGluZy5uZXh0RWxlbWVudFNpYmxpbmcpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5tYXliZUxpbWl0U3RyZWFtKGVsKTtcbiAgfVxuXG4gIG1heWJlTGltaXRTdHJlYW0oZWwpIHtcbiAgICBjb25zdCB7IGxpbWl0IH0gPSB0aGlzLmdldFN0cmVhbUluc2VydChlbCk7XG4gICAgY29uc3QgY2hpbGRyZW4gPSBsaW1pdCAhPT0gbnVsbCAmJiBBcnJheS5mcm9tKGVsLnBhcmVudEVsZW1lbnQuY2hpbGRyZW4pO1xuICAgIGlmIChsaW1pdCAmJiBsaW1pdCA8IDAgJiYgY2hpbGRyZW4ubGVuZ3RoID4gbGltaXQgKiAtMSkge1xuICAgICAgY2hpbGRyZW5cbiAgICAgICAgLnNsaWNlKDAsIGNoaWxkcmVuLmxlbmd0aCArIGxpbWl0KVxuICAgICAgICAuZm9yRWFjaCgoY2hpbGQpID0+IHRoaXMucmVtb3ZlU3RyZWFtQ2hpbGRFbGVtZW50KGNoaWxkKSk7XG4gICAgfSBlbHNlIGlmIChsaW1pdCAmJiBsaW1pdCA+PSAwICYmIGNoaWxkcmVuLmxlbmd0aCA+IGxpbWl0KSB7XG4gICAgICBjaGlsZHJlblxuICAgICAgICAuc2xpY2UobGltaXQpXG4gICAgICAgIC5mb3JFYWNoKChjaGlsZCkgPT4gdGhpcy5yZW1vdmVTdHJlYW1DaGlsZEVsZW1lbnQoY2hpbGQpKTtcbiAgICB9XG4gIH1cblxuICB0cmFuc2l0aW9uUGVuZGluZ1JlbW92ZXMoKSB7XG4gICAgY29uc3QgeyBwZW5kaW5nUmVtb3ZlcywgbGl2ZVNvY2tldCB9ID0gdGhpcztcbiAgICBpZiAocGVuZGluZ1JlbW92ZXMubGVuZ3RoID4gMCkge1xuICAgICAgbGl2ZVNvY2tldC50cmFuc2l0aW9uUmVtb3ZlcyhwZW5kaW5nUmVtb3ZlcywgKCkgPT4ge1xuICAgICAgICBwZW5kaW5nUmVtb3Zlcy5mb3JFYWNoKChlbCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNoaWxkID0gRE9NLmZpcnN0UGh4Q2hpbGQoZWwpO1xuICAgICAgICAgIGlmIChjaGlsZCkge1xuICAgICAgICAgICAgbGl2ZVNvY2tldC5kZXN0cm95Vmlld0J5RWwoY2hpbGQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbC5yZW1vdmUoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudHJhY2tBZnRlcihcInRyYW5zaXRpb25zRGlzY2FyZGVkXCIsIHBlbmRpbmdSZW1vdmVzKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGlzQ2hhbmdlZFNlbGVjdChmcm9tRWwsIHRvRWwpIHtcbiAgICBpZiAoIShmcm9tRWwgaW5zdGFuY2VvZiBIVE1MU2VsZWN0RWxlbWVudCkgfHwgZnJvbUVsLm11bHRpcGxlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChmcm9tRWwub3B0aW9ucy5sZW5ndGggIT09IHRvRWwub3B0aW9ucy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIGtlZXAgdGhlIGN1cnJlbnQgdmFsdWVcbiAgICB0b0VsLnZhbHVlID0gZnJvbUVsLnZhbHVlO1xuXG4gICAgLy8gaW4gZ2VuZXJhbCB3ZSBoYXZlIHRvIGJlIHZlcnkgY2FyZWZ1bCB3aXRoIHVzaW5nIGlzRXF1YWxOb2RlIGFzIGl0IGRvZXMgbm90IGEgcmVsaWFibGVcbiAgICAvLyBET00gdHJlZSBlcXVhbGl0eSBjaGVjaywgYnV0IGZvciBzZWxlY3Rpb24gYXR0cmlidXRlcyBhbmQgb3B0aW9ucyBpdCB3b3JrcyBmaW5lXG4gICAgcmV0dXJuICFmcm9tRWwuaXNFcXVhbE5vZGUodG9FbCk7XG4gIH1cblxuICBpc0NJRFBhdGNoKCkge1xuICAgIHJldHVybiB0aGlzLmNpZFBhdGNoO1xuICB9XG5cbiAgc2tpcENJRFNpYmxpbmcoZWwpIHtcbiAgICByZXR1cm4gZWwubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmIGVsLmhhc0F0dHJpYnV0ZShQSFhfU0tJUCk7XG4gIH1cblxuICB0YXJnZXRDSURDb250YWluZXIoaHRtbCkge1xuICAgIGlmICghdGhpcy5pc0NJRFBhdGNoKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgW2ZpcnN0LCAuLi5yZXN0XSA9IERPTS5maW5kQ29tcG9uZW50Tm9kZUxpc3QoXG4gICAgICB0aGlzLnZpZXcuaWQsXG4gICAgICB0aGlzLnRhcmdldENJRCxcbiAgICApO1xuICAgIGlmIChyZXN0Lmxlbmd0aCA9PT0gMCAmJiBET00uY2hpbGROb2RlTGVuZ3RoKGh0bWwpID09PSAxKSB7XG4gICAgICByZXR1cm4gZmlyc3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmaXJzdCAmJiBmaXJzdC5wYXJlbnROb2RlO1xuICAgIH1cbiAgfVxuXG4gIGluZGV4T2YocGFyZW50LCBjaGlsZCkge1xuICAgIHJldHVybiBBcnJheS5mcm9tKHBhcmVudC5jaGlsZHJlbikuaW5kZXhPZihjaGlsZCk7XG4gIH1cblxuICB0ZWxlcG9ydChlbCwgbW9ycGgpIHtcbiAgICBjb25zdCB0YXJnZXRTZWxlY3RvciA9IGVsLmdldEF0dHJpYnV0ZShQSFhfUE9SVEFMKTtcbiAgICBjb25zdCBwb3J0YWxDb250YWluZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRhcmdldFNlbGVjdG9yKTtcbiAgICBpZiAoIXBvcnRhbENvbnRhaW5lcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcInBvcnRhbCB0YXJnZXQgd2l0aCBzZWxlY3RvciBcIiArIHRhcmdldFNlbGVjdG9yICsgXCIgbm90IGZvdW5kXCIsXG4gICAgICApO1xuICAgIH1cbiAgICAvLyBwaHgtcG9ydGFsIHRlbXBsYXRlcyBtdXN0IGhhdmUgYSBzaW5nbGUgcm9vdCBlbGVtZW50LCBzbyB3ZSBhc3N1bWUgdGhpcyB0byBiZVxuICAgIC8vIHRoZSBjYXNlIGhlcmVcbiAgICBjb25zdCB0b1RlbGVwb3J0ID0gZWwuY29udGVudC5maXJzdEVsZW1lbnRDaGlsZDtcbiAgICAvLyB0aGUgUEhYX1NLSVAgb3B0aW1pemF0aW9uIGNhbiBhbHNvIGFwcGx5IGluc2lkZSBvZiB0aGUgPHRlbXBsYXRlPiBlbGVtZW50c1xuICAgIGlmICh0aGlzLnNraXBDSURTaWJsaW5nKHRvVGVsZXBvcnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghdG9UZWxlcG9ydD8uaWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJwaHgtcG9ydGFsIHRlbXBsYXRlIG11c3QgaGF2ZSBhIHNpbmdsZSByb290IGVsZW1lbnQgd2l0aCBJRCFcIixcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IGV4aXN0aW5nID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodG9UZWxlcG9ydC5pZCk7XG4gICAgbGV0IHBvcnRhbFRhcmdldDtcbiAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgIC8vIGNoZWNrIGlmIHRoZSBlbGVtZW50IG5lZWRzIHRvIGJlIG1vdmVkIHRvIGFub3RoZXIgdGFyZ2V0XG4gICAgICBpZiAoIXBvcnRhbENvbnRhaW5lci5jb250YWlucyhleGlzdGluZykpIHtcbiAgICAgICAgcG9ydGFsQ29udGFpbmVyLmFwcGVuZENoaWxkKGV4aXN0aW5nKTtcbiAgICAgIH1cbiAgICAgIC8vIHdlIGFscmVhZHkgdGVsZXBvcnRlZCBpbiBhIHByZXZpb3VzIHBhdGNoXG4gICAgICBwb3J0YWxUYXJnZXQgPSBleGlzdGluZztcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gY3JlYXRlIGVtcHR5IHRhcmdldCBhbmQgbW9ycGggaXQgcmVjdXJzaXZlbHlcbiAgICAgIHBvcnRhbFRhcmdldCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodG9UZWxlcG9ydC50YWdOYW1lKTtcbiAgICAgIHBvcnRhbENvbnRhaW5lci5hcHBlbmRDaGlsZChwb3J0YWxUYXJnZXQpO1xuICAgIH1cbiAgICAvLyBtYXJrIHRoZSB0YXJnZXQgYXMgdGVsZXBvcnRlZDtcbiAgICAvLyB0byBwcmV2ZW50IHVubmVjZXNzYXJ5IGF0dHJpYnV0ZSBtb2RpZmljYXRpb25zLCB3ZSBzZXQgdGhlIGF0dHJpYnV0ZVxuICAgIC8vIG9uIHRoZSBzb3VyY2UgYW5kIHJlbW92ZSBpdCBhZnRlciBtb3JwaGluZyAod2UgY291bGQgYWxzbyBqdXN0IGtlZXAgaXQpXG4gICAgLy8gb3RoZXJ3aXNlIG1vcnBoZG9tIHdvdWxkIHJlbW92ZSBpdCwgYXMgdGhlIHJlZiBpcyBub3QgcHJlc2VudCBpbiB0aGUgc291cmNlXG4gICAgLy8gYW5kIHdlJ2QgbmVlZCB0byBzZXQgaXQgYmFjayBhZnRlciBlYWNoIG1vcnBoXG4gICAgdG9UZWxlcG9ydC5zZXRBdHRyaWJ1dGUoUEhYX1RFTEVQT1JURURfUkVGLCB0aGlzLnZpZXcuaWQpO1xuICAgIHRvVGVsZXBvcnQuc2V0QXR0cmlidXRlKFBIWF9URUxFUE9SVEVEX1NSQywgZWwuaWQpO1xuICAgIG1vcnBoKHBvcnRhbFRhcmdldCwgdG9UZWxlcG9ydCwgdHJ1ZSk7XG4gICAgdG9UZWxlcG9ydC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1RFTEVQT1JURURfUkVGKTtcbiAgICB0b1RlbGVwb3J0LnJlbW92ZUF0dHJpYnV0ZShQSFhfVEVMRVBPUlRFRF9TUkMpO1xuICAgIC8vIHN0b3JlIGEgcmVmZXJlbmNlIHRvIHRoZSB0ZWxlcG9ydGVkIGVsZW1lbnQgaW4gdGhlIHZpZXdcbiAgICAvLyB0byBjbGVhbnVwIHdoZW4gdGhlIHZpZXcgaXMgZGVzdHJveWVkLCBpbiBjYXNlIHRoZSBwb3J0YWwgdGFyZ2V0XG4gICAgLy8gaXMgb3V0c2lkZSB0aGUgdmlldyBpdHNlbGZcbiAgICB0aGlzLnZpZXcucHVzaFBvcnRhbEVsZW1lbnRJZCh0b1RlbGVwb3J0LmlkKTtcbiAgfVxuXG4gIGhhbmRsZVJ1bnRpbWVIb29rKGVsLCBzb3VyY2UpIHtcbiAgICAvLyB1c3VhbGx5LCBzY3JpcHRzIGFyZSBub3QgZXhlY3V0ZWQgd2hlbiBtb3JwaGRvbSBhZGRzIHRoZW0gdG8gdGhlIERPTVxuICAgIC8vIHdlIHNwZWNpYWwgY2FzZSBydW50aW1lIGNvbG9jYXRlZCBob29rc1xuICAgIGNvbnN0IG5hbWUgPSBlbC5nZXRBdHRyaWJ1dGUoUEhYX1JVTlRJTUVfSE9PSyk7XG4gICAgbGV0IG5vbmNlID0gZWwuaGFzQXR0cmlidXRlKFwibm9uY2VcIikgPyBlbC5nZXRBdHRyaWJ1dGUoXCJub25jZVwiKSA6IG51bGw7XG4gICAgaWYgKGVsLmhhc0F0dHJpYnV0ZShcIm5vbmNlXCIpKSB7XG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ0ZW1wbGF0ZVwiKTtcbiAgICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IHNvdXJjZTtcbiAgICAgIG5vbmNlID0gdGVtcGxhdGUuY29udGVudFxuICAgICAgICAucXVlcnlTZWxlY3Rvcihgc2NyaXB0WyR7UEhYX1JVTlRJTUVfSE9PS309XCIke0NTUy5lc2NhcGUobmFtZSl9XCJdYClcbiAgICAgICAgLmdldEF0dHJpYnV0ZShcIm5vbmNlXCIpO1xuICAgIH1cbiAgICBjb25zdCBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic2NyaXB0XCIpO1xuICAgIHNjcmlwdC50ZXh0Q29udGVudCA9IGVsLnRleHRDb250ZW50O1xuICAgIERPTS5tZXJnZUF0dHJzKHNjcmlwdCwgZWwsIHsgaXNJZ25vcmVkOiBmYWxzZSB9KTtcbiAgICBpZiAobm9uY2UpIHtcbiAgICAgIHNjcmlwdC5ub25jZSA9IG5vbmNlO1xuICAgIH1cbiAgICBlbC5yZXBsYWNlV2l0aChzY3JpcHQpO1xuICAgIGVsID0gc2NyaXB0O1xuICB9XG59XG4iLCAiaW1wb3J0IHtcbiAgQ09NUE9ORU5UUyxcbiAgVEVNUExBVEVTLFxuICBFVkVOVFMsXG4gIFBIWF9DT01QT05FTlQsXG4gIFBIWF9WSUVXX1JFRixcbiAgUEhYX1NLSVAsXG4gIFBIWF9NQUdJQ19JRCxcbiAgUkVQTFksXG4gIFNUQVRJQyxcbiAgVElUTEUsXG4gIFNUUkVBTSxcbiAgUk9PVCxcbiAgS0VZRUQsXG4gIEtFWUVEX0NPVU5ULFxufSBmcm9tIFwiLi9jb25zdGFudHNcIjtcblxuaW1wb3J0IHsgaXNPYmplY3QsIGxvZ0Vycm9yLCBpc0NpZCB9IGZyb20gXCIuL3V0aWxzXCI7XG5cbmNvbnN0IFZPSURfVEFHUyA9IG5ldyBTZXQoW1xuICBcImFyZWFcIixcbiAgXCJiYXNlXCIsXG4gIFwiYnJcIixcbiAgXCJjb2xcIixcbiAgXCJjb21tYW5kXCIsXG4gIFwiZW1iZWRcIixcbiAgXCJoclwiLFxuICBcImltZ1wiLFxuICBcImlucHV0XCIsXG4gIFwia2V5Z2VuXCIsXG4gIFwibGlua1wiLFxuICBcIm1ldGFcIixcbiAgXCJwYXJhbVwiLFxuICBcInNvdXJjZVwiLFxuICBcInRyYWNrXCIsXG4gIFwid2JyXCIsXG5dKTtcbmNvbnN0IHF1b3RlQ2hhcnMgPSBuZXcgU2V0KFtcIidcIiwgJ1wiJ10pO1xuXG5leHBvcnQgY29uc3QgbW9kaWZ5Um9vdCA9IChodG1sLCBhdHRycywgY2xlYXJJbm5lckhUTUwpID0+IHtcbiAgbGV0IGkgPSAwO1xuICBsZXQgaW5zaWRlQ29tbWVudCA9IGZhbHNlO1xuICBsZXQgYmVmb3JlVGFnLCBhZnRlclRhZywgdGFnLCB0YWdOYW1lRW5kc0F0LCBpZCwgbmV3SFRNTDtcblxuICBjb25zdCBsb29rYWhlYWQgPSBodG1sLm1hdGNoKC9eKFxccyooPzo8IS0tLio/LS0+XFxzKikqKTwoW15cXHNcXC8+XSspLyk7XG4gIGlmIChsb29rYWhlYWQgPT09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYG1hbGZvcm1lZCBodG1sICR7aHRtbH1gKTtcbiAgfVxuXG4gIGkgPSBsb29rYWhlYWRbMF0ubGVuZ3RoO1xuICBiZWZvcmVUYWcgPSBsb29rYWhlYWRbMV07XG4gIHRhZyA9IGxvb2thaGVhZFsyXTtcbiAgdGFnTmFtZUVuZHNBdCA9IGk7XG5cbiAgLy8gU2NhbiB0aGUgb3BlbmluZyB0YWcgZm9yIGlkLCBpZiB0aGVyZSBpcyBhbnlcbiAgZm9yIChpOyBpIDwgaHRtbC5sZW5ndGg7IGkrKykge1xuICAgIGlmIChodG1sLmNoYXJBdChpKSA9PT0gXCI+XCIpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBpZiAoaHRtbC5jaGFyQXQoaSkgPT09IFwiPVwiKSB7XG4gICAgICBjb25zdCBpc0lkID0gaHRtbC5zbGljZShpIC0gMywgaSkgPT09IFwiIGlkXCI7XG4gICAgICBpKys7XG4gICAgICBjb25zdCBjaGFyID0gaHRtbC5jaGFyQXQoaSk7XG4gICAgICBpZiAocXVvdGVDaGFycy5oYXMoY2hhcikpIHtcbiAgICAgICAgY29uc3QgYXR0clN0YXJ0c0F0ID0gaTtcbiAgICAgICAgaSsrO1xuICAgICAgICBmb3IgKGk7IGkgPCBodG1sLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWYgKGh0bWwuY2hhckF0KGkpID09PSBjaGFyKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzSWQpIHtcbiAgICAgICAgICBpZCA9IGh0bWwuc2xpY2UoYXR0clN0YXJ0c0F0ICsgMSwgaSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBsZXQgY2xvc2VBdCA9IGh0bWwubGVuZ3RoIC0gMTtcbiAgaW5zaWRlQ29tbWVudCA9IGZhbHNlO1xuICB3aGlsZSAoY2xvc2VBdCA+PSBiZWZvcmVUYWcubGVuZ3RoICsgdGFnLmxlbmd0aCkge1xuICAgIGNvbnN0IGNoYXIgPSBodG1sLmNoYXJBdChjbG9zZUF0KTtcbiAgICBpZiAoaW5zaWRlQ29tbWVudCkge1xuICAgICAgaWYgKGNoYXIgPT09IFwiLVwiICYmIGh0bWwuc2xpY2UoY2xvc2VBdCAtIDMsIGNsb3NlQXQpID09PSBcIjwhLVwiKSB7XG4gICAgICAgIGluc2lkZUNvbW1lbnQgPSBmYWxzZTtcbiAgICAgICAgY2xvc2VBdCAtPSA0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2xvc2VBdCAtPSAxO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY2hhciA9PT0gXCI+XCIgJiYgaHRtbC5zbGljZShjbG9zZUF0IC0gMiwgY2xvc2VBdCkgPT09IFwiLS1cIikge1xuICAgICAgaW5zaWRlQ29tbWVudCA9IHRydWU7XG4gICAgICBjbG9zZUF0IC09IDM7XG4gICAgfSBlbHNlIGlmIChjaGFyID09PSBcIj5cIikge1xuICAgICAgYnJlYWs7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNsb3NlQXQgLT0gMTtcbiAgICB9XG4gIH1cbiAgYWZ0ZXJUYWcgPSBodG1sLnNsaWNlKGNsb3NlQXQgKyAxLCBodG1sLmxlbmd0aCk7XG5cbiAgY29uc3QgYXR0cnNTdHIgPSBPYmplY3Qua2V5cyhhdHRycylcbiAgICAubWFwKChhdHRyKSA9PiAoYXR0cnNbYXR0cl0gPT09IHRydWUgPyBhdHRyIDogYCR7YXR0cn09XCIke2F0dHJzW2F0dHJdfVwiYCkpXG4gICAgLmpvaW4oXCIgXCIpO1xuXG4gIGlmIChjbGVhcklubmVySFRNTCkge1xuICAgIC8vIEtlZXAgdGhlIGlkIGlmIGFueVxuICAgIGNvbnN0IGlkQXR0clN0ciA9IGlkID8gYCBpZD1cIiR7aWR9XCJgIDogXCJcIjtcbiAgICBpZiAoVk9JRF9UQUdTLmhhcyh0YWcpKSB7XG4gICAgICBuZXdIVE1MID0gYDwke3RhZ30ke2lkQXR0clN0cn0ke2F0dHJzU3RyID09PSBcIlwiID8gXCJcIiA6IFwiIFwifSR7YXR0cnNTdHJ9Lz5gO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXdIVE1MID0gYDwke3RhZ30ke2lkQXR0clN0cn0ke2F0dHJzU3RyID09PSBcIlwiID8gXCJcIiA6IFwiIFwifSR7YXR0cnNTdHJ9PjwvJHt0YWd9PmA7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGNvbnN0IHJlc3QgPSBodG1sLnNsaWNlKHRhZ05hbWVFbmRzQXQsIGNsb3NlQXQgKyAxKTtcbiAgICBuZXdIVE1MID0gYDwke3RhZ30ke2F0dHJzU3RyID09PSBcIlwiID8gXCJcIiA6IFwiIFwifSR7YXR0cnNTdHJ9JHtyZXN0fWA7XG4gIH1cblxuICByZXR1cm4gW25ld0hUTUwsIGJlZm9yZVRhZywgYWZ0ZXJUYWddO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmVuZGVyZWQge1xuICBzdGF0aWMgZXh0cmFjdChkaWZmKSB7XG4gICAgY29uc3QgeyBbUkVQTFldOiByZXBseSwgW0VWRU5UU106IGV2ZW50cywgW1RJVExFXTogdGl0bGUgfSA9IGRpZmY7XG4gICAgZGVsZXRlIGRpZmZbUkVQTFldO1xuICAgIGRlbGV0ZSBkaWZmW0VWRU5UU107XG4gICAgZGVsZXRlIGRpZmZbVElUTEVdO1xuICAgIHJldHVybiB7IGRpZmYsIHRpdGxlLCByZXBseTogcmVwbHkgfHwgbnVsbCwgZXZlbnRzOiBldmVudHMgfHwgW10gfTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHZpZXdJZCwgcmVuZGVyZWQpIHtcbiAgICB0aGlzLnZpZXdJZCA9IHZpZXdJZDtcbiAgICB0aGlzLnJlbmRlcmVkID0ge307XG4gICAgdGhpcy5tYWdpY0lkID0gMDtcbiAgICB0aGlzLm1lcmdlRGlmZihyZW5kZXJlZCk7XG4gIH1cblxuICBwYXJlbnRWaWV3SWQoKSB7XG4gICAgcmV0dXJuIHRoaXMudmlld0lkO1xuICB9XG5cbiAgdG9TdHJpbmcob25seUNpZHMpIHtcbiAgICBjb25zdCB7IGJ1ZmZlcjogc3RyLCBzdHJlYW1zOiBzdHJlYW1zIH0gPSB0aGlzLnJlY3Vyc2l2ZVRvU3RyaW5nKFxuICAgICAgdGhpcy5yZW5kZXJlZCxcbiAgICAgIHRoaXMucmVuZGVyZWRbQ09NUE9ORU5UU10sXG4gICAgICBvbmx5Q2lkcyxcbiAgICAgIHRydWUsXG4gICAgICB7fSxcbiAgICApO1xuICAgIHJldHVybiB7IGJ1ZmZlcjogc3RyLCBzdHJlYW1zOiBzdHJlYW1zIH07XG4gIH1cblxuICByZWN1cnNpdmVUb1N0cmluZyhcbiAgICByZW5kZXJlZCxcbiAgICBjb21wb25lbnRzID0gcmVuZGVyZWRbQ09NUE9ORU5UU10sXG4gICAgb25seUNpZHMsXG4gICAgY2hhbmdlVHJhY2tpbmcsXG4gICAgcm9vdEF0dHJzLFxuICApIHtcbiAgICBvbmx5Q2lkcyA9IG9ubHlDaWRzID8gbmV3IFNldChvbmx5Q2lkcykgOiBudWxsO1xuICAgIGNvbnN0IG91dHB1dCA9IHtcbiAgICAgIGJ1ZmZlcjogXCJcIixcbiAgICAgIGNvbXBvbmVudHM6IGNvbXBvbmVudHMsXG4gICAgICBvbmx5Q2lkczogb25seUNpZHMsXG4gICAgICBzdHJlYW1zOiBuZXcgU2V0KCksXG4gICAgfTtcbiAgICB0aGlzLnRvT3V0cHV0QnVmZmVyKHJlbmRlcmVkLCBudWxsLCBvdXRwdXQsIGNoYW5nZVRyYWNraW5nLCByb290QXR0cnMpO1xuICAgIHJldHVybiB7IGJ1ZmZlcjogb3V0cHV0LmJ1ZmZlciwgc3RyZWFtczogb3V0cHV0LnN0cmVhbXMgfTtcbiAgfVxuXG4gIGNvbXBvbmVudENJRHMoZGlmZikge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhkaWZmW0NPTVBPTkVOVFNdIHx8IHt9KS5tYXAoKGkpID0+IHBhcnNlSW50KGkpKTtcbiAgfVxuXG4gIGlzQ29tcG9uZW50T25seURpZmYoZGlmZikge1xuICAgIGlmICghZGlmZltDT01QT05FTlRTXSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gT2JqZWN0LmtleXMoZGlmZikubGVuZ3RoID09PSAxO1xuICB9XG5cbiAgZ2V0Q29tcG9uZW50KGRpZmYsIGNpZCkge1xuICAgIHJldHVybiBkaWZmW0NPTVBPTkVOVFNdW2NpZF07XG4gIH1cblxuICByZXNldFJlbmRlcihjaWQpIHtcbiAgICAvLyB3ZSBhcmUgcmFjaW5nIGEgY29tcG9uZW50IGRlc3Ryb3ksIGl0IGNvdWxkIG5vdCBleGlzdCwgc29cbiAgICAvLyBtYWtlIHN1cmUgdGhhdCB3ZSBkb24ndCB0cnkgdG8gc2V0IHJlc2V0IG9uIHVuZGVmaW5lZFxuICAgIGlmICh0aGlzLnJlbmRlcmVkW0NPTVBPTkVOVFNdW2NpZF0pIHtcbiAgICAgIHRoaXMucmVuZGVyZWRbQ09NUE9ORU5UU11bY2lkXS5yZXNldCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgbWVyZ2VEaWZmKGRpZmYpIHtcbiAgICBjb25zdCBuZXdjID0gZGlmZltDT01QT05FTlRTXTtcbiAgICBjb25zdCBjYWNoZSA9IHt9O1xuICAgIGRlbGV0ZSBkaWZmW0NPTVBPTkVOVFNdO1xuICAgIHRoaXMucmVuZGVyZWQgPSB0aGlzLm11dGFibGVNZXJnZSh0aGlzLnJlbmRlcmVkLCBkaWZmKTtcbiAgICB0aGlzLnJlbmRlcmVkW0NPTVBPTkVOVFNdID0gdGhpcy5yZW5kZXJlZFtDT01QT05FTlRTXSB8fCB7fTtcblxuICAgIGlmIChuZXdjKSB7XG4gICAgICBjb25zdCBvbGRjID0gdGhpcy5yZW5kZXJlZFtDT01QT05FTlRTXTtcblxuICAgICAgZm9yIChjb25zdCBjaWQgaW4gbmV3Yykge1xuICAgICAgICBuZXdjW2NpZF0gPSB0aGlzLmNhY2hlZEZpbmRDb21wb25lbnQoY2lkLCBuZXdjW2NpZF0sIG9sZGMsIG5ld2MsIGNhY2hlKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChjb25zdCBjaWQgaW4gbmV3Yykge1xuICAgICAgICBvbGRjW2NpZF0gPSBuZXdjW2NpZF07XG4gICAgICB9XG4gICAgICBkaWZmW0NPTVBPTkVOVFNdID0gbmV3YztcbiAgICB9XG4gIH1cblxuICBjYWNoZWRGaW5kQ29tcG9uZW50KGNpZCwgY2RpZmYsIG9sZGMsIG5ld2MsIGNhY2hlKSB7XG4gICAgaWYgKGNhY2hlW2NpZF0pIHtcbiAgICAgIHJldHVybiBjYWNoZVtjaWRdO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgbmRpZmYsXG4gICAgICAgIHN0YXQsXG4gICAgICAgIHNjaWQgPSBjZGlmZltTVEFUSUNdO1xuXG4gICAgICBpZiAoaXNDaWQoc2NpZCkpIHtcbiAgICAgICAgbGV0IHRkaWZmO1xuXG4gICAgICAgIGlmIChzY2lkID4gMCkge1xuICAgICAgICAgIHRkaWZmID0gdGhpcy5jYWNoZWRGaW5kQ29tcG9uZW50KHNjaWQsIG5ld2Nbc2NpZF0sIG9sZGMsIG5ld2MsIGNhY2hlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0ZGlmZiA9IG9sZGNbLXNjaWRdO1xuICAgICAgICB9XG5cbiAgICAgICAgc3RhdCA9IHRkaWZmW1NUQVRJQ107XG4gICAgICAgIG5kaWZmID0gdGhpcy5jbG9uZU1lcmdlKHRkaWZmLCBjZGlmZiwgdHJ1ZSk7XG4gICAgICAgIG5kaWZmW1NUQVRJQ10gPSBzdGF0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmRpZmYgPVxuICAgICAgICAgIGNkaWZmW1NUQVRJQ10gIT09IHVuZGVmaW5lZCB8fCBvbGRjW2NpZF0gPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgPyBjZGlmZlxuICAgICAgICAgICAgOiB0aGlzLmNsb25lTWVyZ2Uob2xkY1tjaWRdLCBjZGlmZiwgZmFsc2UpO1xuICAgICAgfVxuXG4gICAgICBjYWNoZVtjaWRdID0gbmRpZmY7XG4gICAgICByZXR1cm4gbmRpZmY7XG4gICAgfVxuICB9XG5cbiAgbXV0YWJsZU1lcmdlKHRhcmdldCwgc291cmNlKSB7XG4gICAgaWYgKHNvdXJjZVtTVEFUSUNdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBzb3VyY2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZG9NdXRhYmxlTWVyZ2UodGFyZ2V0LCBzb3VyY2UpO1xuICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG4gIH1cblxuICBkb011dGFibGVNZXJnZSh0YXJnZXQsIHNvdXJjZSkge1xuICAgIGlmIChzb3VyY2VbS0VZRURdKSB7XG4gICAgICB0aGlzLm1lcmdlS2V5ZWQodGFyZ2V0LCBzb3VyY2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGNvbnN0IGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgY29uc3QgdmFsID0gc291cmNlW2tleV07XG4gICAgICAgIGNvbnN0IHRhcmdldFZhbCA9IHRhcmdldFtrZXldO1xuICAgICAgICBjb25zdCBpc09ialZhbCA9IGlzT2JqZWN0KHZhbCk7XG4gICAgICAgIGlmIChpc09ialZhbCAmJiB2YWxbU1RBVElDXSA9PT0gdW5kZWZpbmVkICYmIGlzT2JqZWN0KHRhcmdldFZhbCkpIHtcbiAgICAgICAgICB0aGlzLmRvTXV0YWJsZU1lcmdlKHRhcmdldFZhbCwgdmFsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0YXJnZXRba2V5XSA9IHZhbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAodGFyZ2V0W1JPT1RdKSB7XG4gICAgICB0YXJnZXQubmV3UmVuZGVyID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBjbG9uZShkaWZmKSB7XG4gICAgaWYgKFwic3RydWN0dXJlZENsb25lXCIgaW4gd2luZG93KSB7XG4gICAgICByZXR1cm4gc3RydWN0dXJlZENsb25lKGRpZmYpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBmYWxsYmFjayBmb3IgamVzdFxuICAgICAgcmV0dXJuIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZGlmZikpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGtleWVkIGNvbXByZWhlbnNpb25zXG4gIG1lcmdlS2V5ZWQodGFyZ2V0LCBzb3VyY2UpIHtcbiAgICAvLyB3ZSBuZWVkIHRvIGNsb25lIHRoZSB0YXJnZXQgc2luY2UgZWxlbWVudHMgY2FuIG1vdmUgYW5kIG90aGVyd2lzZVxuICAgIC8vIGl0IGNvdWxkIGhhcHBlbiB0aGF0IHdlIG1vZGlmeSBhbiBlbGVtZW50IHRoYXQgd2UnbGwgbmVlZCB0byByZWZlciB0b1xuICAgIC8vIGxhdGVyXG4gICAgY29uc3QgY2xvbmVkVGFyZ2V0ID0gdGhpcy5jbG9uZSh0YXJnZXQpO1xuICAgIE9iamVjdC5lbnRyaWVzKHNvdXJjZVtLRVlFRF0pLmZvckVhY2goKFtpLCBlbnRyeV0pID0+IHtcbiAgICAgIGlmIChpID09PSBLRVlFRF9DT1VOVCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShlbnRyeSkpIHtcbiAgICAgICAgLy8gW29sZF9pZHgsIGRpZmZdXG4gICAgICAgIC8vIG1vdmVkIHdpdGggZGlmZlxuICAgICAgICBjb25zdCBbb2xkX2lkeCwgZGlmZl0gPSBlbnRyeTtcbiAgICAgICAgdGFyZ2V0W0tFWUVEXVtpXSA9IGNsb25lZFRhcmdldFtLRVlFRF1bb2xkX2lkeF07XG4gICAgICAgIHRoaXMuZG9NdXRhYmxlTWVyZ2UodGFyZ2V0W0tFWUVEXVtpXSwgZGlmZik7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBlbnRyeSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAvLyBtb3ZlZCB3aXRob3V0IGRpZmZcbiAgICAgICAgY29uc3Qgb2xkX2lkeCA9IGVudHJ5O1xuICAgICAgICB0YXJnZXRbS0VZRURdW2ldID0gY2xvbmVkVGFyZ2V0W0tFWUVEXVtvbGRfaWR4XTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGVudHJ5ID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIC8vIGRpZmYsIHNhbWUgcG9zaXRpb25cbiAgICAgICAgaWYgKCF0YXJnZXRbS0VZRURdW2ldKSB7XG4gICAgICAgICAgdGFyZ2V0W0tFWUVEXVtpXSA9IHt9O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZG9NdXRhYmxlTWVyZ2UodGFyZ2V0W0tFWUVEXVtpXSwgZW50cnkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIC8vIGRyb3AgZXh0cmEgZW50cmllc1xuICAgIGlmIChzb3VyY2VbS0VZRURdW0tFWUVEX0NPVU5UXSA8IHRhcmdldFtLRVlFRF1bS0VZRURfQ09VTlRdKSB7XG4gICAgICBmb3IgKFxuICAgICAgICBsZXQgaSA9IHNvdXJjZVtLRVlFRF1bS0VZRURfQ09VTlRdO1xuICAgICAgICBpIDwgdGFyZ2V0W0tFWUVEXVtLRVlFRF9DT1VOVF07XG4gICAgICAgIGkrK1xuICAgICAgKSB7XG4gICAgICAgIGRlbGV0ZSB0YXJnZXRbS0VZRURdW2ldO1xuICAgICAgfVxuICAgIH1cbiAgICB0YXJnZXRbS0VZRURdW0tFWUVEX0NPVU5UXSA9IHNvdXJjZVtLRVlFRF1bS0VZRURfQ09VTlRdO1xuICAgIGlmIChzb3VyY2VbU1RSRUFNXSkge1xuICAgICAgdGFyZ2V0W1NUUkVBTV0gPSBzb3VyY2VbU1RSRUFNXTtcbiAgICB9XG4gICAgaWYgKHNvdXJjZVtURU1QTEFURVNdKSB7XG4gICAgICB0YXJnZXRbVEVNUExBVEVTXSA9IHNvdXJjZVtURU1QTEFURVNdO1xuICAgIH1cbiAgfVxuXG4gIC8vIE1lcmdlcyBjaWQgdHJlZXMgdG9nZXRoZXIsIGNvcHlpbmcgc3RhdGljcyBmcm9tIHNvdXJjZSB0cmVlLlxuICAvL1xuICAvLyBUaGUgYHBydW5lTWFnaWNJZGAgaXMgcGFzc2VkIHRvIGNvbnRyb2wgcHJ1bmluZyB0aGUgbWFnaWNJZCBvZiB0aGVcbiAgLy8gdGFyZ2V0LiBXZSBtdXN0IGFsd2F5cyBwcnVuZSB0aGUgbWFnaWNJZCB3aGVuIHdlIGFyZSBzaGFyaW5nIHN0YXRpY3NcbiAgLy8gZnJvbSBhbm90aGVyIGNvbXBvbmVudC4gSWYgbm90IHBydW5pbmcsIHdlIHJlcGxpY2F0ZSB0aGUgbG9naWMgZnJvbVxuICAvLyBtdXRhYmxlTWVyZ2UsIHdoZXJlIHdlIHNldCBuZXdSZW5kZXIgdG8gdHJ1ZSBpZiB0aGVyZSBpcyBhIHJvb3RcbiAgLy8gKGVmZmVjdGl2ZWx5IGZvcmNpbmcgdGhlIG5ldyB2ZXJzaW9uIHRvIGJlIHJlbmRlcmVkIGluc3RlYWQgb2Ygc2tpcHBlZClcbiAgLy9cbiAgY2xvbmVNZXJnZSh0YXJnZXQsIHNvdXJjZSwgcHJ1bmVNYWdpY0lkKSB7XG4gICAgbGV0IG1lcmdlZDtcbiAgICBpZiAoc291cmNlW0tFWUVEXSkge1xuICAgICAgbWVyZ2VkID0gdGhpcy5jbG9uZSh0YXJnZXQpO1xuICAgICAgdGhpcy5tZXJnZUtleWVkKG1lcmdlZCwgc291cmNlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbWVyZ2VkID0geyAuLi50YXJnZXQsIC4uLnNvdXJjZSB9O1xuICAgICAgZm9yIChjb25zdCBrZXkgaW4gbWVyZ2VkKSB7XG4gICAgICAgIGNvbnN0IHZhbCA9IHNvdXJjZVtrZXldO1xuICAgICAgICBjb25zdCB0YXJnZXRWYWwgPSB0YXJnZXRba2V5XTtcbiAgICAgICAgaWYgKGlzT2JqZWN0KHZhbCkgJiYgdmFsW1NUQVRJQ10gPT09IHVuZGVmaW5lZCAmJiBpc09iamVjdCh0YXJnZXRWYWwpKSB7XG4gICAgICAgICAgbWVyZ2VkW2tleV0gPSB0aGlzLmNsb25lTWVyZ2UodGFyZ2V0VmFsLCB2YWwsIHBydW5lTWFnaWNJZCk7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsID09PSB1bmRlZmluZWQgJiYgaXNPYmplY3QodGFyZ2V0VmFsKSkge1xuICAgICAgICAgIG1lcmdlZFtrZXldID0gdGhpcy5jbG9uZU1lcmdlKHRhcmdldFZhbCwge30sIHBydW5lTWFnaWNJZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHBydW5lTWFnaWNJZCkge1xuICAgICAgZGVsZXRlIG1lcmdlZC5tYWdpY0lkO1xuICAgICAgZGVsZXRlIG1lcmdlZC5uZXdSZW5kZXI7XG4gICAgfSBlbHNlIGlmICh0YXJnZXRbUk9PVF0pIHtcbiAgICAgIG1lcmdlZC5uZXdSZW5kZXIgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gbWVyZ2VkO1xuICB9XG5cbiAgY29tcG9uZW50VG9TdHJpbmcoY2lkKSB7XG4gICAgY29uc3QgeyBidWZmZXI6IHN0ciwgc3RyZWFtcyB9ID0gdGhpcy5yZWN1cnNpdmVDSURUb1N0cmluZyhcbiAgICAgIHRoaXMucmVuZGVyZWRbQ09NUE9ORU5UU10sXG4gICAgICBjaWQsXG4gICAgICBudWxsLFxuICAgICk7XG4gICAgY29uc3QgW3N0cmlwcGVkSFRNTCwgX2JlZm9yZSwgX2FmdGVyXSA9IG1vZGlmeVJvb3Qoc3RyLCB7fSk7XG4gICAgcmV0dXJuIHsgYnVmZmVyOiBzdHJpcHBlZEhUTUwsIHN0cmVhbXM6IHN0cmVhbXMgfTtcbiAgfVxuXG4gIHBydW5lQ0lEcyhjaWRzKSB7XG4gICAgY2lkcy5mb3JFYWNoKChjaWQpID0+IGRlbGV0ZSB0aGlzLnJlbmRlcmVkW0NPTVBPTkVOVFNdW2NpZF0pO1xuICB9XG5cbiAgLy8gcHJpdmF0ZVxuXG4gIGdldCgpIHtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXJlZDtcbiAgfVxuXG4gIGlzTmV3RmluZ2VycHJpbnQoZGlmZiA9IHt9KSB7XG4gICAgcmV0dXJuICEhZGlmZltTVEFUSUNdO1xuICB9XG5cbiAgdGVtcGxhdGVTdGF0aWMocGFydCwgdGVtcGxhdGVzKSB7XG4gICAgaWYgKHR5cGVvZiBwYXJ0ID09PSBcIm51bWJlclwiKSB7XG4gICAgICByZXR1cm4gdGVtcGxhdGVzW3BhcnRdO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gcGFydDtcbiAgICB9XG4gIH1cblxuICBuZXh0TWFnaWNJRCgpIHtcbiAgICB0aGlzLm1hZ2ljSWQrKztcbiAgICByZXR1cm4gYG0ke3RoaXMubWFnaWNJZH0tJHt0aGlzLnBhcmVudFZpZXdJZCgpfWA7XG4gIH1cblxuICAvLyBDb252ZXJ0cyByZW5kZXJlZCB0cmVlIHRvIG91dHB1dCBidWZmZXIuXG4gIC8vXG4gIC8vIGNoYW5nZVRyYWNraW5nIGNvbnRyb2xzIGlmIHdlIGNhbiBhcHBseSB0aGUgUEhYX1NLSVAgb3B0aW1pemF0aW9uLlxuICB0b091dHB1dEJ1ZmZlcihyZW5kZXJlZCwgdGVtcGxhdGVzLCBvdXRwdXQsIGNoYW5nZVRyYWNraW5nLCByb290QXR0cnMgPSB7fSkge1xuICAgIGlmIChyZW5kZXJlZFtLRVlFRF0pIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbXByZWhlbnNpb25Ub0J1ZmZlcihcbiAgICAgICAgcmVuZGVyZWQsXG4gICAgICAgIHRlbXBsYXRlcyxcbiAgICAgICAgb3V0cHV0LFxuICAgICAgICBjaGFuZ2VUcmFja2luZyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gVGVtcGxhdGVzIGFyZSBhIHdheSBvZiBzaGFyaW5nIHN0YXRpY3MgYmV0d2VlbiBtdWx0aXBsZSByZW5kZXJlZCBzdHJ1Y3RzLlxuICAgIC8vIFNpbmNlIExpdmVWaWV3IDEuMSwgdGhvc2UgY2FuIGFsc28gYXBwZWFyIGF0IHRoZSByb290IC0gZm9yIGV4YW1wbGUgaWYgb25lIHJlbmRlcnNcbiAgICAvLyB0d28gY29tcHJlaGVuc2lvbnMgdGhhdCBjYW4gc2hhcmUgc3RhdGljcy5cbiAgICAvLyBXaGVuZXZlciB3ZSBmaW5kIHRlbXBsYXRlcywgd2UgbmVlZCB0byB1c2UgdGhlbSByZWN1cnNpdmVseS4gQWxzbywgdGVtcGxhdGVzIGNhblxuICAgIC8vIGJlIHNlbnQgZm9yIGVhY2ggZGlmZiwgbm90IG9ubHkgZm9yIHRoZSBpbml0aWFsIG9uZS4gV2UgZG9uJ3Qgd2FudCB0byBtZXJnZSB0aGVtXG4gICAgLy8gdGhvdWdoLCBzbyB3ZSBhbHdheXMgcmVzb2x2ZSB0aGVtIGFuZCByZW1vdmUgdGhlbSBmcm9tIHRoZSByZW5kZXJlZCBvYmplY3QuXG4gICAgaWYgKHJlbmRlcmVkW1RFTVBMQVRFU10pIHtcbiAgICAgIHRlbXBsYXRlcyA9IHJlbmRlcmVkW1RFTVBMQVRFU107XG4gICAgICBkZWxldGUgcmVuZGVyZWRbVEVNUExBVEVTXTtcbiAgICB9XG5cbiAgICBsZXQgeyBbU1RBVElDXTogc3RhdGljcyB9ID0gcmVuZGVyZWQ7XG4gICAgc3RhdGljcyA9IHRoaXMudGVtcGxhdGVTdGF0aWMoc3RhdGljcywgdGVtcGxhdGVzKTtcbiAgICByZW5kZXJlZFtTVEFUSUNdID0gc3RhdGljcztcbiAgICBjb25zdCBpc1Jvb3QgPSByZW5kZXJlZFtST09UXTtcbiAgICBjb25zdCBwcmV2QnVmZmVyID0gb3V0cHV0LmJ1ZmZlcjtcbiAgICBpZiAoaXNSb290KSB7XG4gICAgICBvdXRwdXQuYnVmZmVyID0gXCJcIjtcbiAgICB9XG5cbiAgICAvLyB0aGlzIGNvbmRpdGlvbiBpcyBjYWxsZWQgd2hlbiBmaXJzdCByZW5kZXJpbmcgYW4gb3B0aW1pemFibGUgZnVuY3Rpb24gY29tcG9uZW50LlxuICAgIC8vIExDIGhhdmUgdGhlaXIgbWFnaWNJZCBwcmV2aW91c2x5IHNldFxuICAgIGlmIChjaGFuZ2VUcmFja2luZyAmJiBpc1Jvb3QgJiYgIXJlbmRlcmVkLm1hZ2ljSWQpIHtcbiAgICAgIHJlbmRlcmVkLm5ld1JlbmRlciA9IHRydWU7XG4gICAgICByZW5kZXJlZC5tYWdpY0lkID0gdGhpcy5uZXh0TWFnaWNJRCgpO1xuICAgIH1cblxuICAgIG91dHB1dC5idWZmZXIgKz0gc3RhdGljc1swXTtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IHN0YXRpY3MubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMuZHluYW1pY1RvQnVmZmVyKHJlbmRlcmVkW2kgLSAxXSwgdGVtcGxhdGVzLCBvdXRwdXQsIGNoYW5nZVRyYWNraW5nKTtcbiAgICAgIG91dHB1dC5idWZmZXIgKz0gc3RhdGljc1tpXTtcbiAgICB9XG5cbiAgICAvLyBBcHBsaWVzIHRoZSByb290IHRhZyBcInNraXBcIiBvcHRpbWl6YXRpb24gaWYgc3VwcG9ydGVkLCB3aGljaCBjbGVhcnNcbiAgICAvLyB0aGUgcm9vdCB0YWcgYXR0cmlidXRlcyBhbmQgaW5uZXJIVE1MLCBhbmQgb25seSBtYWludGFpbnMgdGhlIG1hZ2ljSWQuXG4gICAgLy8gV2UgY2FuIG9ubHkgc2tpcCB3aGVuIGNoYW5nZVRyYWNraW5nIGlzIHN1cHBvcnRlZCxcbiAgICAvLyBhbmQgd2hlbiB0aGUgcm9vdCBlbGVtZW50IGhhc24ndCBleHBlcmllbmNlZCBhbiB1bnJlbmRlcmVkIG1lcmdlIChuZXdSZW5kZXIgdHJ1ZSkuXG4gICAgaWYgKGlzUm9vdCkge1xuICAgICAgbGV0IHNraXAgPSBmYWxzZTtcbiAgICAgIGxldCBhdHRycztcbiAgICAgIC8vIFdoZW4gYSBMQyBpcyByZS1hZGRlZCB0byB0aGUgcGFnZSwgd2UgbmVlZCB0byByZS1yZW5kZXIgdGhlIGVudGlyZSBMQyB0cmVlLFxuICAgICAgLy8gdGhlcmVmb3JlIGNoYW5nZVRyYWNraW5nIGlzIGZhbHNlOyBob3dldmVyLCB3ZSBuZWVkIHRvIGtlZXAgYWxsIHRoZSBtYWdpY0lkc1xuICAgICAgLy8gZnJvbSBhbnkgZnVuY3Rpb24gY29tcG9uZW50IHNvIHRoZSBuZXh0IHRpbWUgdGhlIExDIGlzIHVwZGF0ZWQsIHdlIGNhbiBhcHBseVxuICAgICAgLy8gdGhlIHNraXAgb3B0aW1pemF0aW9uXG4gICAgICBpZiAoY2hhbmdlVHJhY2tpbmcgfHwgcmVuZGVyZWQubWFnaWNJZCkge1xuICAgICAgICBza2lwID0gY2hhbmdlVHJhY2tpbmcgJiYgIXJlbmRlcmVkLm5ld1JlbmRlcjtcbiAgICAgICAgYXR0cnMgPSB7IFtQSFhfTUFHSUNfSURdOiByZW5kZXJlZC5tYWdpY0lkLCAuLi5yb290QXR0cnMgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGF0dHJzID0gcm9vdEF0dHJzO1xuICAgICAgfVxuICAgICAgaWYgKHNraXApIHtcbiAgICAgICAgYXR0cnNbUEhYX1NLSVBdID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IFtuZXdSb290LCBjb21tZW50QmVmb3JlLCBjb21tZW50QWZ0ZXJdID0gbW9kaWZ5Um9vdChcbiAgICAgICAgb3V0cHV0LmJ1ZmZlcixcbiAgICAgICAgYXR0cnMsXG4gICAgICAgIHNraXAsXG4gICAgICApO1xuICAgICAgcmVuZGVyZWQubmV3UmVuZGVyID0gZmFsc2U7XG4gICAgICBvdXRwdXQuYnVmZmVyID0gcHJldkJ1ZmZlciArIGNvbW1lbnRCZWZvcmUgKyBuZXdSb290ICsgY29tbWVudEFmdGVyO1xuICAgIH1cbiAgfVxuXG4gIGNvbXByZWhlbnNpb25Ub0J1ZmZlcihyZW5kZXJlZCwgdGVtcGxhdGVzLCBvdXRwdXQsIGNoYW5nZVRyYWNraW5nKSB7XG4gICAgY29uc3Qga2V5ZWRUZW1wbGF0ZXMgPSB0ZW1wbGF0ZXMgfHwgcmVuZGVyZWRbVEVNUExBVEVTXTtcbiAgICBjb25zdCBzdGF0aWNzID0gdGhpcy50ZW1wbGF0ZVN0YXRpYyhyZW5kZXJlZFtTVEFUSUNdLCB0ZW1wbGF0ZXMpO1xuICAgIHJlbmRlcmVkW1NUQVRJQ10gPSBzdGF0aWNzO1xuICAgIGRlbGV0ZSByZW5kZXJlZFtURU1QTEFURVNdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVuZGVyZWRbS0VZRURdW0tFWUVEX0NPVU5UXTsgaSsrKSB7XG4gICAgICBvdXRwdXQuYnVmZmVyICs9IHN0YXRpY3NbMF07XG4gICAgICBmb3IgKGxldCBqID0gMTsgaiA8IHN0YXRpY3MubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgdGhpcy5keW5hbWljVG9CdWZmZXIoXG4gICAgICAgICAgcmVuZGVyZWRbS0VZRURdW2ldW2ogLSAxXSxcbiAgICAgICAgICBrZXllZFRlbXBsYXRlcyxcbiAgICAgICAgICBvdXRwdXQsXG4gICAgICAgICAgY2hhbmdlVHJhY2tpbmcsXG4gICAgICAgICk7XG4gICAgICAgIG91dHB1dC5idWZmZXIgKz0gc3RhdGljc1tqXTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gd2UgZG9uJ3QgbmVlZCB0byBzdG9yZSB0aGUgcmVuZGVyZWQgdHJlZSBmb3Igc3RyZWFtc1xuICAgIGlmIChyZW5kZXJlZFtTVFJFQU1dKSB7XG4gICAgICBjb25zdCBzdHJlYW0gPSByZW5kZXJlZFtTVFJFQU1dO1xuICAgICAgY29uc3QgW19yZWYsIF9pbnNlcnRzLCBkZWxldGVJZHMsIHJlc2V0XSA9IHN0cmVhbSB8fCBbbnVsbCwge30sIFtdLCBudWxsXTtcbiAgICAgIGlmIChcbiAgICAgICAgc3RyZWFtICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgKHJlbmRlcmVkW0tFWUVEXVtLRVlFRF9DT1VOVF0gPiAwIHx8IGRlbGV0ZUlkcy5sZW5ndGggPiAwIHx8IHJlc2V0KVxuICAgICAgKSB7XG4gICAgICAgIGRlbGV0ZSByZW5kZXJlZFtTVFJFQU1dO1xuICAgICAgICByZW5kZXJlZFtLRVlFRF0gPSB7XG4gICAgICAgICAgW0tFWUVEX0NPVU5UXTogMCxcbiAgICAgICAgfTtcbiAgICAgICAgb3V0cHV0LnN0cmVhbXMuYWRkKHN0cmVhbSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZHluYW1pY1RvQnVmZmVyKHJlbmRlcmVkLCB0ZW1wbGF0ZXMsIG91dHB1dCwgY2hhbmdlVHJhY2tpbmcpIHtcbiAgICBpZiAodHlwZW9mIHJlbmRlcmVkID09PSBcIm51bWJlclwiKSB7XG4gICAgICBjb25zdCB7IGJ1ZmZlcjogc3RyLCBzdHJlYW1zIH0gPSB0aGlzLnJlY3Vyc2l2ZUNJRFRvU3RyaW5nKFxuICAgICAgICBvdXRwdXQuY29tcG9uZW50cyxcbiAgICAgICAgcmVuZGVyZWQsXG4gICAgICAgIG91dHB1dC5vbmx5Q2lkcyxcbiAgICAgICk7XG4gICAgICBvdXRwdXQuYnVmZmVyICs9IHN0cjtcbiAgICAgIG91dHB1dC5zdHJlYW1zID0gbmV3IFNldChbLi4ub3V0cHV0LnN0cmVhbXMsIC4uLnN0cmVhbXNdKTtcbiAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KHJlbmRlcmVkKSkge1xuICAgICAgdGhpcy50b091dHB1dEJ1ZmZlcihyZW5kZXJlZCwgdGVtcGxhdGVzLCBvdXRwdXQsIGNoYW5nZVRyYWNraW5nLCB7fSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dC5idWZmZXIgKz0gcmVuZGVyZWQ7XG4gICAgfVxuICB9XG5cbiAgcmVjdXJzaXZlQ0lEVG9TdHJpbmcoY29tcG9uZW50cywgY2lkLCBvbmx5Q2lkcykge1xuICAgIGNvbnN0IGNvbXBvbmVudCA9XG4gICAgICBjb21wb25lbnRzW2NpZF0gfHwgbG9nRXJyb3IoYG5vIGNvbXBvbmVudCBmb3IgQ0lEICR7Y2lkfWAsIGNvbXBvbmVudHMpO1xuICAgIGNvbnN0IGF0dHJzID0geyBbUEhYX0NPTVBPTkVOVF06IGNpZCwgW1BIWF9WSUVXX1JFRl06IHRoaXMudmlld0lkIH07XG4gICAgY29uc3Qgc2tpcCA9IG9ubHlDaWRzICYmICFvbmx5Q2lkcy5oYXMoY2lkKTtcbiAgICAvLyBUd28gb3B0aW1pemF0aW9uIHBhdGhzIGFwcGx5IGhlcmU6XG4gICAgLy9cbiAgICAvLyAgIDEuIFRoZSBvbmx5Q2lkcyBvcHRpbWl6YXRpb24gd29ya3MgYnkgdGhlIHNlcnZlciBkaWZmIHRlbGxpbmcgdXMgb25seSBzcGVjaWZpY1xuICAgIC8vICAgICBjaWQncyBoYXZlIGNoYW5nZWQuIFRoaXMgYWxsb3dzIHVzIHRvIHNraXAgcmVuZGVyaW5nIGFueSBjb21wb25lbnQgdGhhdCBoYXNuJ3QgY2hhbmdlZCxcbiAgICAvLyAgICAgd2hpY2ggdWx0aW1hdGVseSBzZXRzIFBIWF9TS0lQIHJvb3QgYXR0cmlidXRlIGFuZCBhdm9pZHMgcmVuZGVyaW5nIHRoZSBpbm5lckhUTUwuXG4gICAgLy9cbiAgICAvLyAgIDIuIFRoZSByb290IFBIWF9TS0lQIG9wdGltaXphdGlvbiBnZW5lcmFsaXplcyB0byBhbGwgSEVFeCBmdW5jdGlvbiBjb21wb25lbnRzLCBhbmRcbiAgICAvLyAgICAgd29ya3MgaW4gdGhlIHNhbWUgUEhYX1NLSVAgYXR0cmlidXRlIGZhc2hpb24gYXMgMSwgYnV0IHRoZSBuZXdSZW5kZXIgdHJhY2tpbmcgaXMgZG9uZVxuICAgIC8vICAgICBhdCB0aGUgZ2VuZXJhbCBkaWZmIG1lcmdlIGxldmVsLiBJZiB3ZSBtZXJnZSBhIGRpZmYgd2l0aCBuZXcgZHluYW1pY3MsIHdlIG5lY2Vzc2FyaWx5IGhhdmVcbiAgICAvLyAgICAgZXhwZXJpZW5jZWQgYSBjaGFuZ2Ugd2hpY2ggbXVzdCBiZSBhIG5ld1JlbmRlciwgYW5kIHRodXMgd2UgY2FuJ3Qgc2tpcCB0aGUgcmVuZGVyLlxuICAgIC8vXG4gICAgLy8gQm90aCBvcHRpbWl6YXRpb24gZmxvd3MgYXBwbHkgaGVyZS4gbmV3UmVuZGVyIGlzIHNldCBiYXNlZCBvbiB0aGUgb25seUNpZHMgb3B0aW1pemF0aW9uLCBhbmRcbiAgICAvLyB3ZSB0cmFjayBhIGRldGVybWluaXN0aWMgbWFnaWNJZCBiYXNlZCBvbiB0aGUgY2lkLlxuICAgIC8vXG4gICAgLy8gY2hhbmdlVHJhY2tpbmcgaXMgYWJvdXQgdGhlIGVudGlyZSB0cmVlXG4gICAgLy8gbmV3UmVuZGVyIGlzIGFib3V0IHRoZSBjdXJyZW50IHJvb3QgaW4gdGhlIHRyZWVcbiAgICAvL1xuICAgIC8vIEJ5IGRlZmF1bHQgY2hhbmdlVHJhY2tpbmcgaXMgZW5hYmxlZCwgYnV0IHdlIHNwZWNpYWwgY2FzZSB0aGUgZmxvdyB3aGVyZSB0aGUgY2xpZW50IGlzIHBydW5pbmdcbiAgICAvLyBjaWRzIGFuZCB0aGUgc2VydmVyIGFkZHMgdGhlIGNvbXBvbmVudCBiYWNrLiBJbiBzdWNoIGNhc2VzLCB3ZSBleHBsaWNpdGx5IGRpc2FibGUgY2hhbmdlVHJhY2tpbmdcbiAgICAvLyB3aXRoIHJlc2V0UmVuZGVyIGZvciB0aGlzIGNpZCwgdGhlbiByZS1lbmFibGUgaXQgYWZ0ZXIgdGhlIHJlY3Vyc2l2ZSBjYWxsIHRvIHNraXAgdGhlIG9wdGltaXphdGlvblxuICAgIC8vIGZvciB0aGUgZW50aXJlIGNvbXBvbmVudCB0cmVlLlxuICAgIGNvbXBvbmVudC5uZXdSZW5kZXIgPSAhc2tpcDtcbiAgICBjb21wb25lbnQubWFnaWNJZCA9IGBjJHtjaWR9LSR7dGhpcy5wYXJlbnRWaWV3SWQoKX1gO1xuICAgIC8vIGVuYWJsZSBjaGFuZ2UgdHJhY2tpbmcgYXMgbG9uZyBhcyB0aGUgY29tcG9uZW50IGhhc24ndCBiZWVuIHJlc2V0XG4gICAgY29uc3QgY2hhbmdlVHJhY2tpbmcgPSAhY29tcG9uZW50LnJlc2V0O1xuICAgIGNvbnN0IHsgYnVmZmVyOiBodG1sLCBzdHJlYW1zIH0gPSB0aGlzLnJlY3Vyc2l2ZVRvU3RyaW5nKFxuICAgICAgY29tcG9uZW50LFxuICAgICAgY29tcG9uZW50cyxcbiAgICAgIG9ubHlDaWRzLFxuICAgICAgY2hhbmdlVHJhY2tpbmcsXG4gICAgICBhdHRycyxcbiAgICApO1xuICAgIC8vIGRpc2FibGUgcmVzZXQgYWZ0ZXIgd2UndmUgcmVuZGVyZWRcbiAgICBkZWxldGUgY29tcG9uZW50LnJlc2V0O1xuXG4gICAgcmV0dXJuIHsgYnVmZmVyOiBodG1sLCBzdHJlYW1zOiBzdHJlYW1zIH07XG4gIH1cbn1cbiIsICJpbXBvcnQgRE9NIGZyb20gXCIuL2RvbVwiO1xuaW1wb3J0IEFSSUEgZnJvbSBcIi4vYXJpYVwiO1xuXG5jb25zdCBmb2N1c1N0YWNrID0gW107XG5jb25zdCBkZWZhdWx0X3RyYW5zaXRpb25fdGltZSA9IDIwMDtcblxuY29uc3QgSlMgPSB7XG4gIC8vIHByaXZhdGVcbiAgZXhlYyhlLCBldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZGVmYXVsdHMpIHtcbiAgICBjb25zdCBbZGVmYXVsdEtpbmQsIGRlZmF1bHRBcmdzXSA9IGRlZmF1bHRzIHx8IFtcbiAgICAgIG51bGwsXG4gICAgICB7IGNhbGxiYWNrOiBkZWZhdWx0cyAmJiBkZWZhdWx0cy5jYWxsYmFjayB9LFxuICAgIF07XG4gICAgY29uc3QgY29tbWFuZHMgPVxuICAgICAgcGh4RXZlbnQuY2hhckF0KDApID09PSBcIltcIlxuICAgICAgICA/IEpTT04ucGFyc2UocGh4RXZlbnQpXG4gICAgICAgIDogW1tkZWZhdWx0S2luZCwgZGVmYXVsdEFyZ3NdXTtcblxuICAgIGNvbW1hbmRzLmZvckVhY2goKFtraW5kLCBhcmdzXSkgPT4ge1xuICAgICAgaWYgKGtpbmQgPT09IGRlZmF1bHRLaW5kKSB7XG4gICAgICAgIC8vIGFsd2F5cyBwcmVmZXIgdGhlIGFyZ3MsIGJ1dCBrZWVwIGV4aXN0aW5nIGtleXMgZnJvbSB0aGUgZGVmYXVsdEFyZ3NcbiAgICAgICAgYXJncyA9IHsgLi4uZGVmYXVsdEFyZ3MsIC4uLmFyZ3MgfTtcbiAgICAgICAgYXJncy5jYWxsYmFjayA9IGFyZ3MuY2FsbGJhY2sgfHwgZGVmYXVsdEFyZ3MuY2FsbGJhY2s7XG4gICAgICB9XG4gICAgICB0aGlzLmZpbHRlclRvRWxzKHZpZXcubGl2ZVNvY2tldCwgc291cmNlRWwsIGFyZ3MpLmZvckVhY2goKGVsKSA9PiB7XG4gICAgICAgIHRoaXNbYGV4ZWNfJHtraW5kfWBdKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgYXJncyk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSxcblxuICBpc1Zpc2libGUoZWwpIHtcbiAgICByZXR1cm4gISEoXG4gICAgICBlbC5vZmZzZXRXaWR0aCB8fFxuICAgICAgZWwub2Zmc2V0SGVpZ2h0IHx8XG4gICAgICBlbC5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCA+IDBcbiAgICApO1xuICB9LFxuXG4gIC8vIHJldHVybnMgdHJ1ZSBpZiBhbnkgcGFydCBvZiB0aGUgZWxlbWVudCBpcyBpbnNpZGUgdGhlIHZpZXdwb3J0XG4gIGlzSW5WaWV3cG9ydChlbCkge1xuICAgIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCB3aW5kb3dIZWlnaHQgPVxuICAgICAgd2luZG93LmlubmVySGVpZ2h0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQ7XG4gICAgY29uc3Qgd2luZG93V2lkdGggPVxuICAgICAgd2luZG93LmlubmVyV2lkdGggfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoO1xuXG4gICAgcmV0dXJuIChcbiAgICAgIHJlY3QucmlnaHQgPiAwICYmXG4gICAgICByZWN0LmJvdHRvbSA+IDAgJiZcbiAgICAgIHJlY3QubGVmdCA8IHdpbmRvd1dpZHRoICYmXG4gICAgICByZWN0LnRvcCA8IHdpbmRvd0hlaWdodFxuICAgICk7XG4gIH0sXG5cbiAgLy8gcHJpdmF0ZVxuXG4gIC8vIGNvbW1hbmRzXG5cbiAgZXhlY19leGVjKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgeyBhdHRyLCB0byB9KSB7XG4gICAgY29uc3QgZW5jb2RlZEpTID0gZWwuZ2V0QXR0cmlidXRlKGF0dHIpO1xuICAgIGlmICghZW5jb2RlZEpTKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGV4cGVjdGVkICR7YXR0cn0gdG8gY29udGFpbiBKUyBjb21tYW5kIG9uIFwiJHt0b31cImApO1xuICAgIH1cbiAgICB2aWV3LmxpdmVTb2NrZXQuZXhlY0pTKGVsLCBlbmNvZGVkSlMsIGV2ZW50VHlwZSk7XG4gIH0sXG5cbiAgZXhlY19kaXNwYXRjaChcbiAgICBlLFxuICAgIGV2ZW50VHlwZSxcbiAgICBwaHhFdmVudCxcbiAgICB2aWV3LFxuICAgIHNvdXJjZUVsLFxuICAgIGVsLFxuICAgIHsgZXZlbnQsIGRldGFpbCwgYnViYmxlcywgYmxvY2tpbmcgfSxcbiAgKSB7XG4gICAgZGV0YWlsID0gZGV0YWlsIHx8IHt9O1xuICAgIGRldGFpbC5kaXNwYXRjaGVyID0gc291cmNlRWw7XG4gICAgaWYgKGJsb2NraW5nKSB7XG4gICAgICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUsIF9yZWplY3QpID0+IHtcbiAgICAgICAgZGV0YWlsLmRvbmUgPSByZXNvbHZlO1xuICAgICAgfSk7XG4gICAgICB2aWV3LmxpdmVTb2NrZXQuYXN5bmNUcmFuc2l0aW9uKHByb21pc2UpO1xuICAgIH1cbiAgICBET00uZGlzcGF0Y2hFdmVudChlbCwgZXZlbnQsIHsgZGV0YWlsLCBidWJibGVzIH0pO1xuICB9LFxuXG4gIGV4ZWNfcHVzaChlLCBldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIGFyZ3MpIHtcbiAgICBjb25zdCB7XG4gICAgICBldmVudCxcbiAgICAgIGRhdGEsXG4gICAgICB0YXJnZXQsXG4gICAgICBwYWdlX2xvYWRpbmcsXG4gICAgICBsb2FkaW5nLFxuICAgICAgdmFsdWUsXG4gICAgICBkaXNwYXRjaGVyLFxuICAgICAgY2FsbGJhY2ssXG4gICAgfSA9IGFyZ3M7XG4gICAgY29uc3QgcHVzaE9wdHMgPSB7XG4gICAgICBsb2FkaW5nLFxuICAgICAgdmFsdWUsXG4gICAgICB0YXJnZXQsXG4gICAgICBwYWdlX2xvYWRpbmc6ICEhcGFnZV9sb2FkaW5nLFxuICAgICAgb3JpZ2luYWxFdmVudDogZSxcbiAgICB9O1xuICAgIGNvbnN0IHRhcmdldFNyYyA9XG4gICAgICBldmVudFR5cGUgPT09IFwiY2hhbmdlXCIgJiYgZGlzcGF0Y2hlciA/IGRpc3BhdGNoZXIgOiBzb3VyY2VFbDtcbiAgICBjb25zdCBwaHhUYXJnZXQgPVxuICAgICAgdGFyZ2V0IHx8IHRhcmdldFNyYy5nZXRBdHRyaWJ1dGUodmlldy5iaW5kaW5nKFwidGFyZ2V0XCIpKSB8fCB0YXJnZXRTcmM7XG4gICAgY29uc3QgaGFuZGxlciA9ICh0YXJnZXRWaWV3LCB0YXJnZXRDdHgpID0+IHtcbiAgICAgIGlmICghdGFyZ2V0Vmlldy5pc0Nvbm5lY3RlZCgpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChldmVudFR5cGUgPT09IFwiY2hhbmdlXCIpIHtcbiAgICAgICAgbGV0IHsgbmV3Q2lkLCBfdGFyZ2V0IH0gPSBhcmdzO1xuICAgICAgICBfdGFyZ2V0ID1cbiAgICAgICAgICBfdGFyZ2V0IHx8IChET00uaXNGb3JtSW5wdXQoc291cmNlRWwpID8gc291cmNlRWwubmFtZSA6IHVuZGVmaW5lZCk7XG4gICAgICAgIGlmIChfdGFyZ2V0KSB7XG4gICAgICAgICAgcHVzaE9wdHMuX3RhcmdldCA9IF90YXJnZXQ7XG4gICAgICAgIH1cbiAgICAgICAgdGFyZ2V0Vmlldy5wdXNoSW5wdXQoXG4gICAgICAgICAgc291cmNlRWwsXG4gICAgICAgICAgdGFyZ2V0Q3R4LFxuICAgICAgICAgIG5ld0NpZCxcbiAgICAgICAgICBldmVudCB8fCBwaHhFdmVudCxcbiAgICAgICAgICBwdXNoT3B0cyxcbiAgICAgICAgICBjYWxsYmFjayxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoZXZlbnRUeXBlID09PSBcInN1Ym1pdFwiKSB7XG4gICAgICAgIGNvbnN0IHsgc3VibWl0dGVyIH0gPSBhcmdzO1xuICAgICAgICB0YXJnZXRWaWV3LnN1Ym1pdEZvcm0oXG4gICAgICAgICAgc291cmNlRWwsXG4gICAgICAgICAgdGFyZ2V0Q3R4LFxuICAgICAgICAgIGV2ZW50IHx8IHBoeEV2ZW50LFxuICAgICAgICAgIHN1Ym1pdHRlcixcbiAgICAgICAgICBwdXNoT3B0cyxcbiAgICAgICAgICBjYWxsYmFjayxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRhcmdldFZpZXcucHVzaEV2ZW50KFxuICAgICAgICAgIGV2ZW50VHlwZSxcbiAgICAgICAgICBzb3VyY2VFbCxcbiAgICAgICAgICB0YXJnZXRDdHgsXG4gICAgICAgICAgZXZlbnQgfHwgcGh4RXZlbnQsXG4gICAgICAgICAgZGF0YSxcbiAgICAgICAgICBwdXNoT3B0cyxcbiAgICAgICAgICBjYWxsYmFjayxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIC8vIGluIGNhc2Ugb2YgZm9ybVJlY292ZXJ5LCB0YXJnZXRWaWV3IGFuZCB0YXJnZXRDdHggYXJlIHBhc3NlZCBhcyBhcmd1bWVudFxuICAgIC8vIGFzIHRoZXkgYXJlIGxvb2tlZCB1cCBpbiBhIHRlbXBsYXRlIGVsZW1lbnQsIG5vdCB0aGUgcmVhbCBET01cbiAgICBpZiAoYXJncy50YXJnZXRWaWV3ICYmIGFyZ3MudGFyZ2V0Q3R4KSB7XG4gICAgICBoYW5kbGVyKGFyZ3MudGFyZ2V0VmlldywgYXJncy50YXJnZXRDdHgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2aWV3LndpdGhpblRhcmdldHMocGh4VGFyZ2V0LCBoYW5kbGVyKTtcbiAgICB9XG4gIH0sXG5cbiAgZXhlY19uYXZpZ2F0ZShlLCBldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIHsgaHJlZiwgcmVwbGFjZSB9KSB7XG4gICAgdmlldy5saXZlU29ja2V0Lmhpc3RvcnlSZWRpcmVjdChcbiAgICAgIGUsXG4gICAgICBocmVmLFxuICAgICAgcmVwbGFjZSA/IFwicmVwbGFjZVwiIDogXCJwdXNoXCIsXG4gICAgICBudWxsLFxuICAgICAgc291cmNlRWwsXG4gICAgKTtcbiAgfSxcblxuICBleGVjX3BhdGNoKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgeyBocmVmLCByZXBsYWNlIH0pIHtcbiAgICB2aWV3LmxpdmVTb2NrZXQucHVzaEhpc3RvcnlQYXRjaChcbiAgICAgIGUsXG4gICAgICBocmVmLFxuICAgICAgcmVwbGFjZSA/IFwicmVwbGFjZVwiIDogXCJwdXNoXCIsXG4gICAgICBzb3VyY2VFbCxcbiAgICApO1xuICB9LFxuXG4gIGV4ZWNfZm9jdXMoZSwgZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsKSB7XG4gICAgQVJJQS5hdHRlbXB0Rm9jdXMoZWwpO1xuICAgIC8vIGluIGNhc2UgdGhlIEpTLmZvY3VzIGNvbW1hbmQgaXMgaW4gYSBKUy5zaG93L2hpZGUvdG9nZ2xlIGNoYWluLCBmb3Igc2hvdyB3ZSBuZWVkXG4gICAgLy8gdG8gd2FpdCBmb3IgSlMuc2hvdyB0byBoYXZlIHVwZGF0ZWQgdGhlIGVsZW1lbnQncyBkaXNwbGF5IHByb3BlcnR5IChzZWUgZXhlY190b2dnbGUpXG4gICAgLy8gYnV0IHRoYXQgcnVuIGluIG5lc3RlZCBhbmltYXRpb24gZnJhbWVzLCB0aGVyZWZvcmUgd2UgbmVlZCB0byB1c2UgdGhlbSBoZXJlIGFzIHdlbGxcbiAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gQVJJQS5hdHRlbXB0Rm9jdXMoZWwpKTtcbiAgICB9KTtcbiAgfSxcblxuICBleGVjX2ZvY3VzX2ZpcnN0KGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCkge1xuICAgIEFSSUEuZm9jdXNGaXJzdEludGVyYWN0aXZlKGVsKSB8fCBBUklBLmZvY3VzRmlyc3QoZWwpO1xuICAgIC8vIGlmIHlvdSB3b25kZXIgYWJvdXQgdGhlIG5lc3RlZCBhbmltYXRpb24gZnJhbWVzLCBzZWUgZXhlY19mb2N1c1xuICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZShcbiAgICAgICAgKCkgPT4gQVJJQS5mb2N1c0ZpcnN0SW50ZXJhY3RpdmUoZWwpIHx8IEFSSUEuZm9jdXNGaXJzdChlbCksXG4gICAgICApO1xuICAgIH0pO1xuICB9LFxuXG4gIGV4ZWNfcHVzaF9mb2N1cyhlLCBldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwpIHtcbiAgICBmb2N1c1N0YWNrLnB1c2goZWwgfHwgc291cmNlRWwpO1xuICB9LFxuXG4gIGV4ZWNfcG9wX2ZvY3VzKF9lLCBfZXZlbnRUeXBlLCBfcGh4RXZlbnQsIF92aWV3LCBfc291cmNlRWwsIF9lbCkge1xuICAgIGNvbnN0IGVsID0gZm9jdXNTdGFjay5wb3AoKTtcbiAgICBpZiAoZWwpIHtcbiAgICAgIGVsLmZvY3VzKCk7XG4gICAgICAvLyBpZiB5b3Ugd29uZGVyIGFib3V0IHRoZSBuZXN0ZWQgYW5pbWF0aW9uIGZyYW1lcywgc2VlIGV4ZWNfZm9jdXNcbiAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IGVsLmZvY3VzKCkpO1xuICAgICAgfSk7XG4gICAgfVxuICB9LFxuXG4gIGV4ZWNfYWRkX2NsYXNzKFxuICAgIGUsXG4gICAgZXZlbnRUeXBlLFxuICAgIHBoeEV2ZW50LFxuICAgIHZpZXcsXG4gICAgc291cmNlRWwsXG4gICAgZWwsXG4gICAgeyBuYW1lcywgdHJhbnNpdGlvbiwgdGltZSwgYmxvY2tpbmcgfSxcbiAgKSB7XG4gICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIG5hbWVzLCBbXSwgdHJhbnNpdGlvbiwgdGltZSwgdmlldywgYmxvY2tpbmcpO1xuICB9LFxuXG4gIGV4ZWNfcmVtb3ZlX2NsYXNzKFxuICAgIGUsXG4gICAgZXZlbnRUeXBlLFxuICAgIHBoeEV2ZW50LFxuICAgIHZpZXcsXG4gICAgc291cmNlRWwsXG4gICAgZWwsXG4gICAgeyBuYW1lcywgdHJhbnNpdGlvbiwgdGltZSwgYmxvY2tpbmcgfSxcbiAgKSB7XG4gICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIFtdLCBuYW1lcywgdHJhbnNpdGlvbiwgdGltZSwgdmlldywgYmxvY2tpbmcpO1xuICB9LFxuXG4gIGV4ZWNfdG9nZ2xlX2NsYXNzKFxuICAgIGUsXG4gICAgZXZlbnRUeXBlLFxuICAgIHBoeEV2ZW50LFxuICAgIHZpZXcsXG4gICAgc291cmNlRWwsXG4gICAgZWwsXG4gICAgeyBuYW1lcywgdHJhbnNpdGlvbiwgdGltZSwgYmxvY2tpbmcgfSxcbiAgKSB7XG4gICAgdGhpcy50b2dnbGVDbGFzc2VzKGVsLCBuYW1lcywgdHJhbnNpdGlvbiwgdGltZSwgdmlldywgYmxvY2tpbmcpO1xuICB9LFxuXG4gIGV4ZWNfdG9nZ2xlX2F0dHIoXG4gICAgZSxcbiAgICBldmVudFR5cGUsXG4gICAgcGh4RXZlbnQsXG4gICAgdmlldyxcbiAgICBzb3VyY2VFbCxcbiAgICBlbCxcbiAgICB7IGF0dHI6IFthdHRyLCB2YWwxLCB2YWwyXSB9LFxuICApIHtcbiAgICB0aGlzLnRvZ2dsZUF0dHIoZWwsIGF0dHIsIHZhbDEsIHZhbDIpO1xuICB9LFxuXG4gIGV4ZWNfaWdub3JlX2F0dHJzKGUsIGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgeyBhdHRycyB9KSB7XG4gICAgdGhpcy5pZ25vcmVBdHRycyhlbCwgYXR0cnMpO1xuICB9LFxuXG4gIGV4ZWNfdHJhbnNpdGlvbihcbiAgICBlLFxuICAgIGV2ZW50VHlwZSxcbiAgICBwaHhFdmVudCxcbiAgICB2aWV3LFxuICAgIHNvdXJjZUVsLFxuICAgIGVsLFxuICAgIHsgdGltZSwgdHJhbnNpdGlvbiwgYmxvY2tpbmcgfSxcbiAgKSB7XG4gICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIFtdLCBbXSwgdHJhbnNpdGlvbiwgdGltZSwgdmlldywgYmxvY2tpbmcpO1xuICB9LFxuXG4gIGV4ZWNfdG9nZ2xlKFxuICAgIGUsXG4gICAgZXZlbnRUeXBlLFxuICAgIHBoeEV2ZW50LFxuICAgIHZpZXcsXG4gICAgc291cmNlRWwsXG4gICAgZWwsXG4gICAgeyBkaXNwbGF5LCBpbnMsIG91dHMsIHRpbWUsIGJsb2NraW5nIH0sXG4gICkge1xuICAgIHRoaXMudG9nZ2xlKGV2ZW50VHlwZSwgdmlldywgZWwsIGRpc3BsYXksIGlucywgb3V0cywgdGltZSwgYmxvY2tpbmcpO1xuICB9LFxuXG4gIGV4ZWNfc2hvdyhcbiAgICBlLFxuICAgIGV2ZW50VHlwZSxcbiAgICBwaHhFdmVudCxcbiAgICB2aWV3LFxuICAgIHNvdXJjZUVsLFxuICAgIGVsLFxuICAgIHsgZGlzcGxheSwgdHJhbnNpdGlvbiwgdGltZSwgYmxvY2tpbmcgfSxcbiAgKSB7XG4gICAgdGhpcy5zaG93KGV2ZW50VHlwZSwgdmlldywgZWwsIGRpc3BsYXksIHRyYW5zaXRpb24sIHRpbWUsIGJsb2NraW5nKTtcbiAgfSxcblxuICBleGVjX2hpZGUoXG4gICAgZSxcbiAgICBldmVudFR5cGUsXG4gICAgcGh4RXZlbnQsXG4gICAgdmlldyxcbiAgICBzb3VyY2VFbCxcbiAgICBlbCxcbiAgICB7IGRpc3BsYXksIHRyYW5zaXRpb24sIHRpbWUsIGJsb2NraW5nIH0sXG4gICkge1xuICAgIHRoaXMuaGlkZShldmVudFR5cGUsIHZpZXcsIGVsLCBkaXNwbGF5LCB0cmFuc2l0aW9uLCB0aW1lLCBibG9ja2luZyk7XG4gIH0sXG5cbiAgZXhlY19zZXRfYXR0cihcbiAgICBlLFxuICAgIGV2ZW50VHlwZSxcbiAgICBwaHhFdmVudCxcbiAgICB2aWV3LFxuICAgIHNvdXJjZUVsLFxuICAgIGVsLFxuICAgIHsgYXR0cjogW2F0dHIsIHZhbF0gfSxcbiAgKSB7XG4gICAgdGhpcy5zZXRPclJlbW92ZUF0dHJzKGVsLCBbW2F0dHIsIHZhbF1dLCBbXSk7XG4gIH0sXG5cbiAgZXhlY19yZW1vdmVfYXR0cihlLCBldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIHsgYXR0ciB9KSB7XG4gICAgdGhpcy5zZXRPclJlbW92ZUF0dHJzKGVsLCBbXSwgW2F0dHJdKTtcbiAgfSxcblxuICBpZ25vcmVBdHRycyhlbCwgYXR0cnMpIHtcbiAgICBET00ucHV0UHJpdmF0ZShlbCwgXCJKUzppZ25vcmVfYXR0cnNcIiwge1xuICAgICAgYXBwbHk6IChmcm9tRWwsIHRvRWwpID0+IHtcbiAgICAgICAgQXJyYXkuZnJvbShmcm9tRWwuYXR0cmlidXRlcykuZm9yRWFjaCgoYXR0cikgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGF0dHJzLnNvbWUoXG4gICAgICAgICAgICAgICh0b0lnbm9yZSkgPT5cbiAgICAgICAgICAgICAgICBhdHRyLm5hbWUgPT0gdG9JZ25vcmUgfHxcbiAgICAgICAgICAgICAgICB0b0lnbm9yZSA9PT0gXCIqXCIgfHxcbiAgICAgICAgICAgICAgICAodG9JZ25vcmUuaW5jbHVkZXMoXCIqXCIpICYmIGF0dHIubmFtZS5tYXRjaCh0b0lnbm9yZSkgIT0gbnVsbCksXG4gICAgICAgICAgICApXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0b0VsLnNldEF0dHJpYnV0ZShhdHRyLm5hbWUsIGF0dHIudmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9LFxuXG4gIG9uQmVmb3JlRWxVcGRhdGVkKGZyb21FbCwgdG9FbCkge1xuICAgIGNvbnN0IGlnbm9yZUF0dHJzID0gRE9NLnByaXZhdGUoZnJvbUVsLCBcIkpTOmlnbm9yZV9hdHRyc1wiKTtcbiAgICBpZiAoaWdub3JlQXR0cnMpIHtcbiAgICAgIGlnbm9yZUF0dHJzLmFwcGx5KGZyb21FbCwgdG9FbCk7XG4gICAgfVxuICB9LFxuXG4gIC8vIHV0aWxzIGZvciBjb21tYW5kc1xuXG4gIHNob3coZXZlbnRUeXBlLCB2aWV3LCBlbCwgZGlzcGxheSwgdHJhbnNpdGlvbiwgdGltZSwgYmxvY2tpbmcpIHtcbiAgICBpZiAoIXRoaXMuaXNWaXNpYmxlKGVsKSkge1xuICAgICAgdGhpcy50b2dnbGUoXG4gICAgICAgIGV2ZW50VHlwZSxcbiAgICAgICAgdmlldyxcbiAgICAgICAgZWwsXG4gICAgICAgIGRpc3BsYXksXG4gICAgICAgIHRyYW5zaXRpb24sXG4gICAgICAgIG51bGwsXG4gICAgICAgIHRpbWUsXG4gICAgICAgIGJsb2NraW5nLFxuICAgICAgKTtcbiAgICB9XG4gIH0sXG5cbiAgaGlkZShldmVudFR5cGUsIHZpZXcsIGVsLCBkaXNwbGF5LCB0cmFuc2l0aW9uLCB0aW1lLCBibG9ja2luZykge1xuICAgIGlmICh0aGlzLmlzVmlzaWJsZShlbCkpIHtcbiAgICAgIHRoaXMudG9nZ2xlKFxuICAgICAgICBldmVudFR5cGUsXG4gICAgICAgIHZpZXcsXG4gICAgICAgIGVsLFxuICAgICAgICBkaXNwbGF5LFxuICAgICAgICBudWxsLFxuICAgICAgICB0cmFuc2l0aW9uLFxuICAgICAgICB0aW1lLFxuICAgICAgICBibG9ja2luZyxcbiAgICAgICk7XG4gICAgfVxuICB9LFxuXG4gIHRvZ2dsZShldmVudFR5cGUsIHZpZXcsIGVsLCBkaXNwbGF5LCBpbnMsIG91dHMsIHRpbWUsIGJsb2NraW5nKSB7XG4gICAgdGltZSA9IHRpbWUgfHwgZGVmYXVsdF90cmFuc2l0aW9uX3RpbWU7XG4gICAgY29uc3QgW2luQ2xhc3NlcywgaW5TdGFydENsYXNzZXMsIGluRW5kQ2xhc3Nlc10gPSBpbnMgfHwgW1tdLCBbXSwgW11dO1xuICAgIGNvbnN0IFtvdXRDbGFzc2VzLCBvdXRTdGFydENsYXNzZXMsIG91dEVuZENsYXNzZXNdID0gb3V0cyB8fCBbW10sIFtdLCBbXV07XG4gICAgaWYgKGluQ2xhc3Nlcy5sZW5ndGggPiAwIHx8IG91dENsYXNzZXMubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKHRoaXMuaXNWaXNpYmxlKGVsKSkge1xuICAgICAgICBjb25zdCBvblN0YXJ0ID0gKCkgPT4ge1xuICAgICAgICAgIHRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKFxuICAgICAgICAgICAgZWwsXG4gICAgICAgICAgICBvdXRTdGFydENsYXNzZXMsXG4gICAgICAgICAgICBpbkNsYXNzZXMuY29uY2F0KGluU3RhcnRDbGFzc2VzKS5jb25jYXQoaW5FbmRDbGFzc2VzKSxcbiAgICAgICAgICApO1xuICAgICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIG91dENsYXNzZXMsIFtdKTtcbiAgICAgICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT5cbiAgICAgICAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIG91dEVuZENsYXNzZXMsIG91dFN0YXJ0Q2xhc3NlcyksXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBvbkVuZCA9ICgpID0+IHtcbiAgICAgICAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgW10sIG91dENsYXNzZXMuY29uY2F0KG91dEVuZENsYXNzZXMpKTtcbiAgICAgICAgICBET00ucHV0U3RpY2t5KFxuICAgICAgICAgICAgZWwsXG4gICAgICAgICAgICBcInRvZ2dsZVwiLFxuICAgICAgICAgICAgKGN1cnJlbnRFbCkgPT4gKGN1cnJlbnRFbC5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCIpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgZWwuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJwaHg6aGlkZS1lbmRcIikpO1xuICAgICAgICB9O1xuICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcInBoeDpoaWRlLXN0YXJ0XCIpKTtcbiAgICAgICAgaWYgKGJsb2NraW5nID09PSBmYWxzZSkge1xuICAgICAgICAgIG9uU3RhcnQoKTtcbiAgICAgICAgICBzZXRUaW1lb3V0KG9uRW5kLCB0aW1lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2aWV3LnRyYW5zaXRpb24odGltZSwgb25TdGFydCwgb25FbmQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZXZlbnRUeXBlID09PSBcInJlbW92ZVwiKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9uU3RhcnQgPSAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoXG4gICAgICAgICAgICBlbCxcbiAgICAgICAgICAgIGluU3RhcnRDbGFzc2VzLFxuICAgICAgICAgICAgb3V0Q2xhc3Nlcy5jb25jYXQob3V0U3RhcnRDbGFzc2VzKS5jb25jYXQob3V0RW5kQ2xhc3NlcyksXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb25zdCBzdGlja3lEaXNwbGF5ID0gZGlzcGxheSB8fCB0aGlzLmRlZmF1bHREaXNwbGF5KGVsKTtcbiAgICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgIC8vIGZpcnN0IGFkZCB0aGUgc3RhcnRpbmcgKyBhY3RpdmUgY2xhc3MsIFRIRU4gbWFrZSB0aGUgZWxlbWVudCB2aXNpYmxlXG4gICAgICAgICAgICAvLyBvdGhlcndpc2UgaWYgd2UgdG9nZ2xlZCB0aGUgdmlzaWJpbGl0eSBlYXJsaWVyIGNzcyBhbmltYXRpb25zXG4gICAgICAgICAgICAvLyB3b3VsZCBmbGlja2VyLCBhcyB0aGUgZWxlbWVudCBiZWNvbWVzIHZpc2libGUgYmVmb3JlIHRoZSBhY3RpdmUgYW5pbWF0aW9uXG4gICAgICAgICAgICAvLyBjbGFzcyBpcyBzZXQgKHNlZSBodHRwczovL2dpdGh1Yi5jb20vcGhvZW5peGZyYW1ld29yay9waG9lbml4X2xpdmVfdmlldy9pc3N1ZXMvMzQ1NilcbiAgICAgICAgICAgIHRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKGVsLCBpbkNsYXNzZXMsIFtdKTtcbiAgICAgICAgICAgIC8vIGFkZE9yUmVtb3ZlQ2xhc3NlcyB1c2VzIGEgcmVxdWVzdEFuaW1hdGlvbkZyYW1lIGl0c2VsZiwgdGhlcmVmb3JlIHdlIG5lZWQgdG8gbW92ZSB0aGUgcHV0U3RpY2t5XG4gICAgICAgICAgICAvLyBpbnRvIHRoZSBuZXh0IHJlcXVlc3RBbmltYXRpb25GcmFtZS4uLlxuICAgICAgICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgICAgIERPTS5wdXRTdGlja3koXG4gICAgICAgICAgICAgICAgZWwsXG4gICAgICAgICAgICAgICAgXCJ0b2dnbGVcIixcbiAgICAgICAgICAgICAgICAoY3VycmVudEVsKSA9PiAoY3VycmVudEVsLnN0eWxlLmRpc3BsYXkgPSBzdGlja3lEaXNwbGF5KSxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIGluRW5kQ2xhc3NlcywgaW5TdGFydENsYXNzZXMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IG9uRW5kID0gKCkgPT4ge1xuICAgICAgICAgIHRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKGVsLCBbXSwgaW5DbGFzc2VzLmNvbmNhdChpbkVuZENsYXNzZXMpKTtcbiAgICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcInBoeDpzaG93LWVuZFwiKSk7XG4gICAgICAgIH07XG4gICAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwicGh4OnNob3ctc3RhcnRcIikpO1xuICAgICAgICBpZiAoYmxvY2tpbmcgPT09IGZhbHNlKSB7XG4gICAgICAgICAgb25TdGFydCgpO1xuICAgICAgICAgIHNldFRpbWVvdXQob25FbmQsIHRpbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZpZXcudHJhbnNpdGlvbih0aW1lLCBvblN0YXJ0LCBvbkVuZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMuaXNWaXNpYmxlKGVsKSkge1xuICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcInBoeDpoaWRlLXN0YXJ0XCIpKTtcbiAgICAgICAgICBET00ucHV0U3RpY2t5KFxuICAgICAgICAgICAgZWwsXG4gICAgICAgICAgICBcInRvZ2dsZVwiLFxuICAgICAgICAgICAgKGN1cnJlbnRFbCkgPT4gKGN1cnJlbnRFbC5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCIpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgZWwuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJwaHg6aGlkZS1lbmRcIikpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwicGh4OnNob3ctc3RhcnRcIikpO1xuICAgICAgICAgIGNvbnN0IHN0aWNreURpc3BsYXkgPSBkaXNwbGF5IHx8IHRoaXMuZGVmYXVsdERpc3BsYXkoZWwpO1xuICAgICAgICAgIERPTS5wdXRTdGlja3koXG4gICAgICAgICAgICBlbCxcbiAgICAgICAgICAgIFwidG9nZ2xlXCIsXG4gICAgICAgICAgICAoY3VycmVudEVsKSA9PiAoY3VycmVudEVsLnN0eWxlLmRpc3BsYXkgPSBzdGlja3lEaXNwbGF5KSxcbiAgICAgICAgICApO1xuICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwicGh4OnNob3ctZW5kXCIpKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIHRvZ2dsZUNsYXNzZXMoZWwsIGNsYXNzZXMsIHRyYW5zaXRpb24sIHRpbWUsIHZpZXcsIGJsb2NraW5nKSB7XG4gICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICBjb25zdCBbcHJldkFkZHMsIHByZXZSZW1vdmVzXSA9IERPTS5nZXRTdGlja3koZWwsIFwiY2xhc3Nlc1wiLCBbW10sIFtdXSk7XG4gICAgICBjb25zdCBuZXdBZGRzID0gY2xhc3Nlcy5maWx0ZXIoXG4gICAgICAgIChuYW1lKSA9PiBwcmV2QWRkcy5pbmRleE9mKG5hbWUpIDwgMCAmJiAhZWwuY2xhc3NMaXN0LmNvbnRhaW5zKG5hbWUpLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IG5ld1JlbW92ZXMgPSBjbGFzc2VzLmZpbHRlcihcbiAgICAgICAgKG5hbWUpID0+IHByZXZSZW1vdmVzLmluZGV4T2YobmFtZSkgPCAwICYmIGVsLmNsYXNzTGlzdC5jb250YWlucyhuYW1lKSxcbiAgICAgICk7XG4gICAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhcbiAgICAgICAgZWwsXG4gICAgICAgIG5ld0FkZHMsXG4gICAgICAgIG5ld1JlbW92ZXMsXG4gICAgICAgIHRyYW5zaXRpb24sXG4gICAgICAgIHRpbWUsXG4gICAgICAgIHZpZXcsXG4gICAgICAgIGJsb2NraW5nLFxuICAgICAgKTtcbiAgICB9KTtcbiAgfSxcblxuICB0b2dnbGVBdHRyKGVsLCBhdHRyLCB2YWwxLCB2YWwyKSB7XG4gICAgaWYgKGVsLmhhc0F0dHJpYnV0ZShhdHRyKSkge1xuICAgICAgaWYgKHZhbDIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAvLyB0b2dnbGUgYmV0d2VlbiB2YWwxIGFuZCB2YWwyXG4gICAgICAgIGlmIChlbC5nZXRBdHRyaWJ1dGUoYXR0cikgPT09IHZhbDEpIHtcbiAgICAgICAgICB0aGlzLnNldE9yUmVtb3ZlQXR0cnMoZWwsIFtbYXR0ciwgdmFsMl1dLCBbXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zZXRPclJlbW92ZUF0dHJzKGVsLCBbW2F0dHIsIHZhbDFdXSwgW10pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyByZW1vdmUgYXR0clxuICAgICAgICB0aGlzLnNldE9yUmVtb3ZlQXR0cnMoZWwsIFtdLCBbYXR0cl0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldE9yUmVtb3ZlQXR0cnMoZWwsIFtbYXR0ciwgdmFsMV1dLCBbXSk7XG4gICAgfVxuICB9LFxuXG4gIGFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgYWRkcywgcmVtb3ZlcywgdHJhbnNpdGlvbiwgdGltZSwgdmlldywgYmxvY2tpbmcpIHtcbiAgICB0aW1lID0gdGltZSB8fCBkZWZhdWx0X3RyYW5zaXRpb25fdGltZTtcbiAgICBjb25zdCBbdHJhbnNpdGlvblJ1biwgdHJhbnNpdGlvblN0YXJ0LCB0cmFuc2l0aW9uRW5kXSA9IHRyYW5zaXRpb24gfHwgW1xuICAgICAgW10sXG4gICAgICBbXSxcbiAgICAgIFtdLFxuICAgIF07XG4gICAgaWYgKHRyYW5zaXRpb25SdW4ubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3Qgb25TdGFydCA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoXG4gICAgICAgICAgZWwsXG4gICAgICAgICAgdHJhbnNpdGlvblN0YXJ0LFxuICAgICAgICAgIFtdLmNvbmNhdCh0cmFuc2l0aW9uUnVuKS5jb25jYXQodHJhbnNpdGlvbkVuZCksXG4gICAgICAgICk7XG4gICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKGVsLCB0cmFuc2l0aW9uUnVuLCBbXSk7XG4gICAgICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PlxuICAgICAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIHRyYW5zaXRpb25FbmQsIHRyYW5zaXRpb25TdGFydCksXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgICAgY29uc3Qgb25Eb25lID0gKCkgPT5cbiAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoXG4gICAgICAgICAgZWwsXG4gICAgICAgICAgYWRkcy5jb25jYXQodHJhbnNpdGlvbkVuZCksXG4gICAgICAgICAgcmVtb3Zlcy5jb25jYXQodHJhbnNpdGlvblJ1bikuY29uY2F0KHRyYW5zaXRpb25TdGFydCksXG4gICAgICAgICk7XG4gICAgICBpZiAoYmxvY2tpbmcgPT09IGZhbHNlKSB7XG4gICAgICAgIG9uU3RhcnQoKTtcbiAgICAgICAgc2V0VGltZW91dChvbkRvbmUsIHRpbWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmlldy50cmFuc2l0aW9uKHRpbWUsIG9uU3RhcnQsIG9uRG9uZSk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICBjb25zdCBbcHJldkFkZHMsIHByZXZSZW1vdmVzXSA9IERPTS5nZXRTdGlja3koZWwsIFwiY2xhc3Nlc1wiLCBbW10sIFtdXSk7XG4gICAgICBjb25zdCBrZWVwQWRkcyA9IGFkZHMuZmlsdGVyKFxuICAgICAgICAobmFtZSkgPT4gcHJldkFkZHMuaW5kZXhPZihuYW1lKSA8IDAgJiYgIWVsLmNsYXNzTGlzdC5jb250YWlucyhuYW1lKSxcbiAgICAgICk7XG4gICAgICBjb25zdCBrZWVwUmVtb3ZlcyA9IHJlbW92ZXMuZmlsdGVyKFxuICAgICAgICAobmFtZSkgPT4gcHJldlJlbW92ZXMuaW5kZXhPZihuYW1lKSA8IDAgJiYgZWwuY2xhc3NMaXN0LmNvbnRhaW5zKG5hbWUpLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IG5ld0FkZHMgPSBwcmV2QWRkc1xuICAgICAgICAuZmlsdGVyKChuYW1lKSA9PiByZW1vdmVzLmluZGV4T2YobmFtZSkgPCAwKVxuICAgICAgICAuY29uY2F0KGtlZXBBZGRzKTtcbiAgICAgIGNvbnN0IG5ld1JlbW92ZXMgPSBwcmV2UmVtb3Zlc1xuICAgICAgICAuZmlsdGVyKChuYW1lKSA9PiBhZGRzLmluZGV4T2YobmFtZSkgPCAwKVxuICAgICAgICAuY29uY2F0KGtlZXBSZW1vdmVzKTtcblxuICAgICAgRE9NLnB1dFN0aWNreShlbCwgXCJjbGFzc2VzXCIsIChjdXJyZW50RWwpID0+IHtcbiAgICAgICAgY3VycmVudEVsLmNsYXNzTGlzdC5yZW1vdmUoLi4ubmV3UmVtb3Zlcyk7XG4gICAgICAgIGN1cnJlbnRFbC5jbGFzc0xpc3QuYWRkKC4uLm5ld0FkZHMpO1xuICAgICAgICByZXR1cm4gW25ld0FkZHMsIG5ld1JlbW92ZXNdO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG5cbiAgc2V0T3JSZW1vdmVBdHRycyhlbCwgc2V0cywgcmVtb3Zlcykge1xuICAgIGNvbnN0IFtwcmV2U2V0cywgcHJldlJlbW92ZXNdID0gRE9NLmdldFN0aWNreShlbCwgXCJhdHRyc1wiLCBbW10sIFtdXSk7XG5cbiAgICBjb25zdCBhbHRlcmVkQXR0cnMgPSBzZXRzLm1hcCgoW2F0dHIsIF92YWxdKSA9PiBhdHRyKS5jb25jYXQocmVtb3Zlcyk7XG4gICAgY29uc3QgbmV3U2V0cyA9IHByZXZTZXRzXG4gICAgICAuZmlsdGVyKChbYXR0ciwgX3ZhbF0pID0+ICFhbHRlcmVkQXR0cnMuaW5jbHVkZXMoYXR0cikpXG4gICAgICAuY29uY2F0KHNldHMpO1xuICAgIGNvbnN0IG5ld1JlbW92ZXMgPSBwcmV2UmVtb3Zlc1xuICAgICAgLmZpbHRlcigoYXR0cikgPT4gIWFsdGVyZWRBdHRycy5pbmNsdWRlcyhhdHRyKSlcbiAgICAgIC5jb25jYXQocmVtb3Zlcyk7XG5cbiAgICBET00ucHV0U3RpY2t5KGVsLCBcImF0dHJzXCIsIChjdXJyZW50RWwpID0+IHtcbiAgICAgIG5ld1JlbW92ZXMuZm9yRWFjaCgoYXR0cikgPT4gY3VycmVudEVsLnJlbW92ZUF0dHJpYnV0ZShhdHRyKSk7XG4gICAgICBuZXdTZXRzLmZvckVhY2goKFthdHRyLCB2YWxdKSA9PiBjdXJyZW50RWwuc2V0QXR0cmlidXRlKGF0dHIsIHZhbCkpO1xuICAgICAgcmV0dXJuIFtuZXdTZXRzLCBuZXdSZW1vdmVzXTtcbiAgICB9KTtcbiAgfSxcblxuICBoYXNBbGxDbGFzc2VzKGVsLCBjbGFzc2VzKSB7XG4gICAgcmV0dXJuIGNsYXNzZXMuZXZlcnkoKG5hbWUpID0+IGVsLmNsYXNzTGlzdC5jb250YWlucyhuYW1lKSk7XG4gIH0sXG5cbiAgaXNUb2dnbGVkT3V0KGVsLCBvdXRDbGFzc2VzKSB7XG4gICAgcmV0dXJuICF0aGlzLmlzVmlzaWJsZShlbCkgfHwgdGhpcy5oYXNBbGxDbGFzc2VzKGVsLCBvdXRDbGFzc2VzKTtcbiAgfSxcblxuICBmaWx0ZXJUb0VscyhsaXZlU29ja2V0LCBzb3VyY2VFbCwgeyB0byB9KSB7XG4gICAgY29uc3QgZGVmYXVsdFF1ZXJ5ID0gKCkgPT4ge1xuICAgICAgaWYgKHR5cGVvZiB0byA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCh0byk7XG4gICAgICB9IGVsc2UgaWYgKHRvLmNsb3Nlc3QpIHtcbiAgICAgICAgY29uc3QgdG9FbCA9IHNvdXJjZUVsLmNsb3Nlc3QodG8uY2xvc2VzdCk7XG4gICAgICAgIHJldHVybiB0b0VsID8gW3RvRWxdIDogW107XG4gICAgICB9IGVsc2UgaWYgKHRvLmlubmVyKSB7XG4gICAgICAgIHJldHVybiBzb3VyY2VFbC5xdWVyeVNlbGVjdG9yQWxsKHRvLmlubmVyKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiB0b1xuICAgICAgPyBsaXZlU29ja2V0LmpzUXVlcnlTZWxlY3RvckFsbChzb3VyY2VFbCwgdG8sIGRlZmF1bHRRdWVyeSlcbiAgICAgIDogW3NvdXJjZUVsXTtcbiAgfSxcblxuICBkZWZhdWx0RGlzcGxheShlbCkge1xuICAgIHJldHVybiAoXG4gICAgICB7IHRyOiBcInRhYmxlLXJvd1wiLCB0ZDogXCJ0YWJsZS1jZWxsXCIgfVtlbC50YWdOYW1lLnRvTG93ZXJDYXNlKCldIHx8IFwiYmxvY2tcIlxuICAgICk7XG4gIH0sXG5cbiAgdHJhbnNpdGlvbkNsYXNzZXModmFsKSB7XG4gICAgaWYgKCF2YWwpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGxldCBbdHJhbnMsIHRTdGFydCwgdEVuZF0gPSBBcnJheS5pc0FycmF5KHZhbClcbiAgICAgID8gdmFsXG4gICAgICA6IFt2YWwuc3BsaXQoXCIgXCIpLCBbXSwgW11dO1xuICAgIHRyYW5zID0gQXJyYXkuaXNBcnJheSh0cmFucykgPyB0cmFucyA6IHRyYW5zLnNwbGl0KFwiIFwiKTtcbiAgICB0U3RhcnQgPSBBcnJheS5pc0FycmF5KHRTdGFydCkgPyB0U3RhcnQgOiB0U3RhcnQuc3BsaXQoXCIgXCIpO1xuICAgIHRFbmQgPSBBcnJheS5pc0FycmF5KHRFbmQpID8gdEVuZCA6IHRFbmQuc3BsaXQoXCIgXCIpO1xuICAgIHJldHVybiBbdHJhbnMsIHRTdGFydCwgdEVuZF07XG4gIH0sXG59O1xuXG5leHBvcnQgZGVmYXVsdCBKUztcbiIsICJpbXBvcnQgSlMgZnJvbSBcIi4vanNcIjtcbmltcG9ydCBMaXZlU29ja2V0IGZyb20gXCIuL2xpdmVfc29ja2V0XCI7XG5cbnR5cGUgVHJhbnNpdGlvbiA9IHN0cmluZyB8IHN0cmluZ1tdO1xuXG4vLyBCYXNlIG9wdGlvbnMgZm9yIGNvbW1hbmRzIGludm9sdmluZyB0cmFuc2l0aW9ucyBhbmQgdGltaW5nXG50eXBlIEJhc2VPcHRzID0ge1xuICAvKipcbiAgICogVGhlIENTUyB0cmFuc2l0aW9uIGNsYXNzZXMgdG8gc2V0LlxuICAgKiBBY2NlcHRzIGEgc3RyaW5nIG9mIGNsYXNzZXMgb3IgYSAzLXR1cGxlIGxpa2U6XG4gICAqIGBbXCJlYXNlLW91dCBkdXJhdGlvbi0zMDBcIiwgXCJvcGFjaXR5LTBcIiwgXCJvcGFjaXR5LTEwMFwiXWBcbiAgICovXG4gIHRyYW5zaXRpb24/OiBUcmFuc2l0aW9uO1xuICAvKiogVGhlIHRyYW5zaXRpb24gZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzLiBEZWZhdWx0cyAyMDAuICovXG4gIHRpbWU/OiBudW1iZXI7XG4gIC8qKiBXaGV0aGVyIHRvIGJsb2NrIFVJIGR1cmluZyB0cmFuc2l0aW9uLiBEZWZhdWx0cyBgdHJ1ZWAuICovXG4gIGJsb2NraW5nPzogYm9vbGVhbjtcbn07XG5cbnR5cGUgU2hvd09wdHMgPSBCYXNlT3B0cyAmIHtcbiAgLyoqIFRoZSBDU1MgZGlzcGxheSB2YWx1ZSB0byBzZXQuIERlZmF1bHRzIFwiYmxvY2tcIi4gKi9cbiAgZGlzcGxheT86IHN0cmluZztcbn07XG5cbnR5cGUgVG9nZ2xlT3B0cyA9IHtcbiAgLyoqIFRoZSBDU1MgZGlzcGxheSB2YWx1ZSB0byBzZXQuIERlZmF1bHRzIFwiYmxvY2tcIi4gKi9cbiAgZGlzcGxheT86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBDU1MgdHJhbnNpdGlvbiBjbGFzc2VzIGZvciBzaG93aW5nLlxuICAgKiBBY2NlcHRzIGVpdGhlciB0aGUgc3RyaW5nIG9mIGNsYXNzZXMgdG8gYXBwbHkgd2hlbiB0b2dnbGluZyBpbiwgb3JcbiAgICogYSAzLXR1cGxlIGNvbnRhaW5pbmcgdGhlIHRyYW5zaXRpb24gY2xhc3MsIHRoZSBjbGFzcyB0byBhcHBseVxuICAgKiB0byBzdGFydCB0aGUgdHJhbnNpdGlvbiwgYW5kIHRoZSBlbmRpbmcgdHJhbnNpdGlvbiBjbGFzcywgc3VjaCBhczpcbiAgICogYFtcImVhc2Utb3V0IGR1cmF0aW9uLTMwMFwiLCBcIm9wYWNpdHktMFwiLCBcIm9wYWNpdHktMTAwXCJdYFxuICAgKi9cbiAgaW4/OiBUcmFuc2l0aW9uO1xuICAvKipcbiAgICogVGhlIENTUyB0cmFuc2l0aW9uIGNsYXNzZXMgZm9yIGhpZGluZy5cbiAgICogQWNjZXB0cyBlaXRoZXIgc3RyaW5nIG9mIGNsYXNzZXMgdG8gYXBwbHkgd2hlbiB0b2dnbGluZyBvdXQsIG9yXG4gICAqIGEgMy10dXBsZSBjb250YWluaW5nIHRoZSB0cmFuc2l0aW9uIGNsYXNzLCB0aGUgY2xhc3MgdG8gYXBwbHlcbiAgICogdG8gc3RhcnQgdGhlIHRyYW5zaXRpb24sIGFuZCB0aGUgZW5kaW5nIHRyYW5zaXRpb24gY2xhc3MsIHN1Y2ggYXM6XG4gICAqIGBbXCJlYXNlLW91dCBkdXJhdGlvbi0zMDBcIiwgXCJvcGFjaXR5LTEwMFwiLCBcIm9wYWNpdHktMFwiXWBcbiAgICovXG4gIG91dD86IFRyYW5zaXRpb247XG4gIC8qKiBUaGUgdHJhbnNpdGlvbiBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMuICovXG4gIHRpbWU/OiBudW1iZXI7XG4gIC8qKiBXaGV0aGVyIHRvIGJsb2NrIFVJIGR1cmluZyB0cmFuc2l0aW9uLiBEZWZhdWx0cyBgdHJ1ZWAuICovXG4gIGJsb2NraW5nPzogYm9vbGVhbjtcbn07XG5cbi8vIE9wdGlvbnMgc3BlY2lmaWMgdG8gdGhlICd0cmFuc2l0aW9uJyBjb21tYW5kXG50eXBlIFRyYW5zaXRpb25Db21tYW5kT3B0cyA9IHtcbiAgLyoqIFRoZSB0cmFuc2l0aW9uIGR1cmF0aW9uIGluIG1pbGxpc2Vjb25kcy4gKi9cbiAgdGltZT86IG51bWJlcjtcbiAgLyoqIFdoZXRoZXIgdG8gYmxvY2sgVUkgZHVyaW5nIHRyYW5zaXRpb24uIERlZmF1bHRzIGB0cnVlYC4gKi9cbiAgYmxvY2tpbmc/OiBib29sZWFuO1xufTtcblxudHlwZSBQdXNoT3B0cyA9IHtcbiAgLyoqIERhdGEgdG8gYmUgbWVyZ2VkIGludG8gdGhlIGV2ZW50IHBheWxvYWQuICovXG4gIHZhbHVlPzogYW55O1xuICAvKiogRm9yIHRhcmdldGluZyBhIExpdmVDb21wb25lbnQgYnkgaXRzIElELCBhIGNvbXBvbmVudCBJRCAobnVtYmVyKSwgb3IgYSBDU1Mgc2VsZWN0b3Igc3RyaW5nLiAqL1xuICB0YXJnZXQ/OiBIVE1MRWxlbWVudCB8IG51bWJlciB8IHN0cmluZztcbiAgLyoqIEluZGljYXRlcyBpZiBhIHBhZ2UgbG9hZGluZyBzdGF0ZSBzaG91bGQgYmUgc2hvd24uICovXG4gIHBhZ2VfbG9hZGluZz86IGJvb2xlYW47XG4gIFtrZXk6IHN0cmluZ106IGFueTsgLy8gQWxsb3cgb3RoZXIgcHJvcGVydGllcyBsaWtlICdjaWQnLCAncmVkaXJlY3QnLCBldGMuXG59O1xuXG50eXBlIE5hdmlnYXRpb25PcHRzID0ge1xuICAvKiogV2hldGhlciB0byByZXBsYWNlIHRoZSBjdXJyZW50IGhpc3RvcnkgZW50cnkgaW5zdGVhZCBvZiBwdXNoaW5nIGEgbmV3IG9uZS4gKi9cbiAgcmVwbGFjZT86IGJvb2xlYW47XG59O1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYWxsIHBvc3NpYmxlIEpTIGNvbW1hbmRzIHRoYXQgY2FuIGJlIGdlbmVyYXRlZCBieSB0aGUgZmFjdG9yeS5cbiAqIFRoaXMgaXMgdXNlZCBhcyBhIGJhc2UgZm9yIExpdmVTb2NrZXRKU0NvbW1hbmRzIGFuZCBIb29rSlNDb21tYW5kcy5cbiAqL1xuaW50ZXJmYWNlIEFsbEpTQ29tbWFuZHMge1xuICAvKipcbiAgICogRXhlY3V0ZXMgZW5jb2RlZCBKYXZhU2NyaXB0IGluIHRoZSBjb250ZXh0IG9mIHRoZSBlbGVtZW50LlxuICAgKiBUaGlzIHZlcnNpb24gaXMgZm9yIGdlbmVyYWwgdXNlIHZpYSBsaXZlU29ja2V0LmpzKCkuXG4gICAqXG4gICAqIEBwYXJhbSBlbCAtIFRoZSBlbGVtZW50IGluIHdob3NlIGNvbnRleHQgdG8gZXhlY3V0ZSB0aGUgSmF2YVNjcmlwdC5cbiAgICogQHBhcmFtIGVuY29kZWRKUyAtIFRoZSBlbmNvZGVkIEphdmFTY3JpcHQgc3RyaW5nIHRvIGV4ZWN1dGUuXG4gICAqL1xuICBleGVjKGVsOiBIVE1MRWxlbWVudCwgZW5jb2RlZEpTOiBzdHJpbmcpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBTaG93cyBhbiBlbGVtZW50LlxuICAgKlxuICAgKiBAcGFyYW0gZWwgLSBUaGUgZWxlbWVudCB0byBzaG93LlxuICAgKiBAcGFyYW0ge1Nob3dPcHRzfSBbb3B0cz17fV0gLSBPcHRpb25hbCBzZXR0aW5ncy5cbiAgICogICBBY2NlcHRzOiBgZGlzcGxheWAsIGB0cmFuc2l0aW9uYCwgYHRpbWVgLCBhbmQgYGJsb2NraW5nYC5cbiAgICovXG4gIHNob3coZWw6IEhUTUxFbGVtZW50LCBvcHRzPzogU2hvd09wdHMpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBIaWRlcyBhbiBlbGVtZW50LlxuICAgKlxuICAgKiBAcGFyYW0gZWwgLSBUaGUgZWxlbWVudCB0byBoaWRlLlxuICAgKiBAcGFyYW0gW29wdHM9e31dIC0gT3B0aW9uYWwgc2V0dGluZ3MuXG4gICAqICAgQWNjZXB0czogYHRyYW5zaXRpb25gLCBgdGltZWAsIGFuZCBgYmxvY2tpbmdgLlxuICAgKi9cbiAgaGlkZShlbDogSFRNTEVsZW1lbnQsIG9wdHM/OiBCYXNlT3B0cyk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFRvZ2dsZXMgdGhlIHZpc2liaWxpdHkgb2YgYW4gZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIGVsIC0gVGhlIGVsZW1lbnQgdG8gdG9nZ2xlLlxuICAgKiBAcGFyYW0gW29wdHM9e31dIC0gT3B0aW9uYWwgc2V0dGluZ3MuXG4gICAqICAgQWNjZXB0czogYGRpc3BsYXlgLCBgaW5gLCBgb3V0YCwgYHRpbWVgLCBhbmQgYGJsb2NraW5nYC5cbiAgICovXG4gIHRvZ2dsZShlbDogSFRNTEVsZW1lbnQsIG9wdHM/OiBUb2dnbGVPcHRzKTogdm9pZDtcblxuICAvKipcbiAgICogQWRkcyBDU1MgY2xhc3NlcyB0byBhbiBlbGVtZW50LlxuICAgKlxuICAgKiBAcGFyYW0gZWwgLSBUaGUgZWxlbWVudCB0byBhZGQgY2xhc3NlcyB0by5cbiAgICogQHBhcmFtIG5hbWVzIC0gVGhlIGNsYXNzIG5hbWUocykgdG8gYWRkLlxuICAgKiBAcGFyYW0gW29wdHM9e31dIC0gT3B0aW9uYWwgc2V0dGluZ3MuXG4gICAqICAgQWNjZXB0czogYHRyYW5zaXRpb25gLCBgdGltZWAsIGFuZCBgYmxvY2tpbmdgLlxuICAgKi9cbiAgYWRkQ2xhc3MoZWw6IEhUTUxFbGVtZW50LCBuYW1lczogc3RyaW5nIHwgc3RyaW5nW10sIG9wdHM/OiBCYXNlT3B0cyk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgQ1NTIGNsYXNzZXMgZnJvbSBhbiBlbGVtZW50LlxuICAgKlxuICAgKiBAcGFyYW0gZWwgLSBUaGUgZWxlbWVudCB0byByZW1vdmUgY2xhc3NlcyBmcm9tLlxuICAgKiBAcGFyYW0gbmFtZXMgLSBUaGUgY2xhc3MgbmFtZShzKSB0byByZW1vdmUuXG4gICAqIEBwYXJhbSBbb3B0cz17fV0gLSBPcHRpb25hbCBzZXR0aW5ncy5cbiAgICogICBBY2NlcHRzOiBgdHJhbnNpdGlvbmAsIGB0aW1lYCwgYW5kIGBibG9ja2luZ2AuXG4gICAqL1xuICByZW1vdmVDbGFzcyhlbDogSFRNTEVsZW1lbnQsIG5hbWVzOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3B0cz86IEJhc2VPcHRzKTogdm9pZDtcblxuICAvKipcbiAgICogVG9nZ2xlcyBDU1MgY2xhc3NlcyBvbiBhbiBlbGVtZW50LlxuICAgKlxuICAgKiBAcGFyYW0gZWwgLSBUaGUgZWxlbWVudCB0byB0b2dnbGUgY2xhc3NlcyBvbi5cbiAgICogQHBhcmFtIG5hbWVzIC0gVGhlIGNsYXNzIG5hbWUocykgdG8gdG9nZ2xlLlxuICAgKiBAcGFyYW0gW29wdHM9e31dIC0gT3B0aW9uYWwgc2V0dGluZ3MuXG4gICAqICAgQWNjZXB0czogYHRyYW5zaXRpb25gLCBgdGltZWAsIGFuZCBgYmxvY2tpbmdgLlxuICAgKi9cbiAgdG9nZ2xlQ2xhc3MoZWw6IEhUTUxFbGVtZW50LCBuYW1lczogc3RyaW5nIHwgc3RyaW5nW10sIG9wdHM/OiBCYXNlT3B0cyk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIEFwcGxpZXMgYSBDU1MgdHJhbnNpdGlvbiB0byBhbiBlbGVtZW50LlxuICAgKlxuICAgKiBAcGFyYW0gZWwgLSBUaGUgZWxlbWVudCB0byBhcHBseSB0aGUgdHJhbnNpdGlvbiB0by5cbiAgICogQHBhcmFtIHRyYW5zaXRpb24gLSBUaGUgdHJhbnNpdGlvbiBjbGFzcyhlcykgdG8gYXBwbHkuXG4gICAqICAgQWNjZXB0cyBhIHN0cmluZyBvZiBjbGFzc2VzIHRvIGFwcGx5IHdoZW4gdHJhbnNpdGlvbmluZyBvclxuICAgKiAgIGEgMy10dXBsZSBjb250YWluaW5nIHRoZSB0cmFuc2l0aW9uIGNsYXNzLCB0aGUgY2xhc3MgdG8gYXBwbHlcbiAgICogICB0byBzdGFydCB0aGUgdHJhbnNpdGlvbiwgYW5kIHRoZSBlbmRpbmcgdHJhbnNpdGlvbiBjbGFzcywgc3VjaCBhczpcbiAgICpcbiAgICogICAgICAgW1wiZWFzZS1vdXQgZHVyYXRpb24tMzAwXCIsIFwib3BhY2l0eS0xMDBcIiwgXCJvcGFjaXR5LTBcIl1cbiAgICpcbiAgICogQHBhcmFtIFtvcHRzPXt9XSAtIE9wdGlvbmFsIHNldHRpbmdzIGZvciB0aW1pbmcgYW5kIGJsb2NraW5nIGJlaGF2aW9yLlxuICAgKiAgIEFjY2VwdHM6IGB0aW1lYCBhbmQgYGJsb2NraW5nYC5cbiAgICovXG4gIHRyYW5zaXRpb24oXG4gICAgZWw6IEhUTUxFbGVtZW50LFxuICAgIHRyYW5zaXRpb246IHN0cmluZyB8IHN0cmluZ1tdLFxuICAgIG9wdHM/OiBUcmFuc2l0aW9uQ29tbWFuZE9wdHMsXG4gICk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFNldHMgYW4gYXR0cmlidXRlIG9uIGFuIGVsZW1lbnQuXG4gICAqXG4gICAqIEBwYXJhbSBlbCAtIFRoZSBlbGVtZW50IHRvIHNldCB0aGUgYXR0cmlidXRlIG9uLlxuICAgKiBAcGFyYW0gYXR0ciAtIFRoZSBhdHRyaWJ1dGUgbmFtZSB0byBzZXQuXG4gICAqIEBwYXJhbSB2YWwgLSBUaGUgdmFsdWUgdG8gc2V0IGZvciB0aGUgYXR0cmlidXRlLlxuICAgKi9cbiAgc2V0QXR0cmlidXRlKGVsOiBIVE1MRWxlbWVudCwgYXR0cjogc3RyaW5nLCB2YWw6IHN0cmluZyk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYW4gYXR0cmlidXRlIGZyb20gYW4gZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIGVsIC0gVGhlIGVsZW1lbnQgdG8gcmVtb3ZlIHRoZSBhdHRyaWJ1dGUgZnJvbS5cbiAgICogQHBhcmFtIGF0dHIgLSBUaGUgYXR0cmlidXRlIG5hbWUgdG8gcmVtb3ZlLlxuICAgKi9cbiAgcmVtb3ZlQXR0cmlidXRlKGVsOiBIVE1MRWxlbWVudCwgYXR0cjogc3RyaW5nKTogdm9pZDtcblxuICAvKipcbiAgICogVG9nZ2xlcyBhbiBhdHRyaWJ1dGUgb24gYW4gZWxlbWVudCBiZXR3ZWVuIHR3byB2YWx1ZXMuXG4gICAqXG4gICAqIEBwYXJhbSBlbCAtIFRoZSBlbGVtZW50IHRvIHRvZ2dsZSB0aGUgYXR0cmlidXRlIG9uLlxuICAgKiBAcGFyYW0gYXR0ciAtIFRoZSBhdHRyaWJ1dGUgbmFtZSB0byB0b2dnbGUuXG4gICAqIEBwYXJhbSB2YWwxIC0gVGhlIGZpcnN0IHZhbHVlIHRvIHRvZ2dsZSBiZXR3ZWVuLlxuICAgKiBAcGFyYW0gdmFsMiAtIFRoZSBzZWNvbmQgdmFsdWUgdG8gdG9nZ2xlIGJldHdlZW4uXG4gICAqL1xuICB0b2dnbGVBdHRyaWJ1dGUoXG4gICAgZWw6IEhUTUxFbGVtZW50LFxuICAgIGF0dHI6IHN0cmluZyxcbiAgICB2YWwxOiBzdHJpbmcsXG4gICAgdmFsMjogc3RyaW5nLFxuICApOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBQdXNoZXMgYW4gZXZlbnQgdG8gdGhlIHNlcnZlci5cbiAgICpcbiAgICogQHBhcmFtIGVsIC0gQW4gZWxlbWVudCB0aGF0IGJlbG9uZ3MgdG8gdGhlIHRhcmdldCBMaXZlVmlldyAvIExpdmVDb21wb25lbnQgb3IgYSBjb21wb25lbnQgSUQuXG4gICAqICAgVG8gdGFyZ2V0IGEgTGl2ZUNvbXBvbmVudCBieSBpdHMgSUQsIHBhc3MgYSBzZXBhcmF0ZSBgdGFyZ2V0YCBpbiB0aGUgb3B0aW9ucy5cbiAgICogQHBhcmFtIHR5cGUgLSBUaGUgZXZlbnQgbmFtZSB0byBwdXNoLlxuICAgKiBAcGFyYW0gW29wdHM9e31dIC0gT3B0aW9uYWwgc2V0dGluZ3MuXG4gICAqICAgQWNjZXB0czogYHZhbHVlYCwgYHRhcmdldGAsIGBwYWdlX2xvYWRpbmdgLlxuICAgKi9cbiAgcHVzaChlbDogSFRNTEVsZW1lbnQsIHR5cGU6IHN0cmluZywgb3B0cz86IFB1c2hPcHRzKTogdm9pZDtcblxuICAvKipcbiAgICogU2VuZHMgYSBuYXZpZ2F0aW9uIGV2ZW50IHRvIHRoZSBzZXJ2ZXIgYW5kIHVwZGF0ZXMgdGhlIGJyb3dzZXIncyBwdXNoU3RhdGUgaGlzdG9yeS5cbiAgICpcbiAgICogQHBhcmFtIGhyZWYgLSBUaGUgVVJMIHRvIG5hdmlnYXRlIHRvLlxuICAgKiBAcGFyYW0gW29wdHM9e31dIC0gT3B0aW9uYWwgc2V0dGluZ3MuXG4gICAqICAgQWNjZXB0czogYHJlcGxhY2VgLlxuICAgKi9cbiAgbmF2aWdhdGUoaHJlZjogc3RyaW5nLCBvcHRzPzogTmF2aWdhdGlvbk9wdHMpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBTZW5kcyBhIHBhdGNoIGV2ZW50IHRvIHRoZSBzZXJ2ZXIgYW5kIHVwZGF0ZXMgdGhlIGJyb3dzZXIncyBwdXNoU3RhdGUgaGlzdG9yeS5cbiAgICpcbiAgICogQHBhcmFtIGhyZWYgLSBUaGUgVVJMIHRvIHBhdGNoIHRvLlxuICAgKiBAcGFyYW0gW29wdHM9e31dIC0gT3B0aW9uYWwgc2V0dGluZ3MuXG4gICAqICAgQWNjZXB0czogYHJlcGxhY2VgLlxuICAgKi9cbiAgcGF0Y2goaHJlZjogc3RyaW5nLCBvcHRzPzogTmF2aWdhdGlvbk9wdHMpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBNYXJrIGF0dHJpYnV0ZXMgYXMgaWdub3JlZCwgc2tpcHBpbmcgdGhlbSB3aGVuIHBhdGNoaW5nIHRoZSBET00uXG4gICAqXG4gICAqIEBwYXJhbSBlbCAtIFRoZSBlbGVtZW50IHRvIGlnbm9yZSBhdHRyaWJ1dGVzIG9uLlxuICAgKiBAcGFyYW0gYXR0cnMgLSBUaGUgYXR0cmlidXRlIG5hbWUgb3IgbmFtZXMgdG8gaWdub3JlLlxuICAgKi9cbiAgaWdub3JlQXR0cmlidXRlcyhlbDogSFRNTEVsZW1lbnQsIGF0dHJzOiBzdHJpbmcgfCBzdHJpbmdbXSk6IHZvaWQ7XG59XG5cbmV4cG9ydCBkZWZhdWx0IChcbiAgbGl2ZVNvY2tldDogTGl2ZVNvY2tldCxcbiAgZXZlbnRUeXBlOiBzdHJpbmcgfCBudWxsLFxuKTogQWxsSlNDb21tYW5kcyA9PiB7XG4gIHJldHVybiB7XG4gICAgZXhlYyhlbCwgZW5jb2RlZEpTKSB7XG4gICAgICBsaXZlU29ja2V0LmV4ZWNKUyhlbCwgZW5jb2RlZEpTLCBldmVudFR5cGUpO1xuICAgIH0sXG4gICAgc2hvdyhlbCwgb3B0cyA9IHt9KSB7XG4gICAgICBjb25zdCBvd25lciA9IGxpdmVTb2NrZXQub3duZXIoZWwpO1xuICAgICAgSlMuc2hvdyhcbiAgICAgICAgZXZlbnRUeXBlLFxuICAgICAgICBvd25lcixcbiAgICAgICAgZWwsXG4gICAgICAgIG9wdHMuZGlzcGxheSxcbiAgICAgICAgSlMudHJhbnNpdGlvbkNsYXNzZXMob3B0cy50cmFuc2l0aW9uKSxcbiAgICAgICAgb3B0cy50aW1lLFxuICAgICAgICBvcHRzLmJsb2NraW5nLFxuICAgICAgKTtcbiAgICB9LFxuICAgIGhpZGUoZWwsIG9wdHMgPSB7fSkge1xuICAgICAgY29uc3Qgb3duZXIgPSBsaXZlU29ja2V0Lm93bmVyKGVsKTtcbiAgICAgIEpTLmhpZGUoXG4gICAgICAgIGV2ZW50VHlwZSxcbiAgICAgICAgb3duZXIsXG4gICAgICAgIGVsLFxuICAgICAgICBudWxsLFxuICAgICAgICBKUy50cmFuc2l0aW9uQ2xhc3NlcyhvcHRzLnRyYW5zaXRpb24pLFxuICAgICAgICBvcHRzLnRpbWUsXG4gICAgICAgIG9wdHMuYmxvY2tpbmcsXG4gICAgICApO1xuICAgIH0sXG4gICAgdG9nZ2xlKGVsLCBvcHRzID0ge30pIHtcbiAgICAgIGNvbnN0IG93bmVyID0gbGl2ZVNvY2tldC5vd25lcihlbCk7XG4gICAgICBjb25zdCBpblRyYW5zaXRpb24gPSBKUy50cmFuc2l0aW9uQ2xhc3NlcyhvcHRzLmluKTtcbiAgICAgIGNvbnN0IG91dFRyYW5zaXRpb24gPSBKUy50cmFuc2l0aW9uQ2xhc3NlcyhvcHRzLm91dCk7XG4gICAgICBKUy50b2dnbGUoXG4gICAgICAgIGV2ZW50VHlwZSxcbiAgICAgICAgb3duZXIsXG4gICAgICAgIGVsLFxuICAgICAgICBvcHRzLmRpc3BsYXksXG4gICAgICAgIGluVHJhbnNpdGlvbixcbiAgICAgICAgb3V0VHJhbnNpdGlvbixcbiAgICAgICAgb3B0cy50aW1lLFxuICAgICAgICBvcHRzLmJsb2NraW5nLFxuICAgICAgKTtcbiAgICB9LFxuICAgIGFkZENsYXNzKGVsLCBuYW1lcywgb3B0cyA9IHt9KSB7XG4gICAgICBjb25zdCBjbGFzc05hbWVzID0gQXJyYXkuaXNBcnJheShuYW1lcykgPyBuYW1lcyA6IG5hbWVzLnNwbGl0KFwiIFwiKTtcbiAgICAgIGNvbnN0IG93bmVyID0gbGl2ZVNvY2tldC5vd25lcihlbCk7XG4gICAgICBKUy5hZGRPclJlbW92ZUNsYXNzZXMoXG4gICAgICAgIGVsLFxuICAgICAgICBjbGFzc05hbWVzLFxuICAgICAgICBbXSxcbiAgICAgICAgSlMudHJhbnNpdGlvbkNsYXNzZXMob3B0cy50cmFuc2l0aW9uKSxcbiAgICAgICAgb3B0cy50aW1lLFxuICAgICAgICBvd25lcixcbiAgICAgICAgb3B0cy5ibG9ja2luZyxcbiAgICAgICk7XG4gICAgfSxcbiAgICByZW1vdmVDbGFzcyhlbCwgbmFtZXMsIG9wdHMgPSB7fSkge1xuICAgICAgY29uc3QgY2xhc3NOYW1lcyA9IEFycmF5LmlzQXJyYXkobmFtZXMpID8gbmFtZXMgOiBuYW1lcy5zcGxpdChcIiBcIik7XG4gICAgICBjb25zdCBvd25lciA9IGxpdmVTb2NrZXQub3duZXIoZWwpO1xuICAgICAgSlMuYWRkT3JSZW1vdmVDbGFzc2VzKFxuICAgICAgICBlbCxcbiAgICAgICAgW10sXG4gICAgICAgIGNsYXNzTmFtZXMsXG4gICAgICAgIEpTLnRyYW5zaXRpb25DbGFzc2VzKG9wdHMudHJhbnNpdGlvbiksXG4gICAgICAgIG9wdHMudGltZSxcbiAgICAgICAgb3duZXIsXG4gICAgICAgIG9wdHMuYmxvY2tpbmcsXG4gICAgICApO1xuICAgIH0sXG4gICAgdG9nZ2xlQ2xhc3MoZWwsIG5hbWVzLCBvcHRzID0ge30pIHtcbiAgICAgIGNvbnN0IGNsYXNzTmFtZXMgPSBBcnJheS5pc0FycmF5KG5hbWVzKSA/IG5hbWVzIDogbmFtZXMuc3BsaXQoXCIgXCIpO1xuICAgICAgY29uc3Qgb3duZXIgPSBsaXZlU29ja2V0Lm93bmVyKGVsKTtcbiAgICAgIEpTLnRvZ2dsZUNsYXNzZXMoXG4gICAgICAgIGVsLFxuICAgICAgICBjbGFzc05hbWVzLFxuICAgICAgICBKUy50cmFuc2l0aW9uQ2xhc3NlcyhvcHRzLnRyYW5zaXRpb24pLFxuICAgICAgICBvcHRzLnRpbWUsXG4gICAgICAgIG93bmVyLFxuICAgICAgICBvcHRzLmJsb2NraW5nLFxuICAgICAgKTtcbiAgICB9LFxuICAgIHRyYW5zaXRpb24oZWwsIHRyYW5zaXRpb24sIG9wdHMgPSB7fSkge1xuICAgICAgY29uc3Qgb3duZXIgPSBsaXZlU29ja2V0Lm93bmVyKGVsKTtcbiAgICAgIEpTLmFkZE9yUmVtb3ZlQ2xhc3NlcyhcbiAgICAgICAgZWwsXG4gICAgICAgIFtdLFxuICAgICAgICBbXSxcbiAgICAgICAgSlMudHJhbnNpdGlvbkNsYXNzZXModHJhbnNpdGlvbiksXG4gICAgICAgIG9wdHMudGltZSxcbiAgICAgICAgb3duZXIsXG4gICAgICAgIG9wdHMuYmxvY2tpbmcsXG4gICAgICApO1xuICAgIH0sXG4gICAgc2V0QXR0cmlidXRlKGVsLCBhdHRyLCB2YWwpIHtcbiAgICAgIEpTLnNldE9yUmVtb3ZlQXR0cnMoZWwsIFtbYXR0ciwgdmFsXV0sIFtdKTtcbiAgICB9LFxuICAgIHJlbW92ZUF0dHJpYnV0ZShlbCwgYXR0cikge1xuICAgICAgSlMuc2V0T3JSZW1vdmVBdHRycyhlbCwgW10sIFthdHRyXSk7XG4gICAgfSxcbiAgICB0b2dnbGVBdHRyaWJ1dGUoZWwsIGF0dHIsIHZhbDEsIHZhbDIpIHtcbiAgICAgIEpTLnRvZ2dsZUF0dHIoZWwsIGF0dHIsIHZhbDEsIHZhbDIpO1xuICAgIH0sXG4gICAgcHVzaChlbCwgdHlwZSwgb3B0cyA9IHt9KSB7XG4gICAgICBsaXZlU29ja2V0LndpdGhpbk93bmVycyhlbCwgKHZpZXcpID0+IHtcbiAgICAgICAgY29uc3QgZGF0YSA9IG9wdHMudmFsdWUgfHwge307XG4gICAgICAgIGRlbGV0ZSBvcHRzLnZhbHVlO1xuICAgICAgICBsZXQgZSA9IG5ldyBDdXN0b21FdmVudChcInBoeDpleGVjXCIsIHsgZGV0YWlsOiB7IHNvdXJjZUVsZW1lbnQ6IGVsIH0gfSk7XG4gICAgICAgIEpTLmV4ZWMoZSwgZXZlbnRUeXBlLCB0eXBlLCB2aWV3LCBlbCwgW1wicHVzaFwiLCB7IGRhdGEsIC4uLm9wdHMgfV0pO1xuICAgICAgfSk7XG4gICAgfSxcbiAgICBuYXZpZ2F0ZShocmVmLCBvcHRzID0ge30pIHtcbiAgICAgIGNvbnN0IGN1c3RvbUV2ZW50ID0gbmV3IEN1c3RvbUV2ZW50KFwicGh4OmV4ZWNcIik7XG4gICAgICBsaXZlU29ja2V0Lmhpc3RvcnlSZWRpcmVjdChcbiAgICAgICAgY3VzdG9tRXZlbnQsXG4gICAgICAgIGhyZWYsXG4gICAgICAgIG9wdHMucmVwbGFjZSA/IFwicmVwbGFjZVwiIDogXCJwdXNoXCIsXG4gICAgICAgIG51bGwsXG4gICAgICAgIG51bGwsXG4gICAgICApO1xuICAgIH0sXG4gICAgcGF0Y2goaHJlZiwgb3B0cyA9IHt9KSB7XG4gICAgICBjb25zdCBjdXN0b21FdmVudCA9IG5ldyBDdXN0b21FdmVudChcInBoeDpleGVjXCIpO1xuICAgICAgbGl2ZVNvY2tldC5wdXNoSGlzdG9yeVBhdGNoKFxuICAgICAgICBjdXN0b21FdmVudCxcbiAgICAgICAgaHJlZixcbiAgICAgICAgb3B0cy5yZXBsYWNlID8gXCJyZXBsYWNlXCIgOiBcInB1c2hcIixcbiAgICAgICAgbnVsbCxcbiAgICAgICk7XG4gICAgfSxcbiAgICBpZ25vcmVBdHRyaWJ1dGVzKGVsLCBhdHRycykge1xuICAgICAgSlMuaWdub3JlQXR0cnMoZWwsIEFycmF5LmlzQXJyYXkoYXR0cnMpID8gYXR0cnMgOiBbYXR0cnNdKTtcbiAgICB9LFxuICB9O1xufTtcblxuLyoqXG4gKiBKU0NvbW1hbmRzIGZvciB1c2Ugd2l0aCBgbGl2ZVNvY2tldC5qcygpYC5cbiAqIEluY2x1ZGVzIHRoZSBnZW5lcmFsIGBleGVjYCBjb21tYW5kIHRoYXQgcmVxdWlyZXMgYW4gZWxlbWVudC5cbiAqL1xuZXhwb3J0IHR5cGUgTGl2ZVNvY2tldEpTQ29tbWFuZHMgPSBBbGxKU0NvbW1hbmRzO1xuXG4vKipcbiAqIEpTQ29tbWFuZHMgZm9yIHVzZSB3aXRoaW4gYSBIb29rLlxuICogVGhlIGBleGVjYCBjb21tYW5kIGlzIHRhaWxvcmVkIGZvciBob29rcywgbm90IHJlcXVpcmluZyBhbiBleHBsaWNpdCBlbGVtZW50LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEhvb2tKU0NvbW1hbmRzIGV4dGVuZHMgT21pdDxBbGxKU0NvbW1hbmRzLCBcImV4ZWNcIj4ge1xuICAvKipcbiAgICogRXhlY3V0ZXMgZW5jb2RlZCBKYXZhU2NyaXB0IGluIHRoZSBjb250ZXh0IG9mIHRoZSBob29rJ3MgZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGVuY29kZWRKUyAtIFRoZSBlbmNvZGVkIEphdmFTY3JpcHQgc3RyaW5nIHRvIGV4ZWN1dGUuXG4gICAqL1xuICBleGVjKGVuY29kZWRKUzogc3RyaW5nKTogdm9pZDtcbn1cbiIsICJpbXBvcnQganNDb21tYW5kcywgeyBIb29rSlNDb21tYW5kcyB9IGZyb20gXCIuL2pzX2NvbW1hbmRzXCI7XG5pbXBvcnQgRE9NIGZyb20gXCIuL2RvbVwiO1xuaW1wb3J0IExpdmVTb2NrZXQgZnJvbSBcIi4vbGl2ZV9zb2NrZXRcIjtcbmltcG9ydCBWaWV3IGZyb20gXCIuL3ZpZXdcIjtcblxuY29uc3QgSE9PS19JRCA9IFwiaG9va0lkXCI7XG5sZXQgdmlld0hvb2tJRCA9IDE7XG5cbmV4cG9ydCB0eXBlIE9uUmVwbHkgPSAocmVwbHk6IGFueSwgcmVmOiBudW1iZXIpID0+IGFueTtcbmV4cG9ydCB0eXBlIENhbGxiYWNrUmVmID0geyBldmVudDogc3RyaW5nOyBjYWxsYmFjazogKHBheWxvYWQ6IGFueSkgPT4gYW55IH07XG5cbmV4cG9ydCB0eXBlIFBoeFRhcmdldCA9IHN0cmluZyB8IG51bWJlciB8IEhUTUxFbGVtZW50O1xuXG5leHBvcnQgaW50ZXJmYWNlIEhvb2tJbnRlcmZhY2U8RSBleHRlbmRzIEhUTUxFbGVtZW50ID0gSFRNTEVsZW1lbnQ+IHtcbiAgLyoqXG4gICAqIFRoZSBET00gZWxlbWVudCB0aGF0IHRoZSBob29rIGlzIGF0dGFjaGVkIHRvLlxuICAgKi9cbiAgZWw6IEU7XG5cbiAgLyoqXG4gICAqIFRoZSBMaXZlU29ja2V0IGluc3RhbmNlIHRoYXQgdGhlIGhvb2sgaXMgYXR0YWNoZWQgdG8uXG4gICAqL1xuICBsaXZlU29ja2V0OiBMaXZlU29ja2V0O1xuXG4gIC8qKlxuICAgKiBUaGUgbW91bnRlZCBjYWxsYmFjay5cbiAgICpcbiAgICogQ2FsbGVkIHdoZW4gdGhlIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gdGhlIERPTSBhbmQgaXRzIHNlcnZlciBMaXZlVmlldyBoYXMgZmluaXNoZWQgbW91bnRpbmcuXG4gICAqL1xuICBtb3VudGVkPzogKCkgPT4gdm9pZDtcblxuICAvKipcbiAgICogVGhlIGJlZm9yZVVwZGF0ZSBjYWxsYmFjay5cbiAgICpcbiAgICogQ2FsbGVkIHdoZW4gdGhlIGVsZW1lbnQgaXMgYWJvdXQgdG8gYmUgdXBkYXRlZCBpbiB0aGUgRE9NLlxuICAgKiBOb3RlOiBhbnkgY2FsbCBoZXJlIG11c3QgYmUgc3luY2hyb25vdXMgYXMgdGhlIG9wZXJhdGlvbiBjYW5ub3QgYmUgZGVmZXJyZWQgb3IgY2FuY2VsbGVkLlxuICAgKi9cbiAgYmVmb3JlVXBkYXRlPzogKCkgPT4gdm9pZDtcblxuICAvKipcbiAgICogVGhlIHVwZGF0ZWQgY2FsbGJhY2suXG4gICAqXG4gICAqIENhbGxlZCB3aGVuIHRoZSBlbGVtZW50IGhhcyBiZWVuIHVwZGF0ZWQgaW4gdGhlIERPTSBieSB0aGUgc2VydmVyXG4gICAqL1xuICB1cGRhdGVkPzogKCkgPT4gdm9pZDtcblxuICAvKipcbiAgICogVGhlIGRlc3Ryb3llZCBjYWxsYmFjay5cbiAgICpcbiAgICogQ2FsbGVkIHdoZW4gdGhlIGVsZW1lbnQgaGFzIGJlZW4gcmVtb3ZlZCBmcm9tIHRoZSBwYWdlLCBlaXRoZXIgYnkgYSBwYXJlbnQgdXBkYXRlLCBvciBieSB0aGUgcGFyZW50IGJlaW5nIHJlbW92ZWQgZW50aXJlbHlcbiAgICovXG4gIGRlc3Ryb3llZD86ICgpID0+IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFRoZSBkaXNjb25uZWN0ZWQgY2FsbGJhY2suXG4gICAqXG4gICAqIENhbGxlZCB3aGVuIHRoZSBlbGVtZW50J3MgcGFyZW50IExpdmVWaWV3IGhhcyBkaXNjb25uZWN0ZWQgZnJvbSB0aGUgc2VydmVyLlxuICAgKi9cbiAgZGlzY29ubmVjdGVkPzogKCkgPT4gdm9pZDtcblxuICAvKipcbiAgICogVGhlIHJlY29ubmVjdGVkIGNhbGxiYWNrLlxuICAgKlxuICAgKiBDYWxsZWQgd2hlbiB0aGUgZWxlbWVudCdzIHBhcmVudCBMaXZlVmlldyBoYXMgcmVjb25uZWN0ZWQgdG8gdGhlIHNlcnZlci5cbiAgICovXG4gIHJlY29ubmVjdGVkPzogKCkgPT4gdm9pZDtcblxuICAvKipcbiAgICogUmV0dXJucyBhbiBvYmplY3Qgd2l0aCBtZXRob2RzIHRvIG1hbmlwbHVhdGUgdGhlIERPTSBhbmQgZXhlY3V0ZSBKYXZhU2NyaXB0LlxuICAgKiBUaGUgYXBwbGllZCBjaGFuZ2VzIGludGVncmF0ZSB3aXRoIHNlcnZlciBET00gcGF0Y2hpbmcuXG4gICAqL1xuICBqcygpOiBIb29rSlNDb21tYW5kcztcblxuICAvKipcbiAgICogUHVzaGVzIGFuIGV2ZW50IHRvIHRoZSBzZXJ2ZXIuXG4gICAqXG4gICAqIEBwYXJhbSBldmVudCAtIFRoZSBldmVudCBuYW1lLlxuICAgKiBAcGFyYW0gW3BheWxvYWRdIC0gVGhlIHBheWxvYWQgdG8gc2VuZCB0byB0aGUgc2VydmVyLiBEZWZhdWx0cyB0byBhbiBlbXB0eSBvYmplY3QuXG4gICAqIEBwYXJhbSBbb25SZXBseV0gLSBBIGNhbGxiYWNrIHRvIGhhbmRsZSB0aGUgc2VydmVyJ3MgcmVwbHkuXG4gICAqXG4gICAqIFdoZW4gb25SZXBseSBpcyBub3QgcHJvdmlkZWQsIHRoZSBtZXRob2QgcmV0dXJucyBhIFByb21pc2UgdGhhdFxuICAgKiBXaGVuIG9uUmVwbHkgaXMgcHJvdmlkZWQsIHRoZSBtZXRob2QgcmV0dXJucyB2b2lkLlxuICAgKi9cbiAgcHVzaEV2ZW50KGV2ZW50OiBzdHJpbmcsIHBheWxvYWQ6IGFueSwgb25SZXBseTogT25SZXBseSk6IHZvaWQ7XG4gIHB1c2hFdmVudChldmVudDogc3RyaW5nLCBwYXlsb2FkPzogYW55KTogUHJvbWlzZTxhbnk+O1xuXG4gIC8qKlxuICAgKiBQdXNoZWQgYSB0YXJnZXRlZCBldmVudCB0byB0aGUgc2VydmVyLlxuICAgKlxuICAgKiBJdCBzZW5kcyB0aGUgZXZlbnQgdG8gdGhlIExpdmVDb21wb25lbnQgb3IgTGl2ZVZpZXcgdGhlIGBzZWxlY3Rvck9yVGFyZ2V0YCBpcyBkZWZpbmVkIGluLFxuICAgKiB3aGVyZSBpdHMgdmFsdWUgY2FuIGJlIGVpdGhlciBhIHF1ZXJ5IHNlbGVjdG9yLCBhbiBhY3R1YWwgRE9NIGVsZW1lbnQsIG9yIGEgQ0lEIChjb21wb25lbnQgaWQpXG4gICAqIHJldHVybmVkIGJ5IHRoZSBgQG15c2VsZmAgYXNzaWduLlxuICAgKlxuICAgKiBJZiB0aGUgcXVlcnkgc2VsZWN0b3IgcmV0dXJucyBtb3JlIHRoYW4gb25lIGVsZW1lbnQgaXQgd2lsbCBzZW5kIHRoZSBldmVudCB0byBhbGwgb2YgdGhlbSxcbiAgICogZXZlbiBpZiBhbGwgdGhlIGVsZW1lbnRzIGFyZSBpbiB0aGUgc2FtZSBMaXZlQ29tcG9uZW50IG9yIExpdmVWaWV3LiBCZWNhdXNlIG9mIHRoaXMsXG4gICAqIGlmIG5vIGNhbGxiYWNrIGlzIHBhc3NlZCwgYSBwcm9taXNlIGlzIHJldHVybmVkIHRoYXQgbWF0Y2hlcyB0aGUgcmV0dXJuIHZhbHVlIG9mXG4gICAqIFtgUHJvbWlzZS5hbGxTZXR0bGVkKClgXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9Qcm9taXNlL2FsbFNldHRsZWQjcmV0dXJuX3ZhbHVlKS5cbiAgICogSW5kaXZpZHVhbCBmdWxmaWxsZWQgdmFsdWVzIGFyZSBvZiB0aGUgZm9ybWF0IGB7IHJlcGx5LCByZWYgfWAsIHdoZXJlIGByZXBseWAgaXMgdGhlIHNlcnZlcidzIHJlcGx5LlxuICAgKlxuICAgKiBAcGFyYW0gc2VsZWN0b3JPclRhcmdldCAtIFRoZSBzZWxlY3RvciwgZWxlbWVudCwgb3IgQ0lEIHRvIHRhcmdldC5cbiAgICogQHBhcmFtIGV2ZW50IC0gVGhlIGV2ZW50IG5hbWUuXG4gICAqIEBwYXJhbSBbcGF5bG9hZF0gLSBUaGUgcGF5bG9hZCB0byBzZW5kIHRvIHRoZSBzZXJ2ZXIuIERlZmF1bHRzIHRvIGFuIGVtcHR5IG9iamVjdC5cbiAgICogQHBhcmFtIFtvblJlcGx5XSAtIEEgY2FsbGJhY2sgdG8gaGFuZGxlIHRoZSBzZXJ2ZXIncyByZXBseS5cbiAgICpcbiAgICogV2hlbiBvblJlcGx5IGlzIG5vdCBwcm92aWRlZCwgdGhlIG1ldGhvZCByZXR1cm5zIGEgUHJvbWlzZS5cbiAgICogV2hlbiBvblJlcGx5IGlzIHByb3ZpZGVkLCB0aGUgbWV0aG9kIHJldHVybnMgdm9pZC5cbiAgICovXG4gIHB1c2hFdmVudFRvKFxuICAgIHNlbGVjdG9yT3JUYXJnZXQ6IFBoeFRhcmdldCxcbiAgICBldmVudDogc3RyaW5nLFxuICAgIHBheWxvYWQ6IG9iamVjdCxcbiAgICBvblJlcGx5OiBPblJlcGx5LFxuICApOiB2b2lkO1xuICBwdXNoRXZlbnRUbyhcbiAgICBzZWxlY3Rvck9yVGFyZ2V0OiBQaHhUYXJnZXQsXG4gICAgZXZlbnQ6IHN0cmluZyxcbiAgICBwYXlsb2FkPzogb2JqZWN0LFxuICApOiBQcm9taXNlPFByb21pc2VTZXR0bGVkUmVzdWx0PHsgcmVwbHk6IGFueTsgcmVmOiBudW1iZXIgfT5bXT47XG5cbiAgLyoqXG4gICAqIEFsbG93cyB0byByZWdpc3RlciBhIGNhbGxiYWNrIHRvIGJlIGNhbGxlZCB3aGVuIGFuIGV2ZW50IGlzIHJlY2VpdmVkIGZyb20gdGhlIHNlcnZlci5cbiAgICpcbiAgICogVGhpcyBpcyB1c2VkIHRvIGhhbmRsZSBgcHVzaEV2ZW50YCBjYWxscyBmcm9tIHRoZSBzZXJ2ZXIuIFRoZSBjYWxsYmFjayBpcyBjYWxsZWQgd2l0aCB0aGUgcGF5bG9hZCBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAqXG4gICAqIEBwYXJhbSBldmVudCAtIFRoZSBldmVudCBuYW1lLlxuICAgKiBAcGFyYW0gY2FsbGJhY2sgLSBUaGUgY2FsbGJhY2sgdG8gY2FsbCB3aGVuIHRoZSBldmVudCBpcyByZWNlaXZlZC5cbiAgICpcbiAgICogQHJldHVybnMgQSByZWZlcmVuY2UgdG8gdGhlIGNhbGxiYWNrLCB3aGljaCBjYW4gYmUgdXNlZCBpbiBgcmVtb3ZlSGFuZGxlRXZlbnRgIHRvIHJlbW92ZSB0aGUgY2FsbGJhY2suXG4gICAqL1xuICBoYW5kbGVFdmVudChldmVudDogc3RyaW5nLCBjYWxsYmFjazogKHBheWxvYWQ6IGFueSkgPT4gYW55KTogQ2FsbGJhY2tSZWY7XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYSBjYWxsYmFjayByZWdpc3RlcmVkIHdpdGggYGhhbmRsZUV2ZW50YC5cbiAgICpcbiAgICogQHBhcmFtIGNhbGxiYWNrUmVmIC0gVGhlIHJlZmVyZW5jZSB0byB0aGUgY2FsbGJhY2sgdG8gcmVtb3ZlLlxuICAgKi9cbiAgcmVtb3ZlSGFuZGxlRXZlbnQocmVmOiBDYWxsYmFja1JlZik6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIEFsbG93cyB0byB0cmlnZ2VyIGEgbGl2ZSBmaWxlIHVwbG9hZC5cbiAgICpcbiAgICogQHBhcmFtIG5hbWUgLSBUaGUgdXBsb2FkIG5hbWUgY29ycmVzcG9uZGluZyB0byB0aGUgYFBob2VuaXguTGl2ZVZpZXcuYWxsb3dfdXBsb2FkLzNgIGNhbGwuXG4gICAqIEBwYXJhbSBmaWxlcyAtIFRoZSBmaWxlcyB0byB1cGxvYWQuXG4gICAqL1xuICB1cGxvYWQobmFtZTogYW55LCBmaWxlczogYW55KTogYW55O1xuXG4gIC8qKlxuICAgKiBBbGxvd3MgdG8gdHJpZ2dlciBhIGxpdmUgZmlsZSB1cGxvYWQgdG8gYSBzcGVjaWZpYyB0YXJnZXQuXG4gICAqXG4gICAqIEBwYXJhbSBzZWxlY3Rvck9yVGFyZ2V0IC0gVGhlIHRhcmdldCB0byB1cGxvYWQgdGhlIGZpbGVzIHRvLlxuICAgKiBAcGFyYW0gbmFtZSAtIFRoZSB1cGxvYWQgbmFtZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBgUGhvZW5peC5MaXZlVmlldy5hbGxvd191cGxvYWQvM2AgY2FsbC5cbiAgICogQHBhcmFtIGZpbGVzIC0gVGhlIGZpbGVzIHRvIHVwbG9hZC5cbiAgICovXG4gIHVwbG9hZFRvKHNlbGVjdG9yT3JUYXJnZXQ6IFBoeFRhcmdldCwgbmFtZTogYW55LCBmaWxlczogYW55KTogYW55O1xuXG4gIC8vIGFsbG93IHVua25vd24gbWV0aG9kcywgYXMgcGVvcGxlIGNhbiBkZWZpbmUgdGhlbSBpbiB0aGVpciBob29rc1xuICBba2V5OiBQcm9wZXJ0eUtleV06IGFueTtcbn1cblxuLy8gYmFzZWQgb24gaHR0cHM6Ly9naXRodWIuY29tL0RlZmluaXRlbHlUeXBlZC9EZWZpbml0ZWx5VHlwZWQvYmxvYi9mYWMxYWE3NWFjZGRkYmY0ZjFhOTVlOThlZTIyOTdiNTRjZTRiNGM5L3R5cGVzL3Bob2VuaXhfbGl2ZV92aWV3L2hvb2tzLmQudHMjTDI2XG4vLyBsaWNlbnNlZCB1bmRlciBNSVRcbmV4cG9ydCBpbnRlcmZhY2UgSG9vazxvdXQgVCA9IG9iamVjdCwgRSBleHRlbmRzIEhUTUxFbGVtZW50ID0gSFRNTEVsZW1lbnQ+IHtcbiAgLyoqXG4gICAqIFRoZSBtb3VudGVkIGNhbGxiYWNrLlxuICAgKlxuICAgKiBDYWxsZWQgd2hlbiB0aGUgZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byB0aGUgRE9NIGFuZCBpdHMgc2VydmVyIExpdmVWaWV3IGhhcyBmaW5pc2hlZCBtb3VudGluZy5cbiAgICovXG4gIG1vdW50ZWQ/OiAodGhpczogVCAmIEhvb2tJbnRlcmZhY2U8RT4pID0+IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFRoZSBiZWZvcmVVcGRhdGUgY2FsbGJhY2suXG4gICAqXG4gICAqIENhbGxlZCB3aGVuIHRoZSBlbGVtZW50IGlzIGFib3V0IHRvIGJlIHVwZGF0ZWQgaW4gdGhlIERPTS5cbiAgICogTm90ZTogYW55IGNhbGwgaGVyZSBtdXN0IGJlIHN5bmNocm9ub3VzIGFzIHRoZSBvcGVyYXRpb24gY2Fubm90IGJlIGRlZmVycmVkIG9yIGNhbmNlbGxlZC5cbiAgICovXG4gIGJlZm9yZVVwZGF0ZT86ICh0aGlzOiBUICYgSG9va0ludGVyZmFjZTxFPikgPT4gdm9pZDtcblxuICAvKipcbiAgICogVGhlIHVwZGF0ZWQgY2FsbGJhY2suXG4gICAqXG4gICAqIENhbGxlZCB3aGVuIHRoZSBlbGVtZW50IGhhcyBiZWVuIHVwZGF0ZWQgaW4gdGhlIERPTSBieSB0aGUgc2VydmVyXG4gICAqL1xuICB1cGRhdGVkPzogKHRoaXM6IFQgJiBIb29rSW50ZXJmYWNlPEU+KSA9PiB2b2lkO1xuXG4gIC8qKlxuICAgKiBUaGUgZGVzdHJveWVkIGNhbGxiYWNrLlxuICAgKlxuICAgKiBDYWxsZWQgd2hlbiB0aGUgZWxlbWVudCBoYXMgYmVlbiByZW1vdmVkIGZyb20gdGhlIHBhZ2UsIGVpdGhlciBieSBhIHBhcmVudCB1cGRhdGUsIG9yIGJ5IHRoZSBwYXJlbnQgYmVpbmcgcmVtb3ZlZCBlbnRpcmVseVxuICAgKi9cbiAgZGVzdHJveWVkPzogKHRoaXM6IFQgJiBIb29rSW50ZXJmYWNlPEU+KSA9PiB2b2lkO1xuXG4gIC8qKlxuICAgKiBUaGUgZGlzY29ubmVjdGVkIGNhbGxiYWNrLlxuICAgKlxuICAgKiBDYWxsZWQgd2hlbiB0aGUgZWxlbWVudCdzIHBhcmVudCBMaXZlVmlldyBoYXMgZGlzY29ubmVjdGVkIGZyb20gdGhlIHNlcnZlci5cbiAgICovXG4gIGRpc2Nvbm5lY3RlZD86ICh0aGlzOiBUICYgSG9va0ludGVyZmFjZTxFPikgPT4gdm9pZDtcblxuICAvKipcbiAgICogVGhlIHJlY29ubmVjdGVkIGNhbGxiYWNrLlxuICAgKlxuICAgKiBDYWxsZWQgd2hlbiB0aGUgZWxlbWVudCdzIHBhcmVudCBMaXZlVmlldyBoYXMgcmVjb25uZWN0ZWQgdG8gdGhlIHNlcnZlci5cbiAgICovXG4gIHJlY29ubmVjdGVkPzogKHRoaXM6IFQgJiBIb29rSW50ZXJmYWNlPEU+KSA9PiB2b2lkO1xuXG4gIC8vIEFsbG93IGN1c3RvbSBtZXRob2RzIHdpdGggYW55IHNpZ25hdHVyZSBhbmQgY3VzdG9tIHByb3BlcnRpZXNcbiAgW2tleTogUHJvcGVydHlLZXldOiBhbnk7XG59XG5cbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgTGl2ZVZpZXcgaG9va3MuIFVzZXJzIGV4dGVuZCB0aGlzIGNsYXNzIHRvIGRlZmluZSB0aGVpciBob29rcy5cbiAqXG4gKiBFeGFtcGxlOlxuICogYGBgdHlwZXNjcmlwdFxuICogY2xhc3MgTXlDdXN0b21Ib29rIGV4dGVuZHMgVmlld0hvb2sge1xuICogICBteVN0YXRlID0gXCJpbml0aWFsXCI7XG4gKlxuICogICBtb3VudGVkKCkge1xuICogICAgIGNvbnNvbGUubG9nKFwiSG9vayBtb3VudGVkIG9uIGVsZW1lbnQ6XCIsIHRoaXMuZWwpO1xuICogICAgIHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsICgpID0+IHtcbiAqICAgICAgIHRoaXMucHVzaEV2ZW50KFwiZWxlbWVudC1jbGlja2VkXCIsIHsgc3RhdGU6IHRoaXMubXlTdGF0ZSB9KTtcbiAqICAgICB9KTtcbiAqICAgfVxuICpcbiAqICAgdXBkYXRlZCgpIHtcbiAqICAgICBjb25zb2xlLmxvZyhcIkhvb2sgdXBkYXRlZFwiLCB0aGlzLmVsLmlkKTtcbiAqICAgfVxuICpcbiAqICAgbXlDdXN0b21NZXRob2Qoc29tZUFyZzogc3RyaW5nKSB7XG4gKiAgICAgY29uc29sZS5sb2coXCJteUN1c3RvbU1ldGhvZCBjYWxsZWQgd2l0aDpcIiwgc29tZUFyZywgXCJDdXJyZW50IHN0YXRlOlwiLCB0aGlzLm15U3RhdGUpO1xuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBUaGUgYHRoaXNgIGNvbnRleHQgd2l0aGluIHRoZSBob29rIG1ldGhvZHMgKG1vdW50ZWQsIHVwZGF0ZWQsIGN1c3RvbSBtZXRob2RzLCBldGMuKVxuICogd2lsbCByZWZlciB0byB0aGUgaG9vayBpbnN0YW5jZSwgcHJvdmlkaW5nIGFjY2VzcyB0byBgdGhpcy5lbGAsIGB0aGlzLmxpdmVTb2NrZXRgLFxuICogYHRoaXMucHVzaEV2ZW50KClgLCBldGMuLCBhcyB3ZWxsIGFzIGFueSBwcm9wZXJ0aWVzIG9yIG1ldGhvZHMgZGVmaW5lZCBvbiB0aGUgc3ViY2xhc3MuXG4gKi9cbmV4cG9ydCBjbGFzcyBWaWV3SG9vazxFIGV4dGVuZHMgSFRNTEVsZW1lbnQgPSBIVE1MRWxlbWVudD5cbiAgaW1wbGVtZW50cyBIb29rSW50ZXJmYWNlPEU+XG57XG4gIGVsOiBFO1xuICBsaXZlU29ja2V0OiBMaXZlU29ja2V0O1xuXG4gIHByaXZhdGUgX19saXN0ZW5lcnM6IFNldDxDYWxsYmFja1JlZj47XG4gIHByaXZhdGUgX19pc0Rpc2Nvbm5lY3RlZDogYm9vbGVhbjtcbiAgcHJpdmF0ZSBfX3ZpZXc6ICgpID0+IFZpZXc7XG5cbiAgc3RhdGljIG1ha2VJRCgpIHtcbiAgICByZXR1cm4gdmlld0hvb2tJRCsrO1xuICB9XG4gIHN0YXRpYyBlbGVtZW50SUQoZWw6IEhUTUxFbGVtZW50KSB7XG4gICAgcmV0dXJuIERPTS5wcml2YXRlKGVsLCBIT09LX0lEKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHZpZXc6IFZpZXcgfCBudWxsLCBlbDogRSwgY2FsbGJhY2tzPzogSG9vaykge1xuICAgIHRoaXMuZWwgPSBlbDtcbiAgICB0aGlzLl9fYXR0YWNoVmlldyh2aWV3KTtcbiAgICB0aGlzLl9fbGlzdGVuZXJzID0gbmV3IFNldCgpO1xuICAgIHRoaXMuX19pc0Rpc2Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgIERPTS5wdXRQcml2YXRlKHRoaXMuZWwsIEhPT0tfSUQsIFZpZXdIb29rLm1ha2VJRCgpKTtcblxuICAgIGlmIChjYWxsYmFja3MpIHtcbiAgICAgIC8vIFRoaXMgaW5zdGFuY2UgaXMgZm9yIGFuIG9iamVjdC1saXRlcmFsIGhvb2suIENvcHkgbWV0aG9kcy9wcm9wZXJ0aWVzLlxuICAgICAgLy8gVGhlc2UgYXJlIHByb3BlcnRpZXMgdGhhdCBzaG91bGQgTk9UIGJlIG92ZXJyaWRkZW4gYnkgdGhlIGNhbGxiYWNrcyBvYmplY3QuXG4gICAgICBjb25zdCBwcm90ZWN0ZWRQcm9wcyA9IG5ldyBTZXQoW1xuICAgICAgICBcImVsXCIsXG4gICAgICAgIFwibGl2ZVNvY2tldFwiLFxuICAgICAgICBcIl9fdmlld1wiLFxuICAgICAgICBcIl9fbGlzdGVuZXJzXCIsXG4gICAgICAgIFwiX19pc0Rpc2Nvbm5lY3RlZFwiLFxuICAgICAgICBcImNvbnN0cnVjdG9yXCIsIC8vIFN0YW5kYXJkIG9iamVjdCBwcm9wZXJ0aWVzXG4gICAgICAgIC8vIENvcmUgVmlld0hvb2sgQVBJIG1ldGhvZHNcbiAgICAgICAgXCJqc1wiLFxuICAgICAgICBcInB1c2hFdmVudFwiLFxuICAgICAgICBcInB1c2hFdmVudFRvXCIsXG4gICAgICAgIFwiaGFuZGxlRXZlbnRcIixcbiAgICAgICAgXCJyZW1vdmVIYW5kbGVFdmVudFwiLFxuICAgICAgICBcInVwbG9hZFwiLFxuICAgICAgICBcInVwbG9hZFRvXCIsXG4gICAgICAgIC8vIEludGVybmFsIGxpZmVjeWNsZSBjYWxsZXJzXG4gICAgICAgIFwiX19tb3VudGVkXCIsXG4gICAgICAgIFwiX191cGRhdGVkXCIsXG4gICAgICAgIFwiX19iZWZvcmVVcGRhdGVcIixcbiAgICAgICAgXCJfX2Rlc3Ryb3llZFwiLFxuICAgICAgICBcIl9fcmVjb25uZWN0ZWRcIixcbiAgICAgICAgXCJfX2Rpc2Nvbm5lY3RlZFwiLFxuICAgICAgICBcIl9fY2xlYW51cF9fXCIsXG4gICAgICBdKTtcblxuICAgICAgZm9yIChjb25zdCBrZXkgaW4gY2FsbGJhY2tzKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoY2FsbGJhY2tzLCBrZXkpKSB7XG4gICAgICAgICAgKHRoaXMgYXMgYW55KVtrZXldID0gY2FsbGJhY2tzW2tleV07XG4gICAgICAgICAgLy8gZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LCB3ZSBhbGxvdyB0aGUgb3ZlcndyaXRlLCBidXQgd2UgbG9nIGEgd2FybmluZ1xuICAgICAgICAgIGlmIChwcm90ZWN0ZWRQcm9wcy5oYXMoa2V5KSkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICBgSG9vayBvYmplY3QgZm9yIGVsZW1lbnQgIyR7ZWwuaWR9IG92ZXJ3cml0ZXMgY29yZSBwcm9wZXJ0eSAnJHtrZXl9JyFgLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgbGlmZWN5Y2xlTWV0aG9kczogKGtleW9mIEhvb2spW10gPSBbXG4gICAgICAgIFwibW91bnRlZFwiLFxuICAgICAgICBcImJlZm9yZVVwZGF0ZVwiLFxuICAgICAgICBcInVwZGF0ZWRcIixcbiAgICAgICAgXCJkZXN0cm95ZWRcIixcbiAgICAgICAgXCJkaXNjb25uZWN0ZWRcIixcbiAgICAgICAgXCJyZWNvbm5lY3RlZFwiLFxuICAgICAgXTtcbiAgICAgIGxpZmVjeWNsZU1ldGhvZHMuZm9yRWFjaCgobWV0aG9kTmFtZSkgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgY2FsbGJhY2tzW21ldGhvZE5hbWVdICYmXG4gICAgICAgICAgdHlwZW9mIGNhbGxiYWNrc1ttZXRob2ROYW1lXSA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICkge1xuICAgICAgICAgICh0aGlzIGFzIGFueSlbbWV0aG9kTmFtZV0gPSBjYWxsYmFja3NbbWV0aG9kTmFtZV07XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICAvLyBJZiAnY2FsbGJhY2tzJyBpcyBub3QgcHJvdmlkZWQsIHRoaXMgaXMgYW4gaW5zdGFuY2Ugb2YgYSB1c2VyLWRlZmluZWQgY2xhc3MgKGUuZy4sIE15SG9vaykuXG4gICAgLy8gSXRzIG1ldGhvZHMgKG1vdW50ZWQsIHVwZGF0ZWQsIGN1c3RvbSkgYXJlIGFscmVhZHkgcGFydCBvZiBpdHMgcHJvdG90eXBlIG9yIGluc3RhbmNlLFxuICAgIC8vIGFuZCB3aWxsIGNvcnJlY3RseSBvdmVycmlkZSB0aGUgZGVmYXVsdHMgZnJvbSBWaWV3SG9vay5wcm90b3R5cGUuXG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIF9fYXR0YWNoVmlldyh2aWV3OiBWaWV3IHwgbnVsbCkge1xuICAgIGlmICh2aWV3KSB7XG4gICAgICB0aGlzLl9fdmlldyA9ICgpID0+IHZpZXc7XG4gICAgICB0aGlzLmxpdmVTb2NrZXQgPSB2aWV3LmxpdmVTb2NrZXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX192aWV3ID0gKCkgPT4ge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYGhvb2sgbm90IHlldCBhdHRhY2hlZCB0byBhIGxpdmUgdmlldzogJHt0aGlzLmVsLm91dGVySFRNTH1gLFxuICAgICAgICApO1xuICAgICAgfTtcbiAgICAgIHRoaXMubGl2ZVNvY2tldCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgLy8gRGVmYXVsdCBsaWZlY3ljbGUgbWV0aG9kc1xuICBtb3VudGVkKCk6IHZvaWQge31cbiAgYmVmb3JlVXBkYXRlKCk6IHZvaWQge31cbiAgdXBkYXRlZCgpOiB2b2lkIHt9XG4gIGRlc3Ryb3llZCgpOiB2b2lkIHt9XG4gIGRpc2Nvbm5lY3RlZCgpOiB2b2lkIHt9XG4gIHJlY29ubmVjdGVkKCk6IHZvaWQge31cblxuICAvLyBJbnRlcm5hbCBsaWZlY3ljbGUgY2FsbGVycyAtIGNhbGxlZCBieSB0aGUgVmlld1xuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX19tb3VudGVkKCkge1xuICAgIHRoaXMubW91bnRlZCgpO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX191cGRhdGVkKCkge1xuICAgIHRoaXMudXBkYXRlZCgpO1xuICB9XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX19iZWZvcmVVcGRhdGUoKSB7XG4gICAgdGhpcy5iZWZvcmVVcGRhdGUoKTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIF9fZGVzdHJveWVkKCkge1xuICAgIHRoaXMuZGVzdHJveWVkKCk7XG4gICAgRE9NLmRlbGV0ZVByaXZhdGUodGhpcy5lbCwgSE9PS19JRCk7IC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9waG9lbml4ZnJhbWV3b3JrL3Bob2VuaXhfbGl2ZV92aWV3L2lzc3Vlcy8zNDk2XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfX3JlY29ubmVjdGVkKCkge1xuICAgIGlmICh0aGlzLl9faXNEaXNjb25uZWN0ZWQpIHtcbiAgICAgIHRoaXMuX19pc0Rpc2Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5yZWNvbm5lY3RlZCgpO1xuICAgIH1cbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIF9fZGlzY29ubmVjdGVkKCkge1xuICAgIHRoaXMuX19pc0Rpc2Nvbm5lY3RlZCA9IHRydWU7XG4gICAgdGhpcy5kaXNjb25uZWN0ZWQoKTtcbiAgfVxuXG4gIGpzKCk6IEhvb2tKU0NvbW1hbmRzIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uanNDb21tYW5kcyh0aGlzLl9fdmlldygpLmxpdmVTb2NrZXQsIFwiaG9va1wiKSxcbiAgICAgIGV4ZWM6IChlbmNvZGVkSlM6IHN0cmluZykgPT4ge1xuICAgICAgICB0aGlzLl9fdmlldygpLmxpdmVTb2NrZXQuZXhlY0pTKHRoaXMuZWwsIGVuY29kZWRKUywgXCJob29rXCIpO1xuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgcHVzaEV2ZW50KGV2ZW50OiBzdHJpbmcsIHBheWxvYWQ/OiBhbnksIG9uUmVwbHk/OiBPblJlcGx5KSB7XG4gICAgY29uc3QgcHJvbWlzZSA9IHRoaXMuX192aWV3KCkucHVzaEhvb2tFdmVudChcbiAgICAgIHRoaXMuZWwsXG4gICAgICBudWxsLFxuICAgICAgZXZlbnQsXG4gICAgICBwYXlsb2FkIHx8IHt9LFxuICAgICk7XG4gICAgaWYgKG9uUmVwbHkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHByb21pc2UudGhlbigoeyByZXBseSB9KSA9PiByZXBseSk7XG4gICAgfVxuICAgIHByb21pc2UudGhlbigoeyByZXBseSwgcmVmIH0pID0+IG9uUmVwbHkocmVwbHksIHJlZikpLmNhdGNoKCgpID0+IHt9KTtcbiAgICByZXR1cm47XG4gIH1cblxuICBwdXNoRXZlbnRUbyhcbiAgICBzZWxlY3Rvck9yVGFyZ2V0OiBQaHhUYXJnZXQsXG4gICAgZXZlbnQ6IHN0cmluZyxcbiAgICBwYXlsb2FkPzogb2JqZWN0LFxuICAgIG9uUmVwbHk/OiBPblJlcGx5LFxuICApIHtcbiAgICBpZiAob25SZXBseSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCB0YXJnZXRQYWlyOiB7IHZpZXc6IFZpZXc7IHRhcmdldEN0eDogYW55IH1bXSA9IFtdO1xuICAgICAgdGhpcy5fX3ZpZXcoKS53aXRoaW5UYXJnZXRzKHNlbGVjdG9yT3JUYXJnZXQsICh2aWV3LCB0YXJnZXRDdHgpID0+IHtcbiAgICAgICAgdGFyZ2V0UGFpci5wdXNoKHsgdmlldywgdGFyZ2V0Q3R4IH0pO1xuICAgICAgfSk7XG4gICAgICBjb25zdCBwcm9taXNlcyA9IHRhcmdldFBhaXIubWFwKCh7IHZpZXcsIHRhcmdldEN0eCB9KSA9PiB7XG4gICAgICAgIHJldHVybiB2aWV3LnB1c2hIb29rRXZlbnQodGhpcy5lbCwgdGFyZ2V0Q3R4LCBldmVudCwgcGF5bG9hZCB8fCB7fSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBQcm9taXNlLmFsbFNldHRsZWQocHJvbWlzZXMpO1xuICAgIH1cbiAgICB0aGlzLl9fdmlldygpLndpdGhpblRhcmdldHMoc2VsZWN0b3JPclRhcmdldCwgKHZpZXcsIHRhcmdldEN0eCkgPT4ge1xuICAgICAgdmlld1xuICAgICAgICAucHVzaEhvb2tFdmVudCh0aGlzLmVsLCB0YXJnZXRDdHgsIGV2ZW50LCBwYXlsb2FkIHx8IHt9KVxuICAgICAgICAudGhlbigoeyByZXBseSwgcmVmIH0pID0+IG9uUmVwbHkocmVwbHksIHJlZikpXG4gICAgICAgIC5jYXRjaCgoKSA9PiB7fSk7XG4gICAgfSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaGFuZGxlRXZlbnQoZXZlbnQ6IHN0cmluZywgY2FsbGJhY2s6IChwYXlsb2FkOiBhbnkpID0+IGFueSk6IENhbGxiYWNrUmVmIHtcbiAgICBjb25zdCBjYWxsYmFja1JlZjogQ2FsbGJhY2tSZWYgPSB7XG4gICAgICBldmVudCxcbiAgICAgIGNhbGxiYWNrOiAoY3VzdG9tRXZlbnQ6IEN1c3RvbUV2ZW50KSA9PiBjYWxsYmFjayhjdXN0b21FdmVudC5kZXRhaWwpLFxuICAgIH07XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBgcGh4OiR7ZXZlbnR9YCxcbiAgICAgIGNhbGxiYWNrUmVmLmNhbGxiYWNrIGFzIEV2ZW50TGlzdGVuZXIsXG4gICAgKTtcbiAgICB0aGlzLl9fbGlzdGVuZXJzLmFkZChjYWxsYmFja1JlZik7XG4gICAgcmV0dXJuIGNhbGxiYWNrUmVmO1xuICB9XG5cbiAgcmVtb3ZlSGFuZGxlRXZlbnQocmVmOiBDYWxsYmFja1JlZik6IHZvaWQge1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgYHBoeDoke3JlZi5ldmVudH1gLFxuICAgICAgcmVmLmNhbGxiYWNrIGFzIEV2ZW50TGlzdGVuZXIsXG4gICAgKTtcbiAgICB0aGlzLl9fbGlzdGVuZXJzLmRlbGV0ZShyZWYpO1xuICB9XG5cbiAgdXBsb2FkKG5hbWU6IHN0cmluZywgZmlsZXM6IEZpbGVMaXN0KTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5fX3ZpZXcoKS5kaXNwYXRjaFVwbG9hZHMobnVsbCwgbmFtZSwgZmlsZXMpO1xuICB9XG5cbiAgdXBsb2FkVG8oc2VsZWN0b3JPclRhcmdldDogUGh4VGFyZ2V0LCBuYW1lOiBzdHJpbmcsIGZpbGVzOiBGaWxlTGlzdCk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMuX192aWV3KCkud2l0aGluVGFyZ2V0cyhzZWxlY3Rvck9yVGFyZ2V0LCAodmlldywgdGFyZ2V0Q3R4KSA9PiB7XG4gICAgICB2aWV3LmRpc3BhdGNoVXBsb2Fkcyh0YXJnZXRDdHgsIG5hbWUsIGZpbGVzKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX19jbGVhbnVwX18oKSB7XG4gICAgdGhpcy5fX2xpc3RlbmVycy5mb3JFYWNoKChjYWxsYmFja1JlZikgPT5cbiAgICAgIHRoaXMucmVtb3ZlSGFuZGxlRXZlbnQoY2FsbGJhY2tSZWYpLFxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgSG9va3NPcHRpb25zID0gUmVjb3JkPHN0cmluZywgdHlwZW9mIFZpZXdIb29rIHwgSG9vaz47XG5cbmV4cG9ydCBkZWZhdWx0IFZpZXdIb29rO1xuIiwgImltcG9ydCB7XG4gIEJFRk9SRV9VTkxPQURfTE9BREVSX1RJTUVPVVQsXG4gIENIRUNLQUJMRV9JTlBVVFMsXG4gIENPTlNFQ1VUSVZFX1JFTE9BRFMsXG4gIFBIWF9BVVRPX1JFQ09WRVIsXG4gIFBIWF9DT01QT05FTlQsXG4gIFBIWF9WSUVXX1JFRixcbiAgUEhYX0NPTk5FQ1RFRF9DTEFTUyxcbiAgUEhYX0RJU0FCTEVfV0lUSCxcbiAgUEhYX0RJU0FCTEVfV0lUSF9SRVNUT1JFLFxuICBQSFhfRElTQUJMRUQsXG4gIFBIWF9MT0FESU5HX0NMQVNTLFxuICBQSFhfRVJST1JfQ0xBU1MsXG4gIFBIWF9DTElFTlRfRVJST1JfQ0xBU1MsXG4gIFBIWF9TRVJWRVJfRVJST1JfQ0xBU1MsXG4gIFBIWF9IQVNfRk9DVVNFRCxcbiAgUEhYX0hBU19TVUJNSVRURUQsXG4gIFBIWF9IT09LLFxuICBQSFhfUEFSRU5UX0lELFxuICBQSFhfUFJPR1JFU1MsXG4gIFBIWF9SRUFET05MWSxcbiAgUEhYX1JFRl9MT0FESU5HLFxuICBQSFhfUkVGX1NSQyxcbiAgUEhYX1JFRl9MT0NLLFxuICBQSFhfUk9PVF9JRCxcbiAgUEhYX1NFU1NJT04sXG4gIFBIWF9TVEFUSUMsXG4gIFBIWF9TVElDS1ksXG4gIFBIWF9UUkFDS19TVEFUSUMsXG4gIFBIWF9UUkFDS19VUExPQURTLFxuICBQSFhfVVBEQVRFLFxuICBQSFhfVVBMT0FEX1JFRixcbiAgUEhYX1ZJRVdfU0VMRUNUT1IsXG4gIFBIWF9NQUlOLFxuICBQSFhfTU9VTlRFRCxcbiAgUFVTSF9USU1FT1VULFxuICBQSFhfVklFV1BPUlRfVE9QLFxuICBQSFhfVklFV1BPUlRfQk9UVE9NLFxuICBNQVhfQ0hJTERfSk9JTl9BVFRFTVBUUyxcbiAgUEhYX0xWX1BJRCxcbiAgUEhYX1BPUlRBTCxcbiAgUEhYX1RFTEVQT1JURURfUkVGLFxufSBmcm9tIFwiLi9jb25zdGFudHNcIjtcblxuaW1wb3J0IHtcbiAgY2xvbmUsXG4gIGNsb3Nlc3RQaHhCaW5kaW5nLFxuICBpc0VtcHR5LFxuICBpc0VxdWFsT2JqLFxuICBsb2dFcnJvcixcbiAgbWF5YmUsXG4gIGlzQ2lkLFxufSBmcm9tIFwiLi91dGlsc1wiO1xuXG5pbXBvcnQgQnJvd3NlciBmcm9tIFwiLi9icm93c2VyXCI7XG5pbXBvcnQgRE9NIGZyb20gXCIuL2RvbVwiO1xuaW1wb3J0IEVsZW1lbnRSZWYgZnJvbSBcIi4vZWxlbWVudF9yZWZcIjtcbmltcG9ydCBET01QYXRjaCBmcm9tIFwiLi9kb21fcGF0Y2hcIjtcbmltcG9ydCBMaXZlVXBsb2FkZXIgZnJvbSBcIi4vbGl2ZV91cGxvYWRlclwiO1xuaW1wb3J0IFJlbmRlcmVkIGZyb20gXCIuL3JlbmRlcmVkXCI7XG5pbXBvcnQgeyBWaWV3SG9vayB9IGZyb20gXCIuL3ZpZXdfaG9va1wiO1xuaW1wb3J0IEpTIGZyb20gXCIuL2pzXCI7XG5cbmltcG9ydCBtb3JwaGRvbSBmcm9tIFwibW9ycGhkb21cIjtcblxuZXhwb3J0IGNvbnN0IHByZXBlbmRGb3JtRGF0YUtleSA9IChrZXksIHByZWZpeCkgPT4ge1xuICBjb25zdCBpc0FycmF5ID0ga2V5LmVuZHNXaXRoKFwiW11cIik7XG4gIC8vIFJlbW92ZSB0aGUgXCJbXVwiIGlmIGl0J3MgYW4gYXJyYXlcbiAgbGV0IGJhc2VLZXkgPSBpc0FycmF5ID8ga2V5LnNsaWNlKDAsIC0yKSA6IGtleTtcbiAgLy8gUmVwbGFjZSBsYXN0IG9jY3VycmVuY2Ugb2Yga2V5IGJlZm9yZSBhIGNsb3NpbmcgYnJhY2tldCBvciB0aGUgZW5kIHdpdGgga2V5IHBsdXMgc3VmZml4XG4gIGJhc2VLZXkgPSBiYXNlS2V5LnJlcGxhY2UoLyhbXlxcW1xcXV0rKShcXF0/JCkvLCBgJHtwcmVmaXh9JDEkMmApO1xuICAvLyBBZGQgYmFjayB0aGUgXCJbXVwiIGlmIGl0IHdhcyBhbiBhcnJheVxuICBpZiAoaXNBcnJheSkge1xuICAgIGJhc2VLZXkgKz0gXCJbXVwiO1xuICB9XG4gIHJldHVybiBiYXNlS2V5O1xufTtcblxuY29uc3Qgc2VyaWFsaXplRm9ybSA9IChmb3JtLCBvcHRzLCBvbmx5TmFtZXMgPSBbXSkgPT4ge1xuICBjb25zdCB7IHN1Ym1pdHRlciB9ID0gb3B0cztcblxuICAvLyBXZSBtdXN0IGluamVjdCB0aGUgc3VibWl0dGVyIGluIHRoZSBvcmRlciB0aGF0IGl0IGV4aXN0cyBpbiB0aGUgRE9NXG4gIC8vIHJlbGF0aXZlIHRvIG90aGVyIGlucHV0cy4gRm9yIGV4YW1wbGUsIGZvciBjaGVja2JveCBncm91cHMsIHRoZSBvcmRlciBtdXN0IGJlIG1haW50YWluZWQuXG4gIGxldCBpbmplY3RlZEVsZW1lbnQ7XG4gIGlmIChzdWJtaXR0ZXIgJiYgc3VibWl0dGVyLm5hbWUpIHtcbiAgICBjb25zdCBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbnB1dFwiKTtcbiAgICBpbnB1dC50eXBlID0gXCJoaWRkZW5cIjtcbiAgICAvLyBzZXQgdGhlIGZvcm0gYXR0cmlidXRlIGlmIHRoZSBzdWJtaXR0ZXIgaGFzIG9uZTtcbiAgICAvLyB0aGlzIGNhbiBoYXBwZW4gaWYgdGhlIGVsZW1lbnQgaXMgb3V0c2lkZSB0aGUgYWN0dWFsIGZvcm0gZWxlbWVudFxuICAgIGNvbnN0IGZvcm1JZCA9IHN1Ym1pdHRlci5nZXRBdHRyaWJ1dGUoXCJmb3JtXCIpO1xuICAgIGlmIChmb3JtSWQpIHtcbiAgICAgIGlucHV0LnNldEF0dHJpYnV0ZShcImZvcm1cIiwgZm9ybUlkKTtcbiAgICB9XG4gICAgaW5wdXQubmFtZSA9IHN1Ym1pdHRlci5uYW1lO1xuICAgIGlucHV0LnZhbHVlID0gc3VibWl0dGVyLnZhbHVlO1xuICAgIHN1Ym1pdHRlci5wYXJlbnRFbGVtZW50Lmluc2VydEJlZm9yZShpbnB1dCwgc3VibWl0dGVyKTtcbiAgICBpbmplY3RlZEVsZW1lbnQgPSBpbnB1dDtcbiAgfVxuXG4gIGNvbnN0IGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKGZvcm0pO1xuICBjb25zdCB0b1JlbW92ZSA9IFtdO1xuXG4gIGZvcm1EYXRhLmZvckVhY2goKHZhbCwga2V5LCBfaW5kZXgpID0+IHtcbiAgICBpZiAodmFsIGluc3RhbmNlb2YgRmlsZSkge1xuICAgICAgdG9SZW1vdmUucHVzaChrZXkpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gQ2xlYW51cCBhZnRlciBidWlsZGluZyBmaWxlRGF0YVxuICB0b1JlbW92ZS5mb3JFYWNoKChrZXkpID0+IGZvcm1EYXRhLmRlbGV0ZShrZXkpKTtcblxuICBjb25zdCBwYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKCk7XG5cbiAgY29uc3QgeyBpbnB1dHNVbnVzZWQsIG9ubHlIaWRkZW5JbnB1dHMgfSA9IEFycmF5LmZyb20oZm9ybS5lbGVtZW50cykucmVkdWNlKFxuICAgIChhY2MsIGlucHV0KSA9PiB7XG4gICAgICBjb25zdCB7IGlucHV0c1VudXNlZCwgb25seUhpZGRlbklucHV0cyB9ID0gYWNjO1xuICAgICAgY29uc3Qga2V5ID0gaW5wdXQubmFtZTtcbiAgICAgIGlmICgha2V5KSB7XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbnB1dHNVbnVzZWRba2V5XSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlucHV0c1VudXNlZFtrZXldID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChvbmx5SGlkZGVuSW5wdXRzW2tleV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBvbmx5SGlkZGVuSW5wdXRzW2tleV0gPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBpc1VzZWQgPVxuICAgICAgICBET00ucHJpdmF0ZShpbnB1dCwgUEhYX0hBU19GT0NVU0VEKSB8fFxuICAgICAgICBET00ucHJpdmF0ZShpbnB1dCwgUEhYX0hBU19TVUJNSVRURUQpO1xuICAgICAgY29uc3QgaXNIaWRkZW4gPSBpbnB1dC50eXBlID09PSBcImhpZGRlblwiO1xuICAgICAgaW5wdXRzVW51c2VkW2tleV0gPSBpbnB1dHNVbnVzZWRba2V5XSAmJiAhaXNVc2VkO1xuICAgICAgb25seUhpZGRlbklucHV0c1trZXldID0gb25seUhpZGRlbklucHV0c1trZXldICYmIGlzSGlkZGVuO1xuXG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sXG4gICAgeyBpbnB1dHNVbnVzZWQ6IHt9LCBvbmx5SGlkZGVuSW5wdXRzOiB7fSB9LFxuICApO1xuXG4gIGZvciAoY29uc3QgW2tleSwgdmFsXSBvZiBmb3JtRGF0YS5lbnRyaWVzKCkpIHtcbiAgICBpZiAob25seU5hbWVzLmxlbmd0aCA9PT0gMCB8fCBvbmx5TmFtZXMuaW5kZXhPZihrZXkpID49IDApIHtcbiAgICAgIGNvbnN0IGlzVW51c2VkID0gaW5wdXRzVW51c2VkW2tleV07XG4gICAgICBjb25zdCBoaWRkZW4gPSBvbmx5SGlkZGVuSW5wdXRzW2tleV07XG4gICAgICBpZiAoaXNVbnVzZWQgJiYgIShzdWJtaXR0ZXIgJiYgc3VibWl0dGVyLm5hbWUgPT0ga2V5KSAmJiAhaGlkZGVuKSB7XG4gICAgICAgIHBhcmFtcy5hcHBlbmQocHJlcGVuZEZvcm1EYXRhS2V5KGtleSwgXCJfdW51c2VkX1wiKSwgXCJcIik7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHZhbCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICBwYXJhbXMuYXBwZW5kKGtleSwgdmFsKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyByZW1vdmUgdGhlIGluamVjdGVkIGVsZW1lbnQgYWdhaW5cbiAgLy8gKGl0IHdvdWxkIGJlIHJlbW92ZWQgYnkgdGhlIG5leHQgZG9tIHBhdGNoIGFueXdheSwgYnV0IHRoaXMgaXMgY2xlYW5lcilcbiAgaWYgKHN1Ym1pdHRlciAmJiBpbmplY3RlZEVsZW1lbnQpIHtcbiAgICBzdWJtaXR0ZXIucGFyZW50RWxlbWVudC5yZW1vdmVDaGlsZChpbmplY3RlZEVsZW1lbnQpO1xuICB9XG5cbiAgcmV0dXJuIHBhcmFtcy50b1N0cmluZygpO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVmlldyB7XG4gIHN0YXRpYyBjbG9zZXN0VmlldyhlbCkge1xuICAgIGNvbnN0IGxpdmVWaWV3RWwgPSBlbC5jbG9zZXN0KFBIWF9WSUVXX1NFTEVDVE9SKTtcbiAgICByZXR1cm4gbGl2ZVZpZXdFbCA/IERPTS5wcml2YXRlKGxpdmVWaWV3RWwsIFwidmlld1wiKSA6IG51bGw7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihlbCwgbGl2ZVNvY2tldCwgcGFyZW50VmlldywgZmxhc2gsIGxpdmVSZWZlcmVyKSB7XG4gICAgdGhpcy5pc0RlYWQgPSBmYWxzZTtcbiAgICB0aGlzLmxpdmVTb2NrZXQgPSBsaXZlU29ja2V0O1xuICAgIHRoaXMuZmxhc2ggPSBmbGFzaDtcbiAgICB0aGlzLnBhcmVudCA9IHBhcmVudFZpZXc7XG4gICAgdGhpcy5yb290ID0gcGFyZW50VmlldyA/IHBhcmVudFZpZXcucm9vdCA6IHRoaXM7XG4gICAgdGhpcy5lbCA9IGVsO1xuICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vcGhvZW5peGZyYW1ld29yay9waG9lbml4X2xpdmVfdmlldy9wdWxsLzM3MjFcbiAgICAvLyBjaGVjayBpZiB0aGUgZWxlbWVudCBpcyBhbHJlYWR5IGJvdW5kIHRvIGEgdmlld1xuICAgIGNvbnN0IGJvdW5kVmlldyA9IERPTS5wcml2YXRlKHRoaXMuZWwsIFwidmlld1wiKTtcbiAgICBpZiAoYm91bmRWaWV3ICE9PSB1bmRlZmluZWQgJiYgYm91bmRWaWV3LmlzRGVhZCAhPT0gdHJ1ZSkge1xuICAgICAgbG9nRXJyb3IoXG4gICAgICAgIGBUaGUgRE9NIGVsZW1lbnQgZm9yIHRoaXMgdmlldyBoYXMgYWxyZWFkeSBiZWVuIGJvdW5kIHRvIGEgdmlldy5cblxuICAgICAgICBBbiBlbGVtZW50IGNhbiBvbmx5IGV2ZXIgYmUgYXNzb2NpYXRlZCB3aXRoIGEgc2luZ2xlIHZpZXchXG4gICAgICAgIFBsZWFzZSBlbnN1cmUgdGhhdCB5b3UgYXJlIG5vdCB0cnlpbmcgdG8gaW5pdGlhbGl6ZSBtdWx0aXBsZSBMaXZlU29ja2V0cyBvbiB0aGUgc2FtZSBwYWdlLlxuICAgICAgICBUaGlzIGNvdWxkIGhhcHBlbiBpZiB5b3UncmUgYWNjaWRlbnRhbGx5IHRyeWluZyB0byByZW5kZXIgeW91ciByb290IGxheW91dCBtb3JlIHRoYW4gb25jZS5cbiAgICAgICAgRW5zdXJlIHRoYXQgdGhlIHRlbXBsYXRlIHNldCBvbiB0aGUgTGl2ZVZpZXcgaXMgZGlmZmVyZW50IHRoYW4gdGhlIHJvb3QgbGF5b3V0LlxuICAgICAgYCxcbiAgICAgICAgeyB2aWV3OiBib3VuZFZpZXcgfSxcbiAgICAgICk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgYmluZCBtdWx0aXBsZSB2aWV3cyB0byB0aGUgc2FtZSBET00gZWxlbWVudC5cIik7XG4gICAgfVxuICAgIC8vIGJpbmQgdGhlIHZpZXcgdG8gdGhlIGVsZW1lbnRcbiAgICBET00ucHV0UHJpdmF0ZSh0aGlzLmVsLCBcInZpZXdcIiwgdGhpcyk7XG4gICAgdGhpcy5pZCA9IHRoaXMuZWwuaWQ7XG4gICAgdGhpcy5yZWYgPSAwO1xuICAgIHRoaXMubGFzdEFja1JlZiA9IG51bGw7XG4gICAgdGhpcy5jaGlsZEpvaW5zID0gMDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7UmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCBudWxsfVxuICAgICAqL1xuICAgIHRoaXMubG9hZGVyVGltZXIgPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IG51bGx9XG4gICAgICovXG4gICAgdGhpcy5kaXNjb25uZWN0ZWRUaW1lciA9IG51bGw7XG4gICAgdGhpcy5wZW5kaW5nRGlmZnMgPSBbXTtcbiAgICB0aGlzLnBlbmRpbmdGb3JtcyA9IG5ldyBTZXQoKTtcbiAgICB0aGlzLnJlZGlyZWN0ID0gZmFsc2U7XG4gICAgdGhpcy5ocmVmID0gbnVsbDtcbiAgICB0aGlzLmpvaW5Db3VudCA9IHRoaXMucGFyZW50ID8gdGhpcy5wYXJlbnQuam9pbkNvdW50IC0gMSA6IDA7XG4gICAgdGhpcy5qb2luQXR0ZW1wdHMgPSAwO1xuICAgIHRoaXMuam9pblBlbmRpbmcgPSB0cnVlO1xuICAgIHRoaXMuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgdGhpcy5qb2luQ2FsbGJhY2sgPSBmdW5jdGlvbiAob25Eb25lKSB7XG4gICAgICBvbkRvbmUgJiYgb25Eb25lKCk7XG4gICAgfTtcbiAgICB0aGlzLnN0b3BDYWxsYmFjayA9IGZ1bmN0aW9uICgpIHt9O1xuICAgIC8vIHVzdWFsbHksIG9ubHkgdGhlIHJvb3QgTGl2ZVZpZXcgc3RvcmVzIHBlbmRpbmdcbiAgICAvLyBqb2luIG9wZXJhdGlvbnMgZm9yIGFsbCBjaGlsZHJlbiAoYW5kIGl0c2VsZiksXG4gICAgLy8gYnV0IGluIGNhc2Ugb2YgcmVqb2lucyAoam9pbkNvdW50ID4gMSkgZWFjaCBjaGlsZFxuICAgIC8vIHN0b3JlcyBpdHMgb3duIGV2ZW50cyBpbnN0ZWFkXG4gICAgdGhpcy5wZW5kaW5nSm9pbk9wcyA9IFtdO1xuICAgIHRoaXMudmlld0hvb2tzID0ge307XG4gICAgdGhpcy5mb3JtU3VibWl0cyA9IFtdO1xuICAgIHRoaXMuY2hpbGRyZW4gPSB0aGlzLnBhcmVudCA/IG51bGwgOiB7fTtcbiAgICB0aGlzLnJvb3QuY2hpbGRyZW5bdGhpcy5pZF0gPSB7fTtcbiAgICB0aGlzLmZvcm1zRm9yUmVjb3ZlcnkgPSB7fTtcbiAgICB0aGlzLmNoYW5uZWwgPSB0aGlzLmxpdmVTb2NrZXQuY2hhbm5lbChgbHY6JHt0aGlzLmlkfWAsICgpID0+IHtcbiAgICAgIGNvbnN0IHVybCA9IHRoaXMuaHJlZiAmJiB0aGlzLmV4cGFuZFVSTCh0aGlzLmhyZWYpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcmVkaXJlY3Q6IHRoaXMucmVkaXJlY3QgPyB1cmwgOiB1bmRlZmluZWQsXG4gICAgICAgIHVybDogdGhpcy5yZWRpcmVjdCA/IHVuZGVmaW5lZCA6IHVybCB8fCB1bmRlZmluZWQsXG4gICAgICAgIHBhcmFtczogdGhpcy5jb25uZWN0UGFyYW1zKGxpdmVSZWZlcmVyKSxcbiAgICAgICAgc2Vzc2lvbjogdGhpcy5nZXRTZXNzaW9uKCksXG4gICAgICAgIHN0YXRpYzogdGhpcy5nZXRTdGF0aWMoKSxcbiAgICAgICAgZmxhc2g6IHRoaXMuZmxhc2gsXG4gICAgICAgIHN0aWNreTogdGhpcy5lbC5oYXNBdHRyaWJ1dGUoUEhYX1NUSUNLWSksXG4gICAgICB9O1xuICAgIH0pO1xuICAgIHRoaXMucG9ydGFsRWxlbWVudElkcyA9IG5ldyBTZXQoKTtcbiAgfVxuXG4gIHNldEhyZWYoaHJlZikge1xuICAgIHRoaXMuaHJlZiA9IGhyZWY7XG4gIH1cblxuICBzZXRSZWRpcmVjdChocmVmKSB7XG4gICAgdGhpcy5yZWRpcmVjdCA9IHRydWU7XG4gICAgdGhpcy5ocmVmID0gaHJlZjtcbiAgfVxuXG4gIGlzTWFpbigpIHtcbiAgICByZXR1cm4gdGhpcy5lbC5oYXNBdHRyaWJ1dGUoUEhYX01BSU4pO1xuICB9XG5cbiAgY29ubmVjdFBhcmFtcyhsaXZlUmVmZXJlcikge1xuICAgIGNvbnN0IHBhcmFtcyA9IHRoaXMubGl2ZVNvY2tldC5wYXJhbXModGhpcy5lbCk7XG4gICAgY29uc3QgbWFuaWZlc3QgPSBET00uYWxsKGRvY3VtZW50LCBgWyR7dGhpcy5iaW5kaW5nKFBIWF9UUkFDS19TVEFUSUMpfV1gKVxuICAgICAgLm1hcCgobm9kZSkgPT4gbm9kZS5zcmMgfHwgbm9kZS5ocmVmKVxuICAgICAgLmZpbHRlcigodXJsKSA9PiB0eXBlb2YgdXJsID09PSBcInN0cmluZ1wiKTtcblxuICAgIGlmIChtYW5pZmVzdC5sZW5ndGggPiAwKSB7XG4gICAgICBwYXJhbXNbXCJfdHJhY2tfc3RhdGljXCJdID0gbWFuaWZlc3Q7XG4gICAgfVxuICAgIHBhcmFtc1tcIl9tb3VudHNcIl0gPSB0aGlzLmpvaW5Db3VudDtcbiAgICBwYXJhbXNbXCJfbW91bnRfYXR0ZW1wdHNcIl0gPSB0aGlzLmpvaW5BdHRlbXB0cztcbiAgICBwYXJhbXNbXCJfbGl2ZV9yZWZlcmVyXCJdID0gbGl2ZVJlZmVyZXI7XG4gICAgdGhpcy5qb2luQXR0ZW1wdHMrKztcblxuICAgIHJldHVybiBwYXJhbXM7XG4gIH1cblxuICBpc0Nvbm5lY3RlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5jaGFubmVsLmNhblB1c2goKTtcbiAgfVxuXG4gIGdldFNlc3Npb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuZWwuZ2V0QXR0cmlidXRlKFBIWF9TRVNTSU9OKTtcbiAgfVxuXG4gIGdldFN0YXRpYygpIHtcbiAgICBjb25zdCB2YWwgPSB0aGlzLmVsLmdldEF0dHJpYnV0ZShQSFhfU1RBVElDKTtcbiAgICByZXR1cm4gdmFsID09PSBcIlwiID8gbnVsbCA6IHZhbDtcbiAgfVxuXG4gIGRlc3Ryb3koY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7fSkge1xuICAgIHRoaXMuZGVzdHJveUFsbENoaWxkcmVuKCk7XG4gICAgdGhpcy5kZXN0cm95UG9ydGFsRWxlbWVudHMoKTtcbiAgICB0aGlzLmRlc3Ryb3llZCA9IHRydWU7XG4gICAgRE9NLmRlbGV0ZVByaXZhdGUodGhpcy5lbCwgXCJ2aWV3XCIpO1xuICAgIGRlbGV0ZSB0aGlzLnJvb3QuY2hpbGRyZW5bdGhpcy5pZF07XG4gICAgaWYgKHRoaXMucGFyZW50KSB7XG4gICAgICBkZWxldGUgdGhpcy5yb290LmNoaWxkcmVuW3RoaXMucGFyZW50LmlkXVt0aGlzLmlkXTtcbiAgICB9XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMubG9hZGVyVGltZXIpO1xuICAgIGNvbnN0IG9uRmluaXNoZWQgPSAoKSA9PiB7XG4gICAgICBjYWxsYmFjaygpO1xuICAgICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLnZpZXdIb29rcykge1xuICAgICAgICB0aGlzLmRlc3Ryb3lIb29rKHRoaXMudmlld0hvb2tzW2lkXSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIERPTS5tYXJrUGh4Q2hpbGREZXN0cm95ZWQodGhpcy5lbCk7XG5cbiAgICB0aGlzLmxvZyhcImRlc3Ryb3llZFwiLCAoKSA9PiBbXCJ0aGUgY2hpbGQgaGFzIGJlZW4gcmVtb3ZlZCBmcm9tIHRoZSBwYXJlbnRcIl0pO1xuICAgIHRoaXMuY2hhbm5lbFxuICAgICAgLmxlYXZlKClcbiAgICAgIC5yZWNlaXZlKFwib2tcIiwgb25GaW5pc2hlZClcbiAgICAgIC5yZWNlaXZlKFwiZXJyb3JcIiwgb25GaW5pc2hlZClcbiAgICAgIC5yZWNlaXZlKFwidGltZW91dFwiLCBvbkZpbmlzaGVkKTtcbiAgfVxuXG4gIHNldENvbnRhaW5lckNsYXNzZXMoLi4uY2xhc3Nlcykge1xuICAgIHRoaXMuZWwuY2xhc3NMaXN0LnJlbW92ZShcbiAgICAgIFBIWF9DT05ORUNURURfQ0xBU1MsXG4gICAgICBQSFhfTE9BRElOR19DTEFTUyxcbiAgICAgIFBIWF9FUlJPUl9DTEFTUyxcbiAgICAgIFBIWF9DTElFTlRfRVJST1JfQ0xBU1MsXG4gICAgICBQSFhfU0VSVkVSX0VSUk9SX0NMQVNTLFxuICAgICk7XG4gICAgdGhpcy5lbC5jbGFzc0xpc3QuYWRkKC4uLmNsYXNzZXMpO1xuICB9XG5cbiAgc2hvd0xvYWRlcih0aW1lb3V0KSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMubG9hZGVyVGltZXIpO1xuICAgIGlmICh0aW1lb3V0KSB7XG4gICAgICB0aGlzLmxvYWRlclRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB0aGlzLnNob3dMb2FkZXIoKSwgdGltZW91dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAoY29uc3QgaWQgaW4gdGhpcy52aWV3SG9va3MpIHtcbiAgICAgICAgdGhpcy52aWV3SG9va3NbaWRdLl9fZGlzY29ubmVjdGVkKCk7XG4gICAgICB9XG4gICAgICB0aGlzLnNldENvbnRhaW5lckNsYXNzZXMoUEhYX0xPQURJTkdfQ0xBU1MpO1xuICAgIH1cbiAgfVxuXG4gIGV4ZWNBbGwoYmluZGluZykge1xuICAgIERPTS5hbGwodGhpcy5lbCwgYFske2JpbmRpbmd9XWAsIChlbCkgPT5cbiAgICAgIHRoaXMubGl2ZVNvY2tldC5leGVjSlMoZWwsIGVsLmdldEF0dHJpYnV0ZShiaW5kaW5nKSksXG4gICAgKTtcbiAgfVxuXG4gIGhpZGVMb2FkZXIoKSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMubG9hZGVyVGltZXIpO1xuICAgIGNsZWFyVGltZW91dCh0aGlzLmRpc2Nvbm5lY3RlZFRpbWVyKTtcbiAgICB0aGlzLnNldENvbnRhaW5lckNsYXNzZXMoUEhYX0NPTk5FQ1RFRF9DTEFTUyk7XG4gICAgdGhpcy5leGVjQWxsKHRoaXMuYmluZGluZyhcImNvbm5lY3RlZFwiKSk7XG4gIH1cblxuICB0cmlnZ2VyUmVjb25uZWN0ZWQoKSB7XG4gICAgZm9yIChjb25zdCBpZCBpbiB0aGlzLnZpZXdIb29rcykge1xuICAgICAgdGhpcy52aWV3SG9va3NbaWRdLl9fcmVjb25uZWN0ZWQoKTtcbiAgICB9XG4gIH1cblxuICBsb2coa2luZCwgbXNnQ2FsbGJhY2spIHtcbiAgICB0aGlzLmxpdmVTb2NrZXQubG9nKHRoaXMsIGtpbmQsIG1zZ0NhbGxiYWNrKTtcbiAgfVxuXG4gIHRyYW5zaXRpb24odGltZSwgb25TdGFydCwgb25Eb25lID0gZnVuY3Rpb24gKCkge30pIHtcbiAgICB0aGlzLmxpdmVTb2NrZXQudHJhbnNpdGlvbih0aW1lLCBvblN0YXJ0LCBvbkRvbmUpO1xuICB9XG5cbiAgLy8gY2FsbHMgdGhlIGNhbGxiYWNrIHdpdGggdGhlIHZpZXcgYW5kIHRhcmdldCBlbGVtZW50IGZvciB0aGUgZ2l2ZW4gcGh4VGFyZ2V0XG4gIC8vIHRhcmdldHMgY2FuIGJlOlxuICAvLyAgKiBhbiBlbGVtZW50IGl0c2VsZiwgdGhlbiBpdCBpcyBzaW1wbHkgcGFzc2VkIHRvIGxpdmVTb2NrZXQub3duZXI7XG4gIC8vICAqIGEgQ0lEIChDb21wb25lbnQgSUQpLCB0aGVuIHdlIGZpcnN0IHNlYXJjaCB0aGUgY29tcG9uZW50J3MgZWxlbWVudCBpbiB0aGUgRE9NXG4gIC8vICAqIGEgc2VsZWN0b3IsIHRoZW4gd2Ugc2VhcmNoIHRoZSBzZWxlY3RvciBpbiB0aGUgRE9NIGFuZCBjYWxsIHRoZSBjYWxsYmFja1xuICAvLyAgICBmb3IgZWFjaCBlbGVtZW50IGZvdW5kIHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgb3duZXIgdmlld1xuICB3aXRoaW5UYXJnZXRzKHBoeFRhcmdldCwgY2FsbGJhY2ssIGRvbSA9IGRvY3VtZW50KSB7XG4gICAgLy8gaW4gdGhlIGZvcm0gcmVjb3ZlcnkgY2FzZSB3ZSBzZWFyY2ggaW4gYSB0ZW1wbGF0ZSBmcmFnbWVudCBpbnN0ZWFkIG9mXG4gICAgLy8gdGhlIHJlYWwgZG9tLCB0aGVyZWZvcmUgd2Ugb3B0aW9uYWxseSBwYXNzIGRvbSBhbmQgdmlld0VsXG5cbiAgICBpZiAocGh4VGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgfHwgcGh4VGFyZ2V0IGluc3RhbmNlb2YgU1ZHRWxlbWVudCkge1xuICAgICAgcmV0dXJuIHRoaXMubGl2ZVNvY2tldC5vd25lcihwaHhUYXJnZXQsICh2aWV3KSA9PlxuICAgICAgICBjYWxsYmFjayh2aWV3LCBwaHhUYXJnZXQpLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoaXNDaWQocGh4VGFyZ2V0KSkge1xuICAgICAgY29uc3QgdGFyZ2V0cyA9IERPTS5maW5kQ29tcG9uZW50Tm9kZUxpc3QodGhpcy5pZCwgcGh4VGFyZ2V0LCBkb20pO1xuICAgICAgaWYgKHRhcmdldHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGxvZ0Vycm9yKGBubyBjb21wb25lbnQgZm91bmQgbWF0Y2hpbmcgcGh4LXRhcmdldCBvZiAke3BoeFRhcmdldH1gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNhbGxiYWNrKHRoaXMsIHBhcnNlSW50KHBoeFRhcmdldCkpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB0YXJnZXRzID0gQXJyYXkuZnJvbShkb20ucXVlcnlTZWxlY3RvckFsbChwaHhUYXJnZXQpKTtcbiAgICAgIGlmICh0YXJnZXRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBsb2dFcnJvcihcbiAgICAgICAgICBgbm90aGluZyBmb3VuZCBtYXRjaGluZyB0aGUgcGh4LXRhcmdldCBzZWxlY3RvciBcIiR7cGh4VGFyZ2V0fVwiYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHRhcmdldHMuZm9yRWFjaCgodGFyZ2V0KSA9PlxuICAgICAgICB0aGlzLmxpdmVTb2NrZXQub3duZXIodGFyZ2V0LCAodmlldykgPT4gY2FsbGJhY2sodmlldywgdGFyZ2V0KSksXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGFwcGx5RGlmZih0eXBlLCByYXdEaWZmLCBjYWxsYmFjaykge1xuICAgIHRoaXMubG9nKHR5cGUsICgpID0+IFtcIlwiLCBjbG9uZShyYXdEaWZmKV0pO1xuICAgIGNvbnN0IHsgZGlmZiwgcmVwbHksIGV2ZW50cywgdGl0bGUgfSA9IFJlbmRlcmVkLmV4dHJhY3QocmF3RGlmZik7XG4gICAgY2FsbGJhY2soeyBkaWZmLCByZXBseSwgZXZlbnRzIH0pO1xuICAgIGlmICh0eXBlb2YgdGl0bGUgPT09IFwic3RyaW5nXCIgfHwgKHR5cGUgPT0gXCJtb3VudFwiICYmIHRoaXMuaXNNYWluKCkpKSB7XG4gICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IERPTS5wdXRUaXRsZSh0aXRsZSkpO1xuICAgIH1cbiAgfVxuXG4gIG9uSm9pbihyZXNwKSB7XG4gICAgY29uc3QgeyByZW5kZXJlZCwgY29udGFpbmVyLCBsaXZldmlld192ZXJzaW9uLCBwaWQgfSA9IHJlc3A7XG4gICAgaWYgKGNvbnRhaW5lcikge1xuICAgICAgY29uc3QgW3RhZywgYXR0cnNdID0gY29udGFpbmVyO1xuICAgICAgdGhpcy5lbCA9IERPTS5yZXBsYWNlUm9vdENvbnRhaW5lcih0aGlzLmVsLCB0YWcsIGF0dHJzKTtcbiAgICB9XG4gICAgdGhpcy5jaGlsZEpvaW5zID0gMDtcbiAgICB0aGlzLmpvaW5QZW5kaW5nID0gdHJ1ZTtcbiAgICB0aGlzLmZsYXNoID0gbnVsbDtcbiAgICBpZiAodGhpcy5yb290ID09PSB0aGlzKSB7XG4gICAgICB0aGlzLmZvcm1zRm9yUmVjb3ZlcnkgPSB0aGlzLmdldEZvcm1zRm9yUmVjb3ZlcnkoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuaXNNYWluKCkgJiYgd2luZG93Lmhpc3Rvcnkuc3RhdGUgPT09IG51bGwpIHtcbiAgICAgIC8vIHNldCBpbml0aWFsIGhpc3RvcnkgZW50cnkgaWYgdGhpcyBpcyB0aGUgZmlyc3QgcGFnZSBsb2FkIChubyBoaXN0b3J5KVxuICAgICAgQnJvd3Nlci5wdXNoU3RhdGUoXCJyZXBsYWNlXCIsIHtcbiAgICAgICAgdHlwZTogXCJwYXRjaFwiLFxuICAgICAgICBpZDogdGhpcy5pZCxcbiAgICAgICAgcG9zaXRpb246IHRoaXMubGl2ZVNvY2tldC5jdXJyZW50SGlzdG9yeVBvc2l0aW9uLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKGxpdmV2aWV3X3ZlcnNpb24gIT09IHRoaXMubGl2ZVNvY2tldC52ZXJzaW9uKCkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgIGBMaXZlVmlldyBhc3NldCB2ZXJzaW9uIG1pc21hdGNoLiBKYXZhU2NyaXB0IHZlcnNpb24gJHt0aGlzLmxpdmVTb2NrZXQudmVyc2lvbigpfSB2cy4gc2VydmVyICR7bGl2ZXZpZXdfdmVyc2lvbn0uIFRvIGF2b2lkIGlzc3VlcywgcGxlYXNlIGVuc3VyZSB0aGF0IHlvdXIgYXNzZXRzIHVzZSB0aGUgc2FtZSB2ZXJzaW9uIGFzIHRoZSBzZXJ2ZXIuYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gVGhlIHBpZCBpcyBvbmx5IHNlbnQgaWZcbiAgICAvL1xuICAgIC8vICAgIGNvbmZpZyA6cGhvZW5peF9saXZlX3ZpZXcsIDpkZWJ1Z19hdHRyaWJ1dGVzXG4gICAgLy9cbiAgICAvLyBpZiBzZXQgdG8gdHJ1ZS4gSXQgaXMgdG8gaGVscCBkZWJ1Z2dpbmcgaW4gZGV2ZWxvcG1lbnQuXG4gICAgaWYgKHBpZCkge1xuICAgICAgdGhpcy5lbC5zZXRBdHRyaWJ1dGUoUEhYX0xWX1BJRCwgcGlkKTtcbiAgICB9XG5cbiAgICBCcm93c2VyLmRyb3BMb2NhbChcbiAgICAgIHRoaXMubGl2ZVNvY2tldC5sb2NhbFN0b3JhZ2UsXG4gICAgICB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUsXG4gICAgICBDT05TRUNVVElWRV9SRUxPQURTLFxuICAgICk7XG4gICAgdGhpcy5hcHBseURpZmYoXCJtb3VudFwiLCByZW5kZXJlZCwgKHsgZGlmZiwgZXZlbnRzIH0pID0+IHtcbiAgICAgIHRoaXMucmVuZGVyZWQgPSBuZXcgUmVuZGVyZWQodGhpcy5pZCwgZGlmZik7XG4gICAgICBjb25zdCBbaHRtbCwgc3RyZWFtc10gPSB0aGlzLnJlbmRlckNvbnRhaW5lcihudWxsLCBcImpvaW5cIik7XG4gICAgICB0aGlzLmRyb3BQZW5kaW5nUmVmcygpO1xuICAgICAgdGhpcy5qb2luQ291bnQrKztcbiAgICAgIHRoaXMuam9pbkF0dGVtcHRzID0gMDtcblxuICAgICAgdGhpcy5tYXliZVJlY292ZXJGb3JtcyhodG1sLCAoKSA9PiB7XG4gICAgICAgIHRoaXMub25Kb2luQ29tcGxldGUocmVzcCwgaHRtbCwgc3RyZWFtcywgZXZlbnRzKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZHJvcFBlbmRpbmdSZWZzKCkge1xuICAgIERPTS5hbGwoZG9jdW1lbnQsIGBbJHtQSFhfUkVGX1NSQ309XCIke3RoaXMucmVmU3JjKCl9XCJdYCwgKGVsKSA9PiB7XG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1JFRl9MT0FESU5HKTtcbiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShQSFhfUkVGX1NSQyk7XG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1JFRl9MT0NLKTtcbiAgICB9KTtcbiAgfVxuXG4gIG9uSm9pbkNvbXBsZXRlKHsgbGl2ZV9wYXRjaCB9LCBodG1sLCBzdHJlYW1zLCBldmVudHMpIHtcbiAgICAvLyBJbiBvcmRlciB0byBwcm92aWRlIGEgYmV0dGVyIGV4cGVyaWVuY2UsIHdlIHdhbnQgdG8gam9pblxuICAgIC8vIGFsbCBMaXZlVmlld3MgZmlyc3QgYW5kIG9ubHkgdGhlbiBhcHBseSB0aGVpciBwYXRjaGVzLlxuICAgIGlmICh0aGlzLmpvaW5Db3VudCA+IDEgfHwgKHRoaXMucGFyZW50ICYmICF0aGlzLnBhcmVudC5pc0pvaW5QZW5kaW5nKCkpKSB7XG4gICAgICByZXR1cm4gdGhpcy5hcHBseUpvaW5QYXRjaChsaXZlX3BhdGNoLCBodG1sLCBzdHJlYW1zLCBldmVudHMpO1xuICAgIH1cblxuICAgIC8vIE9uZSBkb3duc2lkZSBvZiB0aGlzIGFwcHJvYWNoIGlzIHRoYXQgd2UgbmVlZCB0byBmaW5kIHBoeENoaWxkcmVuXG4gICAgLy8gaW4gdGhlIGh0bWwgZnJhZ21lbnQsIGluc3RlYWQgb2YgZGlyZWN0bHkgb24gdGhlIERPTS4gVGhlIGZyYWdtZW50XG4gICAgLy8gYWxzbyBkb2VzIG5vdCBpbmNsdWRlIFBIWF9TVEFUSUMsIHNvIHdlIG5lZWQgdG8gY29weSBpdCBvdmVyIGZyb21cbiAgICAvLyB0aGUgRE9NLlxuICAgIGNvbnN0IG5ld0NoaWxkcmVuID0gRE9NLmZpbmRQaHhDaGlsZHJlbkluRnJhZ21lbnQoaHRtbCwgdGhpcy5pZCkuZmlsdGVyKFxuICAgICAgKHRvRWwpID0+IHtcbiAgICAgICAgY29uc3QgZnJvbUVsID0gdG9FbC5pZCAmJiB0aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoYFtpZD1cIiR7dG9FbC5pZH1cIl1gKTtcbiAgICAgICAgY29uc3QgcGh4U3RhdGljID0gZnJvbUVsICYmIGZyb21FbC5nZXRBdHRyaWJ1dGUoUEhYX1NUQVRJQyk7XG4gICAgICAgIGlmIChwaHhTdGF0aWMpIHtcbiAgICAgICAgICB0b0VsLnNldEF0dHJpYnV0ZShQSFhfU1RBVElDLCBwaHhTdGF0aWMpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHNldCBQSFhfUk9PVF9JRCB0byBwcmV2ZW50IGV2ZW50cyBmcm9tIGJlaW5nIGRpc3BhdGNoZWQgdG8gdGhlIHJvb3Qgdmlld1xuICAgICAgICAvLyB3aGlsZSB0aGUgY2hpbGQgam9pbiBpcyBzdGlsbCBwZW5kaW5nXG4gICAgICAgIGlmIChmcm9tRWwpIHtcbiAgICAgICAgICBmcm9tRWwuc2V0QXR0cmlidXRlKFBIWF9ST09UX0lELCB0aGlzLnJvb3QuaWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmpvaW5DaGlsZCh0b0VsKTtcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIGlmIChuZXdDaGlsZHJlbi5sZW5ndGggPT09IDApIHtcbiAgICAgIGlmICh0aGlzLnBhcmVudCkge1xuICAgICAgICB0aGlzLnJvb3QucGVuZGluZ0pvaW5PcHMucHVzaChbXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICAoKSA9PiB0aGlzLmFwcGx5Sm9pblBhdGNoKGxpdmVfcGF0Y2gsIGh0bWwsIHN0cmVhbXMsIGV2ZW50cyksXG4gICAgICAgIF0pO1xuICAgICAgICB0aGlzLnBhcmVudC5hY2tKb2luKHRoaXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5vbkFsbENoaWxkSm9pbnNDb21wbGV0ZSgpO1xuICAgICAgICB0aGlzLmFwcGx5Sm9pblBhdGNoKGxpdmVfcGF0Y2gsIGh0bWwsIHN0cmVhbXMsIGV2ZW50cyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucm9vdC5wZW5kaW5nSm9pbk9wcy5wdXNoKFtcbiAgICAgICAgdGhpcyxcbiAgICAgICAgKCkgPT4gdGhpcy5hcHBseUpvaW5QYXRjaChsaXZlX3BhdGNoLCBodG1sLCBzdHJlYW1zLCBldmVudHMpLFxuICAgICAgXSk7XG4gICAgfVxuICB9XG5cbiAgYXR0YWNoVHJ1ZURvY0VsKCkge1xuICAgIHRoaXMuZWwgPSBET00uYnlJZCh0aGlzLmlkKTtcbiAgICB0aGlzLmVsLnNldEF0dHJpYnV0ZShQSFhfUk9PVF9JRCwgdGhpcy5yb290LmlkKTtcbiAgfVxuXG4gIC8vIHRoaXMgaXMgaW52b2tlZCBmb3IgZGVhZCBhbmQgbGl2ZSB2aWV3cywgc28gd2UgbXVzdCBmaWx0ZXIgYnlcbiAgLy8gYnkgb3duZXIgdG8gZW5zdXJlIHdlIGFyZW4ndCBkdXBsaWNhdGluZyBob29rcyBhY3Jvc3MgZGlzY29ubmVjdFxuICAvLyBhbmQgY29ubmVjdGVkIHN0YXRlcy4gVGhpcyBhbHNvIGhhbmRsZXMgY2FzZXMgd2hlcmUgaG9va3MgZXhpc3RcbiAgLy8gaW4gYSByb290IGxheW91dCB3aXRoIGEgTFYgaW4gdGhlIGJvZHlcbiAgZXhlY05ld01vdW50ZWQocGFyZW50ID0gZG9jdW1lbnQpIHtcbiAgICBsZXQgcGh4Vmlld3BvcnRUb3AgPSB0aGlzLmJpbmRpbmcoUEhYX1ZJRVdQT1JUX1RPUCk7XG4gICAgbGV0IHBoeFZpZXdwb3J0Qm90dG9tID0gdGhpcy5iaW5kaW5nKFBIWF9WSUVXUE9SVF9CT1RUT00pO1xuICAgIHRoaXMuYWxsKFxuICAgICAgcGFyZW50LFxuICAgICAgYFske3BoeFZpZXdwb3J0VG9wfV0sIFske3BoeFZpZXdwb3J0Qm90dG9tfV1gLFxuICAgICAgKGhvb2tFbCkgPT4ge1xuICAgICAgICBET00ubWFpbnRhaW5Qcml2YXRlSG9va3MoXG4gICAgICAgICAgaG9va0VsLFxuICAgICAgICAgIGhvb2tFbCxcbiAgICAgICAgICBwaHhWaWV3cG9ydFRvcCxcbiAgICAgICAgICBwaHhWaWV3cG9ydEJvdHRvbSxcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5tYXliZUFkZE5ld0hvb2soaG9va0VsKTtcbiAgICAgIH0sXG4gICAgKTtcbiAgICB0aGlzLmFsbChcbiAgICAgIHBhcmVudCxcbiAgICAgIGBbJHt0aGlzLmJpbmRpbmcoUEhYX0hPT0spfV0sIFtkYXRhLXBoeC0ke1BIWF9IT09LfV1gLFxuICAgICAgKGhvb2tFbCkgPT4ge1xuICAgICAgICB0aGlzLm1heWJlQWRkTmV3SG9vayhob29rRWwpO1xuICAgICAgfSxcbiAgICApO1xuICAgIHRoaXMuYWxsKHBhcmVudCwgYFske3RoaXMuYmluZGluZyhQSFhfTU9VTlRFRCl9XWAsIChlbCkgPT4ge1xuICAgICAgdGhpcy5tYXliZU1vdW50ZWQoZWwpO1xuICAgIH0pO1xuICB9XG5cbiAgYWxsKHBhcmVudCwgc2VsZWN0b3IsIGNhbGxiYWNrKSB7XG4gICAgRE9NLmFsbChwYXJlbnQsIHNlbGVjdG9yLCAoZWwpID0+IHtcbiAgICAgIGlmICh0aGlzLm93bnNFbGVtZW50KGVsKSkge1xuICAgICAgICBjYWxsYmFjayhlbCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBhcHBseUpvaW5QYXRjaChsaXZlX3BhdGNoLCBodG1sLCBzdHJlYW1zLCBldmVudHMpIHtcbiAgICAvLyBpbiBjYXNlIG9mIHJlam9pbnMsIHdlIG5lZWQgdG8gbWFudWFsbHkgcGVyZm9ybSBhbGxcbiAgICAvLyBwZW5kaW5nIG9wc1xuICAgIGlmICh0aGlzLmpvaW5Db3VudCA+IDEpIHtcbiAgICAgIGlmICh0aGlzLnBlbmRpbmdKb2luT3BzLmxlbmd0aCkge1xuICAgICAgICB0aGlzLnBlbmRpbmdKb2luT3BzLmZvckVhY2goKGNiKSA9PiB0eXBlb2YgY2IgPT09IFwiZnVuY3Rpb25cIiAmJiBjYigpKTtcbiAgICAgICAgdGhpcy5wZW5kaW5nSm9pbk9wcyA9IFtdO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmF0dGFjaFRydWVEb2NFbCgpO1xuICAgIGNvbnN0IHBhdGNoID0gbmV3IERPTVBhdGNoKHRoaXMsIHRoaXMuZWwsIHRoaXMuaWQsIGh0bWwsIHN0cmVhbXMsIG51bGwpO1xuICAgIHBhdGNoLm1hcmtQcnVuYWJsZUNvbnRlbnRGb3JSZW1vdmFsKCk7XG4gICAgdGhpcy5wZXJmb3JtUGF0Y2gocGF0Y2gsIGZhbHNlLCB0cnVlKTtcbiAgICB0aGlzLmpvaW5OZXdDaGlsZHJlbigpO1xuICAgIHRoaXMuZXhlY05ld01vdW50ZWQoKTtcblxuICAgIHRoaXMuam9pblBlbmRpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmxpdmVTb2NrZXQuZGlzcGF0Y2hFdmVudHMoZXZlbnRzKTtcbiAgICB0aGlzLmFwcGx5UGVuZGluZ1VwZGF0ZXMoKTtcblxuICAgIGlmIChsaXZlX3BhdGNoKSB7XG4gICAgICBjb25zdCB7IGtpbmQsIHRvIH0gPSBsaXZlX3BhdGNoO1xuICAgICAgdGhpcy5saXZlU29ja2V0Lmhpc3RvcnlQYXRjaCh0bywga2luZCk7XG4gICAgfVxuICAgIHRoaXMuaGlkZUxvYWRlcigpO1xuICAgIGlmICh0aGlzLmpvaW5Db3VudCA+IDEpIHtcbiAgICAgIHRoaXMudHJpZ2dlclJlY29ubmVjdGVkKCk7XG4gICAgfVxuICAgIHRoaXMuc3RvcENhbGxiYWNrKCk7XG4gIH1cblxuICB0cmlnZ2VyQmVmb3JlVXBkYXRlSG9vayhmcm9tRWwsIHRvRWwpIHtcbiAgICB0aGlzLmxpdmVTb2NrZXQudHJpZ2dlckRPTShcIm9uQmVmb3JlRWxVcGRhdGVkXCIsIFtmcm9tRWwsIHRvRWxdKTtcbiAgICBjb25zdCBob29rID0gdGhpcy5nZXRIb29rKGZyb21FbCk7XG4gICAgY29uc3QgaXNJZ25vcmVkID0gaG9vayAmJiBET00uaXNJZ25vcmVkKGZyb21FbCwgdGhpcy5iaW5kaW5nKFBIWF9VUERBVEUpKTtcbiAgICBpZiAoXG4gICAgICBob29rICYmXG4gICAgICAhZnJvbUVsLmlzRXF1YWxOb2RlKHRvRWwpICYmXG4gICAgICAhKGlzSWdub3JlZCAmJiBpc0VxdWFsT2JqKGZyb21FbC5kYXRhc2V0LCB0b0VsLmRhdGFzZXQpKVxuICAgICkge1xuICAgICAgaG9vay5fX2JlZm9yZVVwZGF0ZSgpO1xuICAgICAgcmV0dXJuIGhvb2s7XG4gICAgfVxuICB9XG5cbiAgbWF5YmVNb3VudGVkKGVsKSB7XG4gICAgY29uc3QgcGh4TW91bnRlZCA9IGVsLmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoUEhYX01PVU5URUQpKTtcbiAgICBjb25zdCBoYXNCZWVuSW52b2tlZCA9IHBoeE1vdW50ZWQgJiYgRE9NLnByaXZhdGUoZWwsIFwibW91bnRlZFwiKTtcbiAgICBpZiAocGh4TW91bnRlZCAmJiAhaGFzQmVlbkludm9rZWQpIHtcbiAgICAgIHRoaXMubGl2ZVNvY2tldC5leGVjSlMoZWwsIHBoeE1vdW50ZWQpO1xuICAgICAgRE9NLnB1dFByaXZhdGUoZWwsIFwibW91bnRlZFwiLCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICBtYXliZUFkZE5ld0hvb2soZWwpIHtcbiAgICBjb25zdCBuZXdIb29rID0gdGhpcy5hZGRIb29rKGVsKTtcbiAgICBpZiAobmV3SG9vaykge1xuICAgICAgbmV3SG9vay5fX21vdW50ZWQoKTtcbiAgICB9XG4gIH1cblxuICBwZXJmb3JtUGF0Y2gocGF0Y2gsIHBydW5lQ2lkcywgaXNKb2luUGF0Y2ggPSBmYWxzZSkge1xuICAgIGNvbnN0IHJlbW92ZWRFbHMgPSBbXTtcbiAgICBsZXQgcGh4Q2hpbGRyZW5BZGRlZCA9IGZhbHNlO1xuICAgIGNvbnN0IHVwZGF0ZWRIb29rSWRzID0gbmV3IFNldCgpO1xuXG4gICAgdGhpcy5saXZlU29ja2V0LnRyaWdnZXJET00oXCJvblBhdGNoU3RhcnRcIiwgW3BhdGNoLnRhcmdldENvbnRhaW5lcl0pO1xuXG4gICAgcGF0Y2guYWZ0ZXIoXCJhZGRlZFwiLCAoZWwpID0+IHtcbiAgICAgIHRoaXMubGl2ZVNvY2tldC50cmlnZ2VyRE9NKFwib25Ob2RlQWRkZWRcIiwgW2VsXSk7XG4gICAgICBjb25zdCBwaHhWaWV3cG9ydFRvcCA9IHRoaXMuYmluZGluZyhQSFhfVklFV1BPUlRfVE9QKTtcbiAgICAgIGNvbnN0IHBoeFZpZXdwb3J0Qm90dG9tID0gdGhpcy5iaW5kaW5nKFBIWF9WSUVXUE9SVF9CT1RUT00pO1xuICAgICAgRE9NLm1haW50YWluUHJpdmF0ZUhvb2tzKGVsLCBlbCwgcGh4Vmlld3BvcnRUb3AsIHBoeFZpZXdwb3J0Qm90dG9tKTtcbiAgICAgIHRoaXMubWF5YmVBZGROZXdIb29rKGVsKTtcbiAgICAgIGlmIChlbC5nZXRBdHRyaWJ1dGUpIHtcbiAgICAgICAgdGhpcy5tYXliZU1vdW50ZWQoZWwpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcGF0Y2guYWZ0ZXIoXCJwaHhDaGlsZEFkZGVkXCIsIChlbCkgPT4ge1xuICAgICAgaWYgKERPTS5pc1BoeFN0aWNreShlbCkpIHtcbiAgICAgICAgdGhpcy5saXZlU29ja2V0LmpvaW5Sb290Vmlld3MoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBoeENoaWxkcmVuQWRkZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcGF0Y2guYmVmb3JlKFwidXBkYXRlZFwiLCAoZnJvbUVsLCB0b0VsKSA9PiB7XG4gICAgICBjb25zdCBob29rID0gdGhpcy50cmlnZ2VyQmVmb3JlVXBkYXRlSG9vayhmcm9tRWwsIHRvRWwpO1xuICAgICAgaWYgKGhvb2spIHtcbiAgICAgICAgdXBkYXRlZEhvb2tJZHMuYWRkKGZyb21FbC5pZCk7XG4gICAgICB9XG4gICAgICAvLyB0cmlnZ2VyIEpTIHNwZWNpZmljIHVwZGF0ZSBsb2dpYyAoZm9yIGV4YW1wbGUgZm9yIEpTLmlnbm9yZV9hdHRyaWJ1dGVzKVxuICAgICAgSlMub25CZWZvcmVFbFVwZGF0ZWQoZnJvbUVsLCB0b0VsKTtcbiAgICB9KTtcblxuICAgIHBhdGNoLmFmdGVyKFwidXBkYXRlZFwiLCAoZWwpID0+IHtcbiAgICAgIGlmICh1cGRhdGVkSG9va0lkcy5oYXMoZWwuaWQpKSB7XG4gICAgICAgIHRoaXMuZ2V0SG9vayhlbCkuX191cGRhdGVkKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBwYXRjaC5hZnRlcihcImRpc2NhcmRlZFwiLCAoZWwpID0+IHtcbiAgICAgIGlmIChlbC5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgICAgcmVtb3ZlZEVscy5wdXNoKGVsKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHBhdGNoLmFmdGVyKFwidHJhbnNpdGlvbnNEaXNjYXJkZWRcIiwgKGVscykgPT5cbiAgICAgIHRoaXMuYWZ0ZXJFbGVtZW50c1JlbW92ZWQoZWxzLCBwcnVuZUNpZHMpLFxuICAgICk7XG4gICAgcGF0Y2gucGVyZm9ybShpc0pvaW5QYXRjaCk7XG4gICAgdGhpcy5hZnRlckVsZW1lbnRzUmVtb3ZlZChyZW1vdmVkRWxzLCBwcnVuZUNpZHMpO1xuXG4gICAgdGhpcy5saXZlU29ja2V0LnRyaWdnZXJET00oXCJvblBhdGNoRW5kXCIsIFtwYXRjaC50YXJnZXRDb250YWluZXJdKTtcbiAgICByZXR1cm4gcGh4Q2hpbGRyZW5BZGRlZDtcbiAgfVxuXG4gIGFmdGVyRWxlbWVudHNSZW1vdmVkKGVsZW1lbnRzLCBwcnVuZUNpZHMpIHtcbiAgICBjb25zdCBkZXN0cm95ZWRDSURzID0gW107XG4gICAgZWxlbWVudHMuZm9yRWFjaCgocGFyZW50KSA9PiB7XG4gICAgICBjb25zdCBjb21wb25lbnRzID0gRE9NLmFsbChcbiAgICAgICAgcGFyZW50LFxuICAgICAgICBgWyR7UEhYX1ZJRVdfUkVGfT1cIiR7dGhpcy5pZH1cIl1bJHtQSFhfQ09NUE9ORU5UfV1gLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGhvb2tzID0gRE9NLmFsbChcbiAgICAgICAgcGFyZW50LFxuICAgICAgICBgWyR7dGhpcy5iaW5kaW5nKFBIWF9IT09LKX1dLCBbZGF0YS1waHgtaG9va11gLFxuICAgICAgKTtcbiAgICAgIGNvbXBvbmVudHMuY29uY2F0KHBhcmVudCkuZm9yRWFjaCgoZWwpID0+IHtcbiAgICAgICAgY29uc3QgY2lkID0gdGhpcy5jb21wb25lbnRJRChlbCk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBpc0NpZChjaWQpICYmXG4gICAgICAgICAgZGVzdHJveWVkQ0lEcy5pbmRleE9mKGNpZCkgPT09IC0xICYmXG4gICAgICAgICAgZWwuZ2V0QXR0cmlidXRlKFBIWF9WSUVXX1JFRikgPT09IHRoaXMuaWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgZGVzdHJveWVkQ0lEcy5wdXNoKGNpZCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaG9va3MuY29uY2F0KHBhcmVudCkuZm9yRWFjaCgoaG9va0VsKSA9PiB7XG4gICAgICAgIGNvbnN0IGhvb2sgPSB0aGlzLmdldEhvb2soaG9va0VsKTtcbiAgICAgICAgaG9vayAmJiB0aGlzLmRlc3Ryb3lIb29rKGhvb2spO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgLy8gV2Ugc2hvdWxkIG5vdCBwcnVuZUNpZHMgb24gam9pbnMuIE90aGVyd2lzZSwgaW4gY2FzZSBvZlxuICAgIC8vIHJlam9pbnMsIHdlIG1heSBub3RpZnkgY2lkcyB0aGF0IG5vIGxvbmdlciBiZWxvbmcgdG8gdGhlXG4gICAgLy8gY3VycmVudCBMaXZlVmlldyB0byBiZSByZW1vdmVkLlxuICAgIGlmIChwcnVuZUNpZHMpIHtcbiAgICAgIHRoaXMubWF5YmVQdXNoQ29tcG9uZW50c0Rlc3Ryb3llZChkZXN0cm95ZWRDSURzKTtcbiAgICB9XG4gIH1cblxuICBqb2luTmV3Q2hpbGRyZW4oKSB7XG4gICAgRE9NLmZpbmRQaHhDaGlsZHJlbihkb2N1bWVudCwgdGhpcy5pZCkuZm9yRWFjaCgoZWwpID0+IHRoaXMuam9pbkNoaWxkKGVsKSk7XG4gIH1cblxuICBtYXliZVJlY292ZXJGb3JtcyhodG1sLCBjYWxsYmFjaykge1xuICAgIGNvbnN0IHBoeENoYW5nZSA9IHRoaXMuYmluZGluZyhcImNoYW5nZVwiKTtcbiAgICBjb25zdCBvbGRGb3JtcyA9IHRoaXMucm9vdC5mb3Jtc0ZvclJlY292ZXJ5O1xuICAgIC8vIFNvIHdoeSBkbyB3ZSBjcmVhdGUgYSB0ZW1wbGF0ZSBlbGVtZW50IGhlcmU/XG4gICAgLy8gT25lIHdheSB0byByZWNvdmVyIGZvcm1zIHdvdWxkIGJlIHRvIGltbWVkaWF0ZWx5IGFwcGx5IHRoZSBtb3VudFxuICAgIC8vIHBhdGNoIGFuZCB0aGVuIGFmdGVyd2FyZHMgcmVjb3ZlciB0aGUgZm9ybXMuIEhvd2V2ZXIsIHRoaXMgd291bGRcbiAgICAvLyBjYXVzZSBhIGZsaWNrZXIsIGJlY2F1c2UgdGhlIG1vdW50IHBhdGNoIHdvdWxkIHJlbW92ZSB0aGUgZm9ybSBjb250ZW50XG4gICAgLy8gdW50aWwgaXQgaXMgcmVzdG9yZWQuIFRoZXJlZm9yZSBMViBkZWNpZGVkIHRvIGRvIGZvcm0gcmVjb3Zlcnkgd2l0aCB0aGVcbiAgICAvLyByYXcgSFRNTCBiZWZvcmUgaXQgaXMgYXBwbGllZCBhbmQgZGVsYXkgdGhlIG1vdW50IHBhdGNoIHVudGlsIHRoZSBmb3JtXG4gICAgLy8gcmVjb3ZlcnkgZXZlbnRzIGFyZSBkb25lLlxuICAgIGNvbnN0IHRlbXBsYXRlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRlbXBsYXRlXCIpO1xuICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IGh0bWw7XG5cbiAgICAvLyB3ZSBzcGVjaWFsIGNhc2UgPC5wb3J0YWw+IGhlcmUgYW5kIHRlbGVwb3J0IGl0IGludG8gb3VyIHRlbXBvcmFyeSBET00gZm9yIHJlY292ZXJ5XG4gICAgLy8gYXMgd2UnZCBvdGhlcndpc2Ugbm90IGZpbmQgdGVsZXBvcnRlZCBmb3Jtc1xuICAgIERPTS5hbGwodGVtcGxhdGUuY29udGVudCwgYFske1BIWF9QT1JUQUx9XWApLmZvckVhY2goKHBvcnRhbFRlbXBsYXRlKSA9PiB7XG4gICAgICB0ZW1wbGF0ZS5jb250ZW50LmZpcnN0RWxlbWVudENoaWxkLmFwcGVuZENoaWxkKFxuICAgICAgICBwb3J0YWxUZW1wbGF0ZS5jb250ZW50LmZpcnN0RWxlbWVudENoaWxkLFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIC8vIGJlY2F1c2Ugd2Ugd29yayB3aXRoIGEgdGVtcGxhdGUgZWxlbWVudCwgd2UgbXVzdCBtYW51YWxseSBjb3B5IHRoZSBhdHRyaWJ1dGVzXG4gICAgLy8gb3RoZXJ3aXNlIHRoZSBvd25lciAvIHRhcmdldCBoZWxwZXJzIGRvbid0IHdvcmsgcHJvcGVybHlcbiAgICBjb25zdCByb290RWwgPSB0ZW1wbGF0ZS5jb250ZW50LmZpcnN0RWxlbWVudENoaWxkO1xuICAgIHJvb3RFbC5pZCA9IHRoaXMuaWQ7XG4gICAgcm9vdEVsLnNldEF0dHJpYnV0ZShQSFhfUk9PVF9JRCwgdGhpcy5yb290LmlkKTtcbiAgICByb290RWwuc2V0QXR0cmlidXRlKFBIWF9TRVNTSU9OLCB0aGlzLmdldFNlc3Npb24oKSk7XG4gICAgcm9vdEVsLnNldEF0dHJpYnV0ZShQSFhfU1RBVElDLCB0aGlzLmdldFN0YXRpYygpKTtcbiAgICByb290RWwuc2V0QXR0cmlidXRlKFBIWF9QQVJFTlRfSUQsIHRoaXMucGFyZW50ID8gdGhpcy5wYXJlbnQuaWQgOiBudWxsKTtcblxuICAgIC8vIHdlIGdvIG92ZXIgYWxsIGZvcm0gZWxlbWVudHMgaW4gdGhlIG5ldyBIVE1MIGZvciB0aGUgTFZcbiAgICAvLyBhbmQgbG9vayBmb3Igb2xkIGZvcm1zIGluIHRoZSBgZm9ybXNGb3JSZWNvdmVyeWAgb2JqZWN0O1xuICAgIC8vIHRoZSBmb3Jtc0ZvclJlY292ZXJ5IGNhbiBhbHNvIGNvbnRhaW4gZm9ybXMgZnJvbSBjaGlsZCB2aWV3c1xuICAgIGNvbnN0IGZvcm1zVG9SZWNvdmVyID1cbiAgICAgIC8vIHdlIGdvIG92ZXIgYWxsIGZvcm1zIGluIHRoZSBuZXcgRE9NOyBiZWNhdXNlIHRoaXMgaXMgb25seSB0aGUgSFRNTCBmb3IgdGhlIGN1cnJlbnRcbiAgICAgIC8vIHZpZXcsIHdlIGNhbiBiZSBzdXJlIHRoYXQgYWxsIGZvcm1zIGFyZSBvd25lZCBieSB0aGlzIHZpZXc6XG4gICAgICBET00uYWxsKHRlbXBsYXRlLmNvbnRlbnQsIFwiZm9ybVwiKVxuICAgICAgICAvLyBvbmx5IHJlY292ZXIgZm9ybXMgdGhhdCBoYXZlIGFuIGlkIGFuZCBhcmUgaW4gdGhlIG9sZCBET01cbiAgICAgICAgLmZpbHRlcigobmV3Rm9ybSkgPT4gbmV3Rm9ybS5pZCAmJiBvbGRGb3Jtc1tuZXdGb3JtLmlkXSlcbiAgICAgICAgLy8gYWJhbmRvbiBmb3JtcyB3ZSBhbHJlYWR5IHRyaWVkIHRvIHJlY292ZXIgdG8gcHJldmVudCBsb29waW5nIGEgZmFpbGVkIHN0YXRlXG4gICAgICAgIC5maWx0ZXIoKG5ld0Zvcm0pID0+ICF0aGlzLnBlbmRpbmdGb3Jtcy5oYXMobmV3Rm9ybS5pZCkpXG4gICAgICAgIC8vIG9ubHkgcmVjb3ZlciBpZiB0aGUgZm9ybSBoYXMgdGhlIHNhbWUgcGh4LWNoYW5nZSB2YWx1ZVxuICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgIChuZXdGb3JtKSA9PlxuICAgICAgICAgICAgb2xkRm9ybXNbbmV3Rm9ybS5pZF0uZ2V0QXR0cmlidXRlKHBoeENoYW5nZSkgPT09XG4gICAgICAgICAgICBuZXdGb3JtLmdldEF0dHJpYnV0ZShwaHhDaGFuZ2UpLFxuICAgICAgICApXG4gICAgICAgIC5tYXAoKG5ld0Zvcm0pID0+IHtcbiAgICAgICAgICByZXR1cm4gW29sZEZvcm1zW25ld0Zvcm0uaWRdLCBuZXdGb3JtXTtcbiAgICAgICAgfSk7XG5cbiAgICBpZiAoZm9ybXNUb1JlY292ZXIubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgICB9XG5cbiAgICBmb3Jtc1RvUmVjb3Zlci5mb3JFYWNoKChbb2xkRm9ybSwgbmV3Rm9ybV0sIGkpID0+IHtcbiAgICAgIHRoaXMucGVuZGluZ0Zvcm1zLmFkZChuZXdGb3JtLmlkKTtcbiAgICAgIC8vIGl0IGlzIGltcG9ydGFudCB0byB1c2UgdGhlIGZpcnN0RWxlbWVudENoaWxkIG9mIHRoZSB0ZW1wbGF0ZSBjb250ZW50XG4gICAgICAvLyBiZWNhdXNlIHdoZW4gdHJhdmVyc2luZyBhIGRvY3VtZW50RnJhZ21lbnQgdXNpbmcgcGFyZW50Tm9kZSwgd2Ugd29uJ3QgZXZlciBhcnJpdmUgYXRcbiAgICAgIC8vIHRoZSBmcmFnbWVudDsgYXMgdGhlIHRlbXBsYXRlIGlzIGFsd2F5cyBhIExpdmVWaWV3LCB3ZSBjYW4gYmUgc3VyZSB0aGF0IHRoZXJlIGlzIG9ubHlcbiAgICAgIC8vIG9uZSBjaGlsZCBvbiB0aGUgcm9vdCBsZXZlbFxuICAgICAgdGhpcy5wdXNoRm9ybVJlY292ZXJ5KFxuICAgICAgICBvbGRGb3JtLFxuICAgICAgICBuZXdGb3JtLFxuICAgICAgICB0ZW1wbGF0ZS5jb250ZW50LmZpcnN0RWxlbWVudENoaWxkLFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5wZW5kaW5nRm9ybXMuZGVsZXRlKG5ld0Zvcm0uaWQpO1xuICAgICAgICAgIC8vIHdlIG9ubHkgY2FsbCB0aGUgY2FsbGJhY2sgb25jZSBhbGwgZm9ybXMgaGF2ZSBiZWVuIHJlY292ZXJlZFxuICAgICAgICAgIGlmIChpID09PSBmb3Jtc1RvUmVjb3Zlci5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBnZXRDaGlsZEJ5SWQoaWQpIHtcbiAgICByZXR1cm4gdGhpcy5yb290LmNoaWxkcmVuW3RoaXMuaWRdW2lkXTtcbiAgfVxuXG4gIGdldERlc2NlbmRlbnRCeUVsKGVsKSB7XG4gICAgaWYgKGVsLmlkID09PSB0aGlzLmlkKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuY2hpbGRyZW5bZWwuZ2V0QXR0cmlidXRlKFBIWF9QQVJFTlRfSUQpXT8uW2VsLmlkXTtcbiAgICB9XG4gIH1cblxuICBkZXN0cm95RGVzY2VuZGVudChpZCkge1xuICAgIGZvciAoY29uc3QgcGFyZW50SWQgaW4gdGhpcy5yb290LmNoaWxkcmVuKSB7XG4gICAgICBmb3IgKGNvbnN0IGNoaWxkSWQgaW4gdGhpcy5yb290LmNoaWxkcmVuW3BhcmVudElkXSkge1xuICAgICAgICBpZiAoY2hpbGRJZCA9PT0gaWQpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5yb290LmNoaWxkcmVuW3BhcmVudElkXVtjaGlsZElkXS5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBqb2luQ2hpbGQoZWwpIHtcbiAgICBjb25zdCBjaGlsZCA9IHRoaXMuZ2V0Q2hpbGRCeUlkKGVsLmlkKTtcbiAgICBpZiAoIWNoaWxkKSB7XG4gICAgICBjb25zdCB2aWV3ID0gbmV3IFZpZXcoZWwsIHRoaXMubGl2ZVNvY2tldCwgdGhpcyk7XG4gICAgICB0aGlzLnJvb3QuY2hpbGRyZW5bdGhpcy5pZF1bdmlldy5pZF0gPSB2aWV3O1xuICAgICAgdmlldy5qb2luKCk7XG4gICAgICB0aGlzLmNoaWxkSm9pbnMrKztcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIGlzSm9pblBlbmRpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMuam9pblBlbmRpbmc7XG4gIH1cblxuICBhY2tKb2luKF9jaGlsZCkge1xuICAgIHRoaXMuY2hpbGRKb2lucy0tO1xuXG4gICAgaWYgKHRoaXMuY2hpbGRKb2lucyA9PT0gMCkge1xuICAgICAgaWYgKHRoaXMucGFyZW50KSB7XG4gICAgICAgIHRoaXMucGFyZW50LmFja0pvaW4odGhpcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm9uQWxsQ2hpbGRKb2luc0NvbXBsZXRlKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgb25BbGxDaGlsZEpvaW5zQ29tcGxldGUoKSB7XG4gICAgLy8gd2UgY2FuIGNsZWFyIHBlbmRpbmcgZm9ybSByZWNvdmVyaWVzIG5vdyB0aGF0IHdlJ3ZlIGpvaW5lZC5cbiAgICAvLyBUaGV5IGVpdGhlciBhbGwgcmVzb2x2ZWQgb3Igd2VyZSBhYmFuZG9uZWRcbiAgICB0aGlzLnBlbmRpbmdGb3Jtcy5jbGVhcigpO1xuICAgIC8vIHdlIGNhbiBhbHNvIGNsZWFyIHRoZSBmb3Jtc0ZvclJlY292ZXJ5IG9iamVjdCB0byBub3Qga2VlcCBvbGQgZm9ybSBlbGVtZW50cyBhcm91bmRcbiAgICB0aGlzLmZvcm1zRm9yUmVjb3ZlcnkgPSB7fTtcbiAgICB0aGlzLmpvaW5DYWxsYmFjaygoKSA9PiB7XG4gICAgICB0aGlzLnBlbmRpbmdKb2luT3BzLmZvckVhY2goKFt2aWV3LCBvcF0pID0+IHtcbiAgICAgICAgaWYgKCF2aWV3LmlzRGVzdHJveWVkKCkpIHtcbiAgICAgICAgICBvcCgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMucGVuZGluZ0pvaW5PcHMgPSBbXTtcbiAgICB9KTtcbiAgfVxuXG4gIHVwZGF0ZShkaWZmLCBldmVudHMsIGlzUGVuZGluZyA9IGZhbHNlKSB7XG4gICAgaWYgKFxuICAgICAgdGhpcy5pc0pvaW5QZW5kaW5nKCkgfHxcbiAgICAgICh0aGlzLmxpdmVTb2NrZXQuaGFzUGVuZGluZ0xpbmsoKSAmJiB0aGlzLnJvb3QuaXNNYWluKCkpXG4gICAgKSB7XG4gICAgICAvLyBkb24ndCBtdXRhdGUgaWYgdGhpcyBpcyBhbHJlYWR5IGEgcGVuZGluZyBkaWZmXG4gICAgICBpZiAoIWlzUGVuZGluZykge1xuICAgICAgICB0aGlzLnBlbmRpbmdEaWZmcy5wdXNoKHsgZGlmZiwgZXZlbnRzIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHRoaXMucmVuZGVyZWQubWVyZ2VEaWZmKGRpZmYpO1xuICAgIGxldCBwaHhDaGlsZHJlbkFkZGVkID0gZmFsc2U7XG5cbiAgICAvLyBXaGVuIHRoZSBkaWZmIG9ubHkgY29udGFpbnMgY29tcG9uZW50IGRpZmZzLCB0aGVuIHdhbGsgY29tcG9uZW50c1xuICAgIC8vIGFuZCBwYXRjaCBvbmx5IHRoZSBwYXJlbnQgY29tcG9uZW50IGNvbnRhaW5lcnMgZm91bmQgaW4gdGhlIGRpZmYuXG4gICAgLy8gT3RoZXJ3aXNlLCBwYXRjaCBlbnRpcmUgTFYgY29udGFpbmVyLlxuICAgIGlmICh0aGlzLnJlbmRlcmVkLmlzQ29tcG9uZW50T25seURpZmYoZGlmZikpIHtcbiAgICAgIHRoaXMubGl2ZVNvY2tldC50aW1lKFwiY29tcG9uZW50IHBhdGNoIGNvbXBsZXRlXCIsICgpID0+IHtcbiAgICAgICAgY29uc3QgcGFyZW50Q2lkcyA9IERPTS5maW5kRXhpc3RpbmdQYXJlbnRDSURzKFxuICAgICAgICAgIHRoaXMuaWQsXG4gICAgICAgICAgdGhpcy5yZW5kZXJlZC5jb21wb25lbnRDSURzKGRpZmYpLFxuICAgICAgICApO1xuICAgICAgICBwYXJlbnRDaWRzLmZvckVhY2goKHBhcmVudENJRCkgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMuY29tcG9uZW50UGF0Y2goXG4gICAgICAgICAgICAgIHRoaXMucmVuZGVyZWQuZ2V0Q29tcG9uZW50KGRpZmYsIHBhcmVudENJRCksXG4gICAgICAgICAgICAgIHBhcmVudENJRCxcbiAgICAgICAgICAgIClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHBoeENoaWxkcmVuQWRkZWQgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKCFpc0VtcHR5KGRpZmYpKSB7XG4gICAgICB0aGlzLmxpdmVTb2NrZXQudGltZShcImZ1bGwgcGF0Y2ggY29tcGxldGVcIiwgKCkgPT4ge1xuICAgICAgICBjb25zdCBbaHRtbCwgc3RyZWFtc10gPSB0aGlzLnJlbmRlckNvbnRhaW5lcihkaWZmLCBcInVwZGF0ZVwiKTtcbiAgICAgICAgY29uc3QgcGF0Y2ggPSBuZXcgRE9NUGF0Y2godGhpcywgdGhpcy5lbCwgdGhpcy5pZCwgaHRtbCwgc3RyZWFtcywgbnVsbCk7XG4gICAgICAgIHBoeENoaWxkcmVuQWRkZWQgPSB0aGlzLnBlcmZvcm1QYXRjaChwYXRjaCwgdHJ1ZSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmxpdmVTb2NrZXQuZGlzcGF0Y2hFdmVudHMoZXZlbnRzKTtcbiAgICBpZiAocGh4Q2hpbGRyZW5BZGRlZCkge1xuICAgICAgdGhpcy5qb2luTmV3Q2hpbGRyZW4oKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJlbmRlckNvbnRhaW5lcihkaWZmLCBraW5kKSB7XG4gICAgcmV0dXJuIHRoaXMubGl2ZVNvY2tldC50aW1lKGB0b1N0cmluZyBkaWZmICgke2tpbmR9KWAsICgpID0+IHtcbiAgICAgIGNvbnN0IHRhZyA9IHRoaXMuZWwudGFnTmFtZTtcbiAgICAgIC8vIERvbid0IHNraXAgYW55IGNvbXBvbmVudCBpbiB0aGUgZGlmZiBub3IgYW55IG1hcmtlZCBhcyBwcnVuZWRcbiAgICAgIC8vIChhcyB0aGV5IG1heSBoYXZlIGJlZW4gYWRkZWQgYmFjaylcbiAgICAgIGNvbnN0IGNpZHMgPSBkaWZmID8gdGhpcy5yZW5kZXJlZC5jb21wb25lbnRDSURzKGRpZmYpIDogbnVsbDtcbiAgICAgIGNvbnN0IHsgYnVmZmVyOiBodG1sLCBzdHJlYW1zIH0gPSB0aGlzLnJlbmRlcmVkLnRvU3RyaW5nKGNpZHMpO1xuICAgICAgcmV0dXJuIFtgPCR7dGFnfT4ke2h0bWx9PC8ke3RhZ30+YCwgc3RyZWFtc107XG4gICAgfSk7XG4gIH1cblxuICBjb21wb25lbnRQYXRjaChkaWZmLCBjaWQpIHtcbiAgICBpZiAoaXNFbXB0eShkaWZmKSkgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IHsgYnVmZmVyOiBodG1sLCBzdHJlYW1zIH0gPSB0aGlzLnJlbmRlcmVkLmNvbXBvbmVudFRvU3RyaW5nKGNpZCk7XG4gICAgY29uc3QgcGF0Y2ggPSBuZXcgRE9NUGF0Y2godGhpcywgdGhpcy5lbCwgdGhpcy5pZCwgaHRtbCwgc3RyZWFtcywgY2lkKTtcbiAgICBjb25zdCBjaGlsZHJlbkFkZGVkID0gdGhpcy5wZXJmb3JtUGF0Y2gocGF0Y2gsIHRydWUpO1xuICAgIHJldHVybiBjaGlsZHJlbkFkZGVkO1xuICB9XG5cbiAgZ2V0SG9vayhlbCkge1xuICAgIHJldHVybiB0aGlzLnZpZXdIb29rc1tWaWV3SG9vay5lbGVtZW50SUQoZWwpXTtcbiAgfVxuXG4gIGFkZEhvb2soZWwpIHtcbiAgICBjb25zdCBob29rRWxJZCA9IFZpZXdIb29rLmVsZW1lbnRJRChlbCk7XG5cbiAgICAvLyBvbmx5IGV2ZXIgdHJ5IHRvIGFkZCBob29rcyB0byBlbGVtZW50cyBvd25lZCBieSB0aGlzIHZpZXdcbiAgICBpZiAoZWwuZ2V0QXR0cmlidXRlICYmICF0aGlzLm93bnNFbGVtZW50KGVsKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChob29rRWxJZCAmJiAhdGhpcy52aWV3SG9va3NbaG9va0VsSWRdKSB7XG4gICAgICAvLyBob29rIGNyZWF0ZWQsIGJ1dCBub3QgYXR0YWNoZWQgKGNyZWF0ZUhvb2sgZm9yIHdlYiBjb21wb25lbnQpXG4gICAgICBjb25zdCBob29rID1cbiAgICAgICAgRE9NLmdldEN1c3RvbUVsSG9vayhlbCkgfHxcbiAgICAgICAgbG9nRXJyb3IoYG5vIGhvb2sgZm91bmQgZm9yIGN1c3RvbSBlbGVtZW50OiAke2VsLmlkfWApO1xuICAgICAgdGhpcy52aWV3SG9va3NbaG9va0VsSWRdID0gaG9vaztcbiAgICAgIGhvb2suX19hdHRhY2hWaWV3KHRoaXMpO1xuICAgICAgcmV0dXJuIGhvb2s7XG4gICAgfSBlbHNlIGlmIChob29rRWxJZCB8fCAhZWwuZ2V0QXR0cmlidXRlKSB7XG4gICAgICAvLyBubyBob29rIGZvdW5kXG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIG5ldyBob29rIGZvdW5kIHdpdGggcGh4LWhvb2sgYXR0cmlidXRlXG4gICAgICBjb25zdCBob29rTmFtZSA9XG4gICAgICAgIGVsLmdldEF0dHJpYnV0ZShgZGF0YS1waHgtJHtQSFhfSE9PS31gKSB8fFxuICAgICAgICBlbC5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFBIWF9IT09LKSk7XG5cbiAgICAgIGlmICghaG9va05hbWUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBob29rRGVmaW5pdGlvbiA9IHRoaXMubGl2ZVNvY2tldC5nZXRIb29rRGVmaW5pdGlvbihob29rTmFtZSk7XG5cbiAgICAgIGlmIChob29rRGVmaW5pdGlvbikge1xuICAgICAgICBpZiAoIWVsLmlkKSB7XG4gICAgICAgICAgbG9nRXJyb3IoXG4gICAgICAgICAgICBgbm8gRE9NIElEIGZvciBob29rIFwiJHtob29rTmFtZX1cIi4gSG9va3MgcmVxdWlyZSBhIHVuaXF1ZSBJRCBvbiBlYWNoIGVsZW1lbnQuYCxcbiAgICAgICAgICAgIGVsLFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGhvb2tJbnN0YW5jZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB0eXBlb2YgaG9va0RlZmluaXRpb24gPT09IFwiZnVuY3Rpb25cIiAmJlxuICAgICAgICAgICAgaG9va0RlZmluaXRpb24ucHJvdG90eXBlIGluc3RhbmNlb2YgVmlld0hvb2tcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIC8vIEl0J3MgYSBjbGFzcyBjb25zdHJ1Y3RvciAoc3ViY2xhc3Mgb2YgVmlld0hvb2spXG4gICAgICAgICAgICBob29rSW5zdGFuY2UgPSBuZXcgaG9va0RlZmluaXRpb24odGhpcywgZWwpOyAvLyBgdGhpc2AgaXMgdGhlIFZpZXcgaW5zdGFuY2VcbiAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgdHlwZW9mIGhvb2tEZWZpbml0aW9uID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgICAgICBob29rRGVmaW5pdGlvbiAhPT0gbnVsbFxuICAgICAgICAgICkge1xuICAgICAgICAgICAgLy8gSXQncyBhbiBvYmplY3QgbGl0ZXJhbCwgcGFzcyBpdCB0byB0aGUgVmlld0hvb2sgY29uc3RydWN0b3IgZm9yIHdyYXBwaW5nXG4gICAgICAgICAgICBob29rSW5zdGFuY2UgPSBuZXcgVmlld0hvb2sodGhpcywgZWwsIGhvb2tEZWZpbml0aW9uKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9nRXJyb3IoXG4gICAgICAgICAgICAgIGBJbnZhbGlkIGhvb2sgZGVmaW5pdGlvbiBmb3IgXCIke2hvb2tOYW1lfVwiLiBFeHBlY3RlZCBhIGNsYXNzIGV4dGVuZGluZyBWaWV3SG9vayBvciBhbiBvYmplY3QgZGVmaW5pdGlvbi5gLFxuICAgICAgICAgICAgICBlbCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZSBpbnN0YW5jZW9mIEVycm9yID8gZS5tZXNzYWdlIDogU3RyaW5nKGUpO1xuICAgICAgICAgIGxvZ0Vycm9yKGBGYWlsZWQgdG8gY3JlYXRlIGhvb2sgXCIke2hvb2tOYW1lfVwiOiAke2Vycm9yTWVzc2FnZX1gLCBlbCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWV3SG9va3NbVmlld0hvb2suZWxlbWVudElEKGhvb2tJbnN0YW5jZS5lbCldID0gaG9va0luc3RhbmNlO1xuICAgICAgICByZXR1cm4gaG9va0luc3RhbmNlO1xuICAgICAgfSBlbHNlIGlmIChob29rTmFtZSAhPT0gbnVsbCkge1xuICAgICAgICBsb2dFcnJvcihgdW5rbm93biBob29rIGZvdW5kIGZvciBcIiR7aG9va05hbWV9XCJgLCBlbCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZGVzdHJveUhvb2soaG9vaykge1xuICAgIC8vIF9fZGVzdHJveWVkIGNsZWFycyB0aGUgZWxlbWVudElEIGZyb20gdGhlIGhvb2ssIHRoZXJlZm9yZVxuICAgIC8vIHdlIG5lZWQgdG8gZ2V0IGl0IGJlZm9yZSBjYWxsaW5nIF9fZGVzdHJveWVkXG4gICAgY29uc3QgaG9va0lkID0gVmlld0hvb2suZWxlbWVudElEKGhvb2suZWwpO1xuICAgIGhvb2suX19kZXN0cm95ZWQoKTtcbiAgICBob29rLl9fY2xlYW51cF9fKCk7XG4gICAgZGVsZXRlIHRoaXMudmlld0hvb2tzW2hvb2tJZF07XG4gIH1cblxuICBhcHBseVBlbmRpbmdVcGRhdGVzKCkge1xuICAgIC8vIFRvIHByZXZlbnQgcmFjZSBjb25kaXRpb25zIHdoZXJlIHdlIG1pZ2h0IHN0aWxsIGJlIHBlbmRpbmcgYSBuZXdcbiAgICAvLyBuYXZpZ2F0aW9uIG9yIHRoZSBqb2luIGlzIHN0aWxsIHBlbmRpbmcsIGB0aGlzLnVwZGF0ZWAgcmV0dXJucyBmYWxzZVxuICAgIC8vIGlmIHRoZSBkaWZmIHdhcyBub3QgYXBwbGllZC5cbiAgICB0aGlzLnBlbmRpbmdEaWZmcyA9IHRoaXMucGVuZGluZ0RpZmZzLmZpbHRlcihcbiAgICAgICh7IGRpZmYsIGV2ZW50cyB9KSA9PiAhdGhpcy51cGRhdGUoZGlmZiwgZXZlbnRzLCB0cnVlKSxcbiAgICApO1xuICAgIHRoaXMuZWFjaENoaWxkKChjaGlsZCkgPT4gY2hpbGQuYXBwbHlQZW5kaW5nVXBkYXRlcygpKTtcbiAgfVxuXG4gIGVhY2hDaGlsZChjYWxsYmFjaykge1xuICAgIGNvbnN0IGNoaWxkcmVuID0gdGhpcy5yb290LmNoaWxkcmVuW3RoaXMuaWRdIHx8IHt9O1xuICAgIGZvciAoY29uc3QgaWQgaW4gY2hpbGRyZW4pIHtcbiAgICAgIGNhbGxiYWNrKHRoaXMuZ2V0Q2hpbGRCeUlkKGlkKSk7XG4gICAgfVxuICB9XG5cbiAgb25DaGFubmVsKGV2ZW50LCBjYikge1xuICAgIHRoaXMubGl2ZVNvY2tldC5vbkNoYW5uZWwodGhpcy5jaGFubmVsLCBldmVudCwgKHJlc3ApID0+IHtcbiAgICAgIGlmICh0aGlzLmlzSm9pblBlbmRpbmcoKSkge1xuICAgICAgICAvLyBpbiBjYXNlIHRoaXMgaXMgYSByZWpvaW4gKGpvaW5Db3VudCA+IDEpIHdlIHN0b3JlIG91ciBvd24gam9pbiBvcHNcbiAgICAgICAgaWYgKHRoaXMuam9pbkNvdW50ID4gMSkge1xuICAgICAgICAgIHRoaXMucGVuZGluZ0pvaW5PcHMucHVzaCgoKSA9PiBjYihyZXNwKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5yb290LnBlbmRpbmdKb2luT3BzLnB1c2goW3RoaXMsICgpID0+IGNiKHJlc3ApXSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubGl2ZVNvY2tldC5yZXF1ZXN0RE9NVXBkYXRlKCgpID0+IGNiKHJlc3ApKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGJpbmRDaGFubmVsKCkge1xuICAgIC8vIFRoZSBkaWZmIGV2ZW50IHNob3VsZCBiZSBoYW5kbGVkIGJ5IHRoZSByZWd1bGFyIHVwZGF0ZSBvcGVyYXRpb25zLlxuICAgIC8vIEFsbCBvdGhlciBvcGVyYXRpb25zIGFyZSBxdWV1ZWQgdG8gYmUgYXBwbGllZCBvbmx5IGFmdGVyIGpvaW4uXG4gICAgdGhpcy5saXZlU29ja2V0Lm9uQ2hhbm5lbCh0aGlzLmNoYW5uZWwsIFwiZGlmZlwiLCAocmF3RGlmZikgPT4ge1xuICAgICAgdGhpcy5saXZlU29ja2V0LnJlcXVlc3RET01VcGRhdGUoKCkgPT4ge1xuICAgICAgICB0aGlzLmFwcGx5RGlmZihcInVwZGF0ZVwiLCByYXdEaWZmLCAoeyBkaWZmLCBldmVudHMgfSkgPT5cbiAgICAgICAgICB0aGlzLnVwZGF0ZShkaWZmLCBldmVudHMpLFxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgdGhpcy5vbkNoYW5uZWwoXCJyZWRpcmVjdFwiLCAoeyB0bywgZmxhc2ggfSkgPT5cbiAgICAgIHRoaXMub25SZWRpcmVjdCh7IHRvLCBmbGFzaCB9KSxcbiAgICApO1xuICAgIHRoaXMub25DaGFubmVsKFwibGl2ZV9wYXRjaFwiLCAocmVkaXIpID0+IHRoaXMub25MaXZlUGF0Y2gocmVkaXIpKTtcbiAgICB0aGlzLm9uQ2hhbm5lbChcImxpdmVfcmVkaXJlY3RcIiwgKHJlZGlyKSA9PiB0aGlzLm9uTGl2ZVJlZGlyZWN0KHJlZGlyKSk7XG4gICAgdGhpcy5jaGFubmVsLm9uRXJyb3IoKHJlYXNvbikgPT4gdGhpcy5vbkVycm9yKHJlYXNvbikpO1xuICAgIHRoaXMuY2hhbm5lbC5vbkNsb3NlKChyZWFzb24pID0+IHRoaXMub25DbG9zZShyZWFzb24pKTtcbiAgfVxuXG4gIGRlc3Ryb3lBbGxDaGlsZHJlbigpIHtcbiAgICB0aGlzLmVhY2hDaGlsZCgoY2hpbGQpID0+IGNoaWxkLmRlc3Ryb3koKSk7XG4gIH1cblxuICBvbkxpdmVSZWRpcmVjdChyZWRpcikge1xuICAgIGNvbnN0IHsgdG8sIGtpbmQsIGZsYXNoIH0gPSByZWRpcjtcbiAgICBjb25zdCB1cmwgPSB0aGlzLmV4cGFuZFVSTCh0byk7XG4gICAgY29uc3QgZSA9IG5ldyBDdXN0b21FdmVudChcInBoeDpzZXJ2ZXItbmF2aWdhdGVcIiwge1xuICAgICAgZGV0YWlsOiB7IHRvLCBraW5kLCBmbGFzaCB9LFxuICAgIH0pO1xuICAgIHRoaXMubGl2ZVNvY2tldC5oaXN0b3J5UmVkaXJlY3QoZSwgdXJsLCBraW5kLCBmbGFzaCk7XG4gIH1cblxuICBvbkxpdmVQYXRjaChyZWRpcikge1xuICAgIGNvbnN0IHsgdG8sIGtpbmQgfSA9IHJlZGlyO1xuICAgIHRoaXMuaHJlZiA9IHRoaXMuZXhwYW5kVVJMKHRvKTtcbiAgICB0aGlzLmxpdmVTb2NrZXQuaGlzdG9yeVBhdGNoKHRvLCBraW5kKTtcbiAgfVxuXG4gIGV4cGFuZFVSTCh0bykge1xuICAgIHJldHVybiB0by5zdGFydHNXaXRoKFwiL1wiKVxuICAgICAgPyBgJHt3aW5kb3cubG9jYXRpb24ucHJvdG9jb2x9Ly8ke3dpbmRvdy5sb2NhdGlvbi5ob3N0fSR7dG99YFxuICAgICAgOiB0bztcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3t0bzogc3RyaW5nLCBmbGFzaD86IHN0cmluZywgcmVsb2FkVG9rZW4/OiBzdHJpbmd9fSByZWRpcmVjdFxuICAgKi9cbiAgb25SZWRpcmVjdCh7IHRvLCBmbGFzaCwgcmVsb2FkVG9rZW4gfSkge1xuICAgIHRoaXMubGl2ZVNvY2tldC5yZWRpcmVjdCh0bywgZmxhc2gsIHJlbG9hZFRva2VuKTtcbiAgfVxuXG4gIGlzRGVzdHJveWVkKCkge1xuICAgIHJldHVybiB0aGlzLmRlc3Ryb3llZDtcbiAgfVxuXG4gIGpvaW5EZWFkKCkge1xuICAgIHRoaXMuaXNEZWFkID0gdHJ1ZTtcbiAgfVxuXG4gIGpvaW5QdXNoKCkge1xuICAgIHRoaXMuam9pblB1c2ggPSB0aGlzLmpvaW5QdXNoIHx8IHRoaXMuY2hhbm5lbC5qb2luKCk7XG4gICAgcmV0dXJuIHRoaXMuam9pblB1c2g7XG4gIH1cblxuICBqb2luKGNhbGxiYWNrKSB7XG4gICAgdGhpcy5zaG93TG9hZGVyKHRoaXMubGl2ZVNvY2tldC5sb2FkZXJUaW1lb3V0KTtcbiAgICB0aGlzLmJpbmRDaGFubmVsKCk7XG4gICAgaWYgKHRoaXMuaXNNYWluKCkpIHtcbiAgICAgIHRoaXMuc3RvcENhbGxiYWNrID0gdGhpcy5saXZlU29ja2V0LndpdGhQYWdlTG9hZGluZyh7XG4gICAgICAgIHRvOiB0aGlzLmhyZWYsXG4gICAgICAgIGtpbmQ6IFwiaW5pdGlhbFwiLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuam9pbkNhbGxiYWNrID0gKG9uRG9uZSkgPT4ge1xuICAgICAgb25Eb25lID0gb25Eb25lIHx8IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgY2FsbGJhY2sgPyBjYWxsYmFjayh0aGlzLmpvaW5Db3VudCwgb25Eb25lKSA6IG9uRG9uZSgpO1xuICAgIH07XG5cbiAgICB0aGlzLndyYXBQdXNoKCgpID0+IHRoaXMuY2hhbm5lbC5qb2luKCksIHtcbiAgICAgIG9rOiAocmVzcCkgPT4gdGhpcy5saXZlU29ja2V0LnJlcXVlc3RET01VcGRhdGUoKCkgPT4gdGhpcy5vbkpvaW4ocmVzcCkpLFxuICAgICAgZXJyb3I6IChlcnJvcikgPT4gdGhpcy5vbkpvaW5FcnJvcihlcnJvciksXG4gICAgICB0aW1lb3V0OiAoKSA9PiB0aGlzLm9uSm9pbkVycm9yKHsgcmVhc29uOiBcInRpbWVvdXRcIiB9KSxcbiAgICB9KTtcbiAgfVxuXG4gIG9uSm9pbkVycm9yKHJlc3ApIHtcbiAgICBpZiAocmVzcC5yZWFzb24gPT09IFwicmVsb2FkXCIpIHtcbiAgICAgIHRoaXMubG9nKFwiZXJyb3JcIiwgKCkgPT4gW1xuICAgICAgICBgZmFpbGVkIG1vdW50IHdpdGggJHtyZXNwLnN0YXR1c30uIEZhbGxpbmcgYmFjayB0byBwYWdlIHJlbG9hZGAsXG4gICAgICAgIHJlc3AsXG4gICAgICBdKTtcbiAgICAgIHRoaXMub25SZWRpcmVjdCh7IHRvOiB0aGlzLnJvb3QuaHJlZiwgcmVsb2FkVG9rZW46IHJlc3AudG9rZW4gfSk7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIGlmIChyZXNwLnJlYXNvbiA9PT0gXCJ1bmF1dGhvcml6ZWRcIiB8fCByZXNwLnJlYXNvbiA9PT0gXCJzdGFsZVwiKSB7XG4gICAgICB0aGlzLmxvZyhcImVycm9yXCIsICgpID0+IFtcbiAgICAgICAgXCJ1bmF1dGhvcml6ZWQgbGl2ZV9yZWRpcmVjdC4gRmFsbGluZyBiYWNrIHRvIHBhZ2UgcmVxdWVzdFwiLFxuICAgICAgICByZXNwLFxuICAgICAgXSk7XG4gICAgICB0aGlzLm9uUmVkaXJlY3QoeyB0bzogdGhpcy5yb290LmhyZWYsIGZsYXNoOiB0aGlzLmZsYXNoIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAocmVzcC5yZWRpcmVjdCB8fCByZXNwLmxpdmVfcmVkaXJlY3QpIHtcbiAgICAgIHRoaXMuam9pblBlbmRpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuY2hhbm5lbC5sZWF2ZSgpO1xuICAgIH1cbiAgICBpZiAocmVzcC5yZWRpcmVjdCkge1xuICAgICAgcmV0dXJuIHRoaXMub25SZWRpcmVjdChyZXNwLnJlZGlyZWN0KTtcbiAgICB9XG4gICAgaWYgKHJlc3AubGl2ZV9yZWRpcmVjdCkge1xuICAgICAgcmV0dXJuIHRoaXMub25MaXZlUmVkaXJlY3QocmVzcC5saXZlX3JlZGlyZWN0KTtcbiAgICB9XG4gICAgdGhpcy5sb2coXCJlcnJvclwiLCAoKSA9PiBbXCJ1bmFibGUgdG8gam9pblwiLCByZXNwXSk7XG4gICAgaWYgKHRoaXMuaXNNYWluKCkpIHtcbiAgICAgIHRoaXMuZGlzcGxheUVycm9yKFxuICAgICAgICBbUEhYX0xPQURJTkdfQ0xBU1MsIFBIWF9FUlJPUl9DTEFTUywgUEhYX1NFUlZFUl9FUlJPUl9DTEFTU10sXG4gICAgICAgIHsgdW5zdHJ1Y3R1cmVkRXJyb3I6IHJlc3AsIGVycm9yS2luZDogXCJzZXJ2ZXJcIiB9LFxuICAgICAgKTtcbiAgICAgIGlmICh0aGlzLmxpdmVTb2NrZXQuaXNDb25uZWN0ZWQoKSkge1xuICAgICAgICB0aGlzLmxpdmVTb2NrZXQucmVsb2FkV2l0aEppdHRlcih0aGlzKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMuam9pbkF0dGVtcHRzID49IE1BWF9DSElMRF9KT0lOX0FUVEVNUFRTKSB7XG4gICAgICAgIC8vIHB1dCB0aGUgcm9vdCByZXZpZXcgaW50byBwZXJtYW5lbnQgZXJyb3Igc3RhdGUsIGJ1dCBkb24ndCBkZXN0cm95IGl0IGFzIGl0IGNhbiByZW1haW4gYWN0aXZlXG4gICAgICAgIHRoaXMucm9vdC5kaXNwbGF5RXJyb3IoXG4gICAgICAgICAgW1BIWF9MT0FESU5HX0NMQVNTLCBQSFhfRVJST1JfQ0xBU1MsIFBIWF9TRVJWRVJfRVJST1JfQ0xBU1NdLFxuICAgICAgICAgIHsgdW5zdHJ1Y3R1cmVkRXJyb3I6IHJlc3AsIGVycm9yS2luZDogXCJzZXJ2ZXJcIiB9LFxuICAgICAgICApO1xuICAgICAgICB0aGlzLmxvZyhcImVycm9yXCIsICgpID0+IFtcbiAgICAgICAgICBgZ2l2aW5nIHVwIHRyeWluZyB0byBtb3VudCBhZnRlciAke01BWF9DSElMRF9KT0lOX0FUVEVNUFRTfSB0cmllc2AsXG4gICAgICAgICAgcmVzcCxcbiAgICAgICAgXSk7XG4gICAgICAgIHRoaXMuZGVzdHJveSgpO1xuICAgICAgfVxuICAgICAgY29uc3QgdHJ1ZUNoaWxkRWwgPSBET00uYnlJZCh0aGlzLmVsLmlkKTtcbiAgICAgIGlmICh0cnVlQ2hpbGRFbCkge1xuICAgICAgICBET00ubWVyZ2VBdHRycyh0cnVlQ2hpbGRFbCwgdGhpcy5lbCk7XG4gICAgICAgIHRoaXMuZGlzcGxheUVycm9yKFxuICAgICAgICAgIFtQSFhfTE9BRElOR19DTEFTUywgUEhYX0VSUk9SX0NMQVNTLCBQSFhfU0VSVkVSX0VSUk9SX0NMQVNTXSxcbiAgICAgICAgICB7IHVuc3RydWN0dXJlZEVycm9yOiByZXNwLCBlcnJvcktpbmQ6IFwic2VydmVyXCIgfSxcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5lbCA9IHRydWVDaGlsZEVsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5kZXN0cm95KCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgb25DbG9zZShyZWFzb24pIHtcbiAgICBpZiAodGhpcy5pc0Rlc3Ryb3llZCgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChcbiAgICAgIHRoaXMuaXNNYWluKCkgJiZcbiAgICAgIHRoaXMubGl2ZVNvY2tldC5oYXNQZW5kaW5nTGluaygpICYmXG4gICAgICByZWFzb24gIT09IFwibGVhdmVcIlxuICAgICkge1xuICAgICAgcmV0dXJuIHRoaXMubGl2ZVNvY2tldC5yZWxvYWRXaXRoSml0dGVyKHRoaXMpO1xuICAgIH1cbiAgICB0aGlzLmRlc3Ryb3lBbGxDaGlsZHJlbigpO1xuICAgIHRoaXMubGl2ZVNvY2tldC5kcm9wQWN0aXZlRWxlbWVudCh0aGlzKTtcbiAgICBpZiAodGhpcy5saXZlU29ja2V0LmlzVW5sb2FkZWQoKSkge1xuICAgICAgdGhpcy5zaG93TG9hZGVyKEJFRk9SRV9VTkxPQURfTE9BREVSX1RJTUVPVVQpO1xuICAgIH1cbiAgfVxuXG4gIG9uRXJyb3IocmVhc29uKSB7XG4gICAgdGhpcy5vbkNsb3NlKHJlYXNvbik7XG4gICAgaWYgKHRoaXMubGl2ZVNvY2tldC5pc0Nvbm5lY3RlZCgpKSB7XG4gICAgICB0aGlzLmxvZyhcImVycm9yXCIsICgpID0+IFtcInZpZXcgY3Jhc2hlZFwiLCByZWFzb25dKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmxpdmVTb2NrZXQuaXNVbmxvYWRlZCgpKSB7XG4gICAgICBpZiAodGhpcy5saXZlU29ja2V0LmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgdGhpcy5kaXNwbGF5RXJyb3IoXG4gICAgICAgICAgW1BIWF9MT0FESU5HX0NMQVNTLCBQSFhfRVJST1JfQ0xBU1MsIFBIWF9TRVJWRVJfRVJST1JfQ0xBU1NdLFxuICAgICAgICAgIHsgdW5zdHJ1Y3R1cmVkRXJyb3I6IHJlYXNvbiwgZXJyb3JLaW5kOiBcInNlcnZlclwiIH0sXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmRpc3BsYXlFcnJvcihcbiAgICAgICAgICBbUEhYX0xPQURJTkdfQ0xBU1MsIFBIWF9FUlJPUl9DTEFTUywgUEhYX0NMSUVOVF9FUlJPUl9DTEFTU10sXG4gICAgICAgICAgeyB1bnN0cnVjdHVyZWRFcnJvcjogcmVhc29uLCBlcnJvcktpbmQ6IFwiY2xpZW50XCIgfSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBkaXNwbGF5RXJyb3IoY2xhc3NlcywgZGV0YWlscyA9IHt9KSB7XG4gICAgaWYgKHRoaXMuaXNNYWluKCkpIHtcbiAgICAgIERPTS5kaXNwYXRjaEV2ZW50KHdpbmRvdywgXCJwaHg6cGFnZS1sb2FkaW5nLXN0YXJ0XCIsIHtcbiAgICAgICAgZGV0YWlsOiB7IHRvOiB0aGlzLmhyZWYsIGtpbmQ6IFwiZXJyb3JcIiwgLi4uZGV0YWlscyB9LFxuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuc2hvd0xvYWRlcigpO1xuICAgIHRoaXMuc2V0Q29udGFpbmVyQ2xhc3NlcyguLi5jbGFzc2VzKTtcbiAgICB0aGlzLmRlbGF5ZWREaXNjb25uZWN0ZWQoKTtcbiAgfVxuXG4gIGRlbGF5ZWREaXNjb25uZWN0ZWQoKSB7XG4gICAgdGhpcy5kaXNjb25uZWN0ZWRUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5leGVjQWxsKHRoaXMuYmluZGluZyhcImRpc2Nvbm5lY3RlZFwiKSk7XG4gICAgfSwgdGhpcy5saXZlU29ja2V0LmRpc2Nvbm5lY3RlZFRpbWVvdXQpO1xuICB9XG5cbiAgd3JhcFB1c2goY2FsbGVyUHVzaCwgcmVjZWl2ZXMpIHtcbiAgICBjb25zdCBsYXRlbmN5ID0gdGhpcy5saXZlU29ja2V0LmdldExhdGVuY3lTaW0oKTtcbiAgICBjb25zdCB3aXRoTGF0ZW5jeSA9IGxhdGVuY3lcbiAgICAgID8gKGNiKSA9PiBzZXRUaW1lb3V0KCgpID0+ICF0aGlzLmlzRGVzdHJveWVkKCkgJiYgY2IoKSwgbGF0ZW5jeSlcbiAgICAgIDogKGNiKSA9PiAhdGhpcy5pc0Rlc3Ryb3llZCgpICYmIGNiKCk7XG5cbiAgICB3aXRoTGF0ZW5jeSgoKSA9PiB7XG4gICAgICBjYWxsZXJQdXNoKClcbiAgICAgICAgLnJlY2VpdmUoXCJva1wiLCAocmVzcCkgPT5cbiAgICAgICAgICB3aXRoTGF0ZW5jeSgoKSA9PiByZWNlaXZlcy5vayAmJiByZWNlaXZlcy5vayhyZXNwKSksXG4gICAgICAgIClcbiAgICAgICAgLnJlY2VpdmUoXCJlcnJvclwiLCAocmVhc29uKSA9PlxuICAgICAgICAgIHdpdGhMYXRlbmN5KCgpID0+IHJlY2VpdmVzLmVycm9yICYmIHJlY2VpdmVzLmVycm9yKHJlYXNvbikpLFxuICAgICAgICApXG4gICAgICAgIC5yZWNlaXZlKFwidGltZW91dFwiLCAoKSA9PlxuICAgICAgICAgIHdpdGhMYXRlbmN5KCgpID0+IHJlY2VpdmVzLnRpbWVvdXQgJiYgcmVjZWl2ZXMudGltZW91dCgpKSxcbiAgICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1c2hXaXRoUmVwbHkocmVmR2VuZXJhdG9yLCBldmVudCwgcGF5bG9hZCkge1xuICAgIGlmICghdGhpcy5pc0Nvbm5lY3RlZCgpKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwibm8gY29ubmVjdGlvblwiKSk7XG4gICAgfVxuXG4gICAgY29uc3QgW3JlZiwgW2VsXSwgb3B0c10gPSByZWZHZW5lcmF0b3JcbiAgICAgID8gcmVmR2VuZXJhdG9yKHsgcGF5bG9hZCB9KVxuICAgICAgOiBbbnVsbCwgW10sIHt9XTtcbiAgICBjb25zdCBvbGRKb2luQ291bnQgPSB0aGlzLmpvaW5Db3VudDtcbiAgICBsZXQgb25Mb2FkaW5nRG9uZSA9IGZ1bmN0aW9uICgpIHt9O1xuICAgIGlmIChvcHRzLnBhZ2VfbG9hZGluZykge1xuICAgICAgb25Mb2FkaW5nRG9uZSA9IHRoaXMubGl2ZVNvY2tldC53aXRoUGFnZUxvYWRpbmcoe1xuICAgICAgICBraW5kOiBcImVsZW1lbnRcIixcbiAgICAgICAgdGFyZ2V0OiBlbCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgcGF5bG9hZC5jaWQgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgIGRlbGV0ZSBwYXlsb2FkLmNpZDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy53cmFwUHVzaCgoKSA9PiB0aGlzLmNoYW5uZWwucHVzaChldmVudCwgcGF5bG9hZCwgUFVTSF9USU1FT1VUKSwge1xuICAgICAgICBvazogKHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVmICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmxhc3RBY2tSZWYgPSByZWY7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGZpbmlzaCA9IChob29rUmVwbHkpID0+IHtcbiAgICAgICAgICAgIGlmIChyZXNwLnJlZGlyZWN0KSB7XG4gICAgICAgICAgICAgIHRoaXMub25SZWRpcmVjdChyZXNwLnJlZGlyZWN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZXNwLmxpdmVfcGF0Y2gpIHtcbiAgICAgICAgICAgICAgdGhpcy5vbkxpdmVQYXRjaChyZXNwLmxpdmVfcGF0Y2gpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHJlc3AubGl2ZV9yZWRpcmVjdCkge1xuICAgICAgICAgICAgICB0aGlzLm9uTGl2ZVJlZGlyZWN0KHJlc3AubGl2ZV9yZWRpcmVjdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvbkxvYWRpbmdEb25lKCk7XG4gICAgICAgICAgICByZXNvbHZlKHsgcmVzcDogcmVzcCwgcmVwbHk6IGhvb2tSZXBseSwgcmVmIH0pO1xuICAgICAgICAgIH07XG4gICAgICAgICAgaWYgKHJlc3AuZGlmZikge1xuICAgICAgICAgICAgdGhpcy5saXZlU29ja2V0LnJlcXVlc3RET01VcGRhdGUoKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLmFwcGx5RGlmZihcInVwZGF0ZVwiLCByZXNwLmRpZmYsICh7IGRpZmYsIHJlcGx5LCBldmVudHMgfSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChyZWYgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMudW5kb1JlZnMocmVmLCBwYXlsb2FkLmV2ZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGUoZGlmZiwgZXZlbnRzKTtcbiAgICAgICAgICAgICAgICBmaW5pc2gocmVwbHkpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAocmVmICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgIHRoaXMudW5kb1JlZnMocmVmLCBwYXlsb2FkLmV2ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZpbmlzaChudWxsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAocmVhc29uKSA9PlxuICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYGZhaWxlZCB3aXRoIHJlYXNvbjogJHtKU09OLnN0cmluZ2lmeShyZWFzb24pfWApKSxcbiAgICAgICAgdGltZW91dDogKCkgPT4ge1xuICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoXCJ0aW1lb3V0XCIpKTtcbiAgICAgICAgICBpZiAodGhpcy5qb2luQ291bnQgPT09IG9sZEpvaW5Db3VudCkge1xuICAgICAgICAgICAgdGhpcy5saXZlU29ja2V0LnJlbG9hZFdpdGhKaXR0ZXIodGhpcywgKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLmxvZyhcInRpbWVvdXRcIiwgKCkgPT4gW1xuICAgICAgICAgICAgICAgIFwicmVjZWl2ZWQgdGltZW91dCB3aGlsZSBjb21tdW5pY2F0aW5nIHdpdGggc2VydmVyLiBGYWxsaW5nIGJhY2sgdG8gaGFyZCByZWZyZXNoIGZvciByZWNvdmVyeVwiLFxuICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgdW5kb1JlZnMocmVmLCBwaHhFdmVudCwgb25seUVscykge1xuICAgIGlmICghdGhpcy5pc0Nvbm5lY3RlZCgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfSAvLyBleGl0IGlmIGV4dGVybmFsIGZvcm0gdHJpZ2dlcmVkXG4gICAgY29uc3Qgc2VsZWN0b3IgPSBgWyR7UEhYX1JFRl9TUkN9PVwiJHt0aGlzLnJlZlNyYygpfVwiXWA7XG5cbiAgICBpZiAob25seUVscykge1xuICAgICAgb25seUVscyA9IG5ldyBTZXQob25seUVscyk7XG4gICAgICBET00uYWxsKGRvY3VtZW50LCBzZWxlY3RvciwgKHBhcmVudCkgPT4ge1xuICAgICAgICBpZiAob25seUVscyAmJiAhb25seUVscy5oYXMocGFyZW50KSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyB1bmRvIGFueSBjaGlsZCByZWZzIHdpdGhpbiBwYXJlbnQgZmlyc3RcbiAgICAgICAgRE9NLmFsbChwYXJlbnQsIHNlbGVjdG9yLCAoY2hpbGQpID0+XG4gICAgICAgICAgdGhpcy51bmRvRWxSZWYoY2hpbGQsIHJlZiwgcGh4RXZlbnQpLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnVuZG9FbFJlZihwYXJlbnQsIHJlZiwgcGh4RXZlbnQpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIERPTS5hbGwoZG9jdW1lbnQsIHNlbGVjdG9yLCAoZWwpID0+IHRoaXMudW5kb0VsUmVmKGVsLCByZWYsIHBoeEV2ZW50KSk7XG4gICAgfVxuICB9XG5cbiAgdW5kb0VsUmVmKGVsLCByZWYsIHBoeEV2ZW50KSB7XG4gICAgY29uc3QgZWxSZWYgPSBuZXcgRWxlbWVudFJlZihlbCk7XG5cbiAgICBlbFJlZi5tYXliZVVuZG8ocmVmLCBwaHhFdmVudCwgKGNsb25lZFRyZWUpID0+IHtcbiAgICAgIC8vIHdlIG5lZWQgdG8gcGVyZm9ybSBhIGZ1bGwgcGF0Y2ggb24gdW5sb2NrZWQgZWxlbWVudHNcbiAgICAgIC8vIHRvIHBlcmZvcm0gYWxsIHRoZSBuZWNlc3NhcnkgbG9naWMgKGxpa2UgY2FsbGluZyB1cGRhdGVkIGZvciBob29rcywgZXRjLilcbiAgICAgIGNvbnN0IHBhdGNoID0gbmV3IERPTVBhdGNoKHRoaXMsIGVsLCB0aGlzLmlkLCBjbG9uZWRUcmVlLCBbXSwgbnVsbCwge1xuICAgICAgICB1bmRvUmVmOiByZWYsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHBoeENoaWxkcmVuQWRkZWQgPSB0aGlzLnBlcmZvcm1QYXRjaChwYXRjaCwgdHJ1ZSk7XG4gICAgICBET00uYWxsKGVsLCBgWyR7UEhYX1JFRl9TUkN9PVwiJHt0aGlzLnJlZlNyYygpfVwiXWAsIChjaGlsZCkgPT5cbiAgICAgICAgdGhpcy51bmRvRWxSZWYoY2hpbGQsIHJlZiwgcGh4RXZlbnQpLFxuICAgICAgKTtcbiAgICAgIGlmIChwaHhDaGlsZHJlbkFkZGVkKSB7XG4gICAgICAgIHRoaXMuam9pbk5ld0NoaWxkcmVuKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICByZWZTcmMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZWwuaWQ7XG4gIH1cblxuICBwdXRSZWYoZWxlbWVudHMsIHBoeEV2ZW50LCBldmVudFR5cGUsIG9wdHMgPSB7fSkge1xuICAgIGNvbnN0IG5ld1JlZiA9IHRoaXMucmVmKys7XG4gICAgY29uc3QgZGlzYWJsZVdpdGggPSB0aGlzLmJpbmRpbmcoUEhYX0RJU0FCTEVfV0lUSCk7XG4gICAgaWYgKG9wdHMubG9hZGluZykge1xuICAgICAgY29uc3QgbG9hZGluZ0VscyA9IERPTS5hbGwoZG9jdW1lbnQsIG9wdHMubG9hZGluZykubWFwKChlbCkgPT4ge1xuICAgICAgICByZXR1cm4geyBlbCwgbG9jazogdHJ1ZSwgbG9hZGluZzogdHJ1ZSB9O1xuICAgICAgfSk7XG4gICAgICBlbGVtZW50cyA9IGVsZW1lbnRzLmNvbmNhdChsb2FkaW5nRWxzKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHsgZWwsIGxvY2ssIGxvYWRpbmcgfSBvZiBlbGVtZW50cykge1xuICAgICAgaWYgKCFsb2NrICYmICFsb2FkaW5nKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcInB1dFJlZiByZXF1aXJlcyBsb2NrIG9yIGxvYWRpbmdcIik7XG4gICAgICB9XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoUEhYX1JFRl9TUkMsIHRoaXMucmVmU3JjKCkpO1xuICAgICAgaWYgKGxvYWRpbmcpIHtcbiAgICAgICAgZWwuc2V0QXR0cmlidXRlKFBIWF9SRUZfTE9BRElORywgbmV3UmVmKTtcbiAgICAgIH1cbiAgICAgIGlmIChsb2NrKSB7XG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZShQSFhfUkVGX0xPQ0ssIG5ld1JlZik7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgIWxvYWRpbmcgfHxcbiAgICAgICAgKG9wdHMuc3VibWl0dGVyICYmICEoZWwgPT09IG9wdHMuc3VibWl0dGVyIHx8IGVsID09PSBvcHRzLmZvcm0pKVxuICAgICAgKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBsb2NrQ29tcGxldGVQcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcihgcGh4OnVuZG8tbG9jazoke25ld1JlZn1gLCAoKSA9PiByZXNvbHZlKGRldGFpbCksIHtcbiAgICAgICAgICBvbmNlOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBsb2FkaW5nQ29tcGxldGVQcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICBgcGh4OnVuZG8tbG9hZGluZzoke25ld1JlZn1gLFxuICAgICAgICAgICgpID0+IHJlc29sdmUoZGV0YWlsKSxcbiAgICAgICAgICB7IG9uY2U6IHRydWUgfSxcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBlbC5jbGFzc0xpc3QuYWRkKGBwaHgtJHtldmVudFR5cGV9LWxvYWRpbmdgKTtcbiAgICAgIGNvbnN0IGRpc2FibGVUZXh0ID0gZWwuZ2V0QXR0cmlidXRlKGRpc2FibGVXaXRoKTtcbiAgICAgIGlmIChkaXNhYmxlVGV4dCAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoIWVsLmdldEF0dHJpYnV0ZShQSFhfRElTQUJMRV9XSVRIX1JFU1RPUkUpKSB7XG4gICAgICAgICAgZWwuc2V0QXR0cmlidXRlKFBIWF9ESVNBQkxFX1dJVEhfUkVTVE9SRSwgZWwudGV4dENvbnRlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkaXNhYmxlVGV4dCAhPT0gXCJcIikge1xuICAgICAgICAgIGVsLnRleHRDb250ZW50ID0gZGlzYWJsZVRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUEhYX0RJU0FCTEVEIGNvdWxkIGhhdmUgYWxyZWFkeSBiZWVuIHNldCBpbiBkaXNhYmxlRm9ybVxuICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoXG4gICAgICAgICAgUEhYX0RJU0FCTEVELFxuICAgICAgICAgIGVsLmdldEF0dHJpYnV0ZShQSFhfRElTQUJMRUQpIHx8IGVsLmRpc2FibGVkLFxuICAgICAgICApO1xuICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiLCBcIlwiKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZGV0YWlsID0ge1xuICAgICAgICBldmVudDogcGh4RXZlbnQsXG4gICAgICAgIGV2ZW50VHlwZTogZXZlbnRUeXBlLFxuICAgICAgICByZWY6IG5ld1JlZixcbiAgICAgICAgaXNMb2FkaW5nOiBsb2FkaW5nLFxuICAgICAgICBpc0xvY2tlZDogbG9jayxcbiAgICAgICAgbG9ja0VsZW1lbnRzOiBlbGVtZW50cy5maWx0ZXIoKHsgbG9jayB9KSA9PiBsb2NrKS5tYXAoKHsgZWwgfSkgPT4gZWwpLFxuICAgICAgICBsb2FkaW5nRWxlbWVudHM6IGVsZW1lbnRzXG4gICAgICAgICAgLmZpbHRlcigoeyBsb2FkaW5nIH0pID0+IGxvYWRpbmcpXG4gICAgICAgICAgLm1hcCgoeyBlbCB9KSA9PiBlbCksXG4gICAgICAgIHVubG9jazogKGVscykgPT4ge1xuICAgICAgICAgIGVscyA9IEFycmF5LmlzQXJyYXkoZWxzKSA/IGVscyA6IFtlbHNdO1xuICAgICAgICAgIHRoaXMudW5kb1JlZnMobmV3UmVmLCBwaHhFdmVudCwgZWxzKTtcbiAgICAgICAgfSxcbiAgICAgICAgbG9ja0NvbXBsZXRlOiBsb2NrQ29tcGxldGVQcm9taXNlLFxuICAgICAgICBsb2FkaW5nQ29tcGxldGU6IGxvYWRpbmdDb21wbGV0ZVByb21pc2UsXG4gICAgICAgIGxvY2s6IChsb2NrRWwpID0+IHtcbiAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzQWNrZWQobmV3UmVmKSkge1xuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShkZXRhaWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9ja0VsLnNldEF0dHJpYnV0ZShQSFhfUkVGX0xPQ0ssIG5ld1JlZik7XG4gICAgICAgICAgICBsb2NrRWwuc2V0QXR0cmlidXRlKFBIWF9SRUZfU1JDLCB0aGlzLnJlZlNyYygpKTtcbiAgICAgICAgICAgIGxvY2tFbC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICBgcGh4OmxvY2stc3RvcDoke25ld1JlZn1gLFxuICAgICAgICAgICAgICAoKSA9PiByZXNvbHZlKGRldGFpbCksXG4gICAgICAgICAgICAgIHsgb25jZTogdHJ1ZSB9LFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBpZiAob3B0cy5wYXlsb2FkKSB7XG4gICAgICAgIGRldGFpbFtcInBheWxvYWRcIl0gPSBvcHRzLnBheWxvYWQ7XG4gICAgICB9XG4gICAgICBpZiAob3B0cy50YXJnZXQpIHtcbiAgICAgICAgZGV0YWlsW1widGFyZ2V0XCJdID0gb3B0cy50YXJnZXQ7XG4gICAgICB9XG4gICAgICBpZiAob3B0cy5vcmlnaW5hbEV2ZW50KSB7XG4gICAgICAgIGRldGFpbFtcIm9yaWdpbmFsRXZlbnRcIl0gPSBvcHRzLm9yaWdpbmFsRXZlbnQ7XG4gICAgICB9XG4gICAgICBlbC5kaXNwYXRjaEV2ZW50KFxuICAgICAgICBuZXcgQ3VzdG9tRXZlbnQoXCJwaHg6cHVzaFwiLCB7XG4gICAgICAgICAgZGV0YWlsOiBkZXRhaWwsXG4gICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgICAgaWYgKHBoeEV2ZW50KSB7XG4gICAgICAgIGVsLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgICAgbmV3IEN1c3RvbUV2ZW50KGBwaHg6cHVzaDoke3BoeEV2ZW50fWAsIHtcbiAgICAgICAgICAgIGRldGFpbDogZGV0YWlsLFxuICAgICAgICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgICAgICAgIGNhbmNlbGFibGU6IGZhbHNlLFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gW25ld1JlZiwgZWxlbWVudHMubWFwKCh7IGVsIH0pID0+IGVsKSwgb3B0c107XG4gIH1cblxuICBpc0Fja2VkKHJlZikge1xuICAgIHJldHVybiB0aGlzLmxhc3RBY2tSZWYgIT09IG51bGwgJiYgdGhpcy5sYXN0QWNrUmVmID49IHJlZjtcbiAgfVxuXG4gIGNvbXBvbmVudElEKGVsKSB7XG4gICAgY29uc3QgY2lkID0gZWwuZ2V0QXR0cmlidXRlICYmIGVsLmdldEF0dHJpYnV0ZShQSFhfQ09NUE9ORU5UKTtcbiAgICByZXR1cm4gY2lkID8gcGFyc2VJbnQoY2lkKSA6IG51bGw7XG4gIH1cblxuICB0YXJnZXRDb21wb25lbnRJRCh0YXJnZXQsIHRhcmdldEN0eCwgb3B0cyA9IHt9KSB7XG4gICAgaWYgKGlzQ2lkKHRhcmdldEN0eCkpIHtcbiAgICAgIHJldHVybiB0YXJnZXRDdHg7XG4gICAgfVxuXG4gICAgY29uc3QgY2lkT3JTZWxlY3RvciA9XG4gICAgICBvcHRzLnRhcmdldCB8fCB0YXJnZXQuZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhcInRhcmdldFwiKSk7XG4gICAgaWYgKGlzQ2lkKGNpZE9yU2VsZWN0b3IpKSB7XG4gICAgICByZXR1cm4gcGFyc2VJbnQoY2lkT3JTZWxlY3Rvcik7XG4gICAgfSBlbHNlIGlmICh0YXJnZXRDdHggJiYgKGNpZE9yU2VsZWN0b3IgIT09IG51bGwgfHwgb3B0cy50YXJnZXQpKSB7XG4gICAgICByZXR1cm4gdGhpcy5jbG9zZXN0Q29tcG9uZW50SUQodGFyZ2V0Q3R4KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgY2xvc2VzdENvbXBvbmVudElEKHRhcmdldEN0eCkge1xuICAgIGlmIChpc0NpZCh0YXJnZXRDdHgpKSB7XG4gICAgICByZXR1cm4gdGFyZ2V0Q3R4O1xuICAgIH0gZWxzZSBpZiAodGFyZ2V0Q3R4KSB7XG4gICAgICByZXR1cm4gbWF5YmUoXG4gICAgICAgIHRhcmdldEN0eC5jbG9zZXN0KGBbJHtQSFhfQ09NUE9ORU5UfV1gKSxcbiAgICAgICAgKGVsKSA9PiB0aGlzLm93bnNFbGVtZW50KGVsKSAmJiB0aGlzLmNvbXBvbmVudElEKGVsKSxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHB1c2hIb29rRXZlbnQoZWwsIHRhcmdldEN0eCwgZXZlbnQsIHBheWxvYWQpIHtcbiAgICBpZiAoIXRoaXMuaXNDb25uZWN0ZWQoKSkge1xuICAgICAgdGhpcy5sb2coXCJob29rXCIsICgpID0+IFtcbiAgICAgICAgXCJ1bmFibGUgdG8gcHVzaCBob29rIGV2ZW50LiBMaXZlVmlldyBub3QgY29ubmVjdGVkXCIsXG4gICAgICAgIGV2ZW50LFxuICAgICAgICBwYXlsb2FkLFxuICAgICAgXSk7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICAgIG5ldyBFcnJvcihcInVuYWJsZSB0byBwdXNoIGhvb2sgZXZlbnQuIExpdmVWaWV3IG5vdCBjb25uZWN0ZWRcIiksXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHJlZkdlbmVyYXRvciA9ICgpID0+XG4gICAgICB0aGlzLnB1dFJlZihbeyBlbCwgbG9hZGluZzogdHJ1ZSwgbG9jazogdHJ1ZSB9XSwgZXZlbnQsIFwiaG9va1wiLCB7XG4gICAgICAgIHBheWxvYWQsXG4gICAgICAgIHRhcmdldDogdGFyZ2V0Q3R4LFxuICAgICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcy5wdXNoV2l0aFJlcGx5KHJlZkdlbmVyYXRvciwgXCJldmVudFwiLCB7XG4gICAgICB0eXBlOiBcImhvb2tcIixcbiAgICAgIGV2ZW50OiBldmVudCxcbiAgICAgIHZhbHVlOiBwYXlsb2FkLFxuICAgICAgY2lkOiB0aGlzLmNsb3Nlc3RDb21wb25lbnRJRCh0YXJnZXRDdHgpLFxuICAgIH0pLnRoZW4oKHsgcmVzcDogX3Jlc3AsIHJlcGx5LCByZWYgfSkgPT4gKHsgcmVwbHksIHJlZiB9KSk7XG4gIH1cblxuICBleHRyYWN0TWV0YShlbCwgbWV0YSwgdmFsdWUpIHtcbiAgICBjb25zdCBwcmVmaXggPSB0aGlzLmJpbmRpbmcoXCJ2YWx1ZS1cIik7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlbC5hdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoIW1ldGEpIHtcbiAgICAgICAgbWV0YSA9IHt9O1xuICAgICAgfVxuICAgICAgY29uc3QgbmFtZSA9IGVsLmF0dHJpYnV0ZXNbaV0ubmFtZTtcbiAgICAgIGlmIChuYW1lLnN0YXJ0c1dpdGgocHJlZml4KSkge1xuICAgICAgICBtZXRhW25hbWUucmVwbGFjZShwcmVmaXgsIFwiXCIpXSA9IGVsLmdldEF0dHJpYnV0ZShuYW1lKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVsLnZhbHVlICE9PSB1bmRlZmluZWQgJiYgIShlbCBpbnN0YW5jZW9mIEhUTUxGb3JtRWxlbWVudCkpIHtcbiAgICAgIGlmICghbWV0YSkge1xuICAgICAgICBtZXRhID0ge307XG4gICAgICB9XG4gICAgICBtZXRhLnZhbHVlID0gZWwudmFsdWU7XG5cbiAgICAgIGlmIChcbiAgICAgICAgZWwudGFnTmFtZSA9PT0gXCJJTlBVVFwiICYmXG4gICAgICAgIENIRUNLQUJMRV9JTlBVVFMuaW5kZXhPZihlbC50eXBlKSA+PSAwICYmXG4gICAgICAgICFlbC5jaGVja2VkXG4gICAgICApIHtcbiAgICAgICAgZGVsZXRlIG1ldGEudmFsdWU7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh2YWx1ZSkge1xuICAgICAgaWYgKCFtZXRhKSB7XG4gICAgICAgIG1ldGEgPSB7fTtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3Qga2V5IGluIHZhbHVlKSB7XG4gICAgICAgIG1ldGFba2V5XSA9IHZhbHVlW2tleV07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtZXRhO1xuICB9XG5cbiAgcHVzaEV2ZW50KHR5cGUsIGVsLCB0YXJnZXRDdHgsIHBoeEV2ZW50LCBtZXRhLCBvcHRzID0ge30sIG9uUmVwbHkpIHtcbiAgICB0aGlzLnB1c2hXaXRoUmVwbHkoXG4gICAgICAobWF5YmVQYXlsb2FkKSA9PlxuICAgICAgICB0aGlzLnB1dFJlZihbeyBlbCwgbG9hZGluZzogdHJ1ZSwgbG9jazogdHJ1ZSB9XSwgcGh4RXZlbnQsIHR5cGUsIHtcbiAgICAgICAgICAuLi5vcHRzLFxuICAgICAgICAgIHBheWxvYWQ6IG1heWJlUGF5bG9hZD8ucGF5bG9hZCxcbiAgICAgICAgfSksXG4gICAgICBcImV2ZW50XCIsXG4gICAgICB7XG4gICAgICAgIHR5cGU6IHR5cGUsXG4gICAgICAgIGV2ZW50OiBwaHhFdmVudCxcbiAgICAgICAgdmFsdWU6IHRoaXMuZXh0cmFjdE1ldGEoZWwsIG1ldGEsIG9wdHMudmFsdWUpLFxuICAgICAgICBjaWQ6IHRoaXMudGFyZ2V0Q29tcG9uZW50SUQoZWwsIHRhcmdldEN0eCwgb3B0cyksXG4gICAgICB9LFxuICAgIClcbiAgICAgIC50aGVuKCh7IHJlcGx5IH0pID0+IG9uUmVwbHkgJiYgb25SZXBseShyZXBseSkpXG4gICAgICAuY2F0Y2goKGVycm9yKSA9PiBsb2dFcnJvcihcIkZhaWxlZCB0byBwdXNoIGV2ZW50XCIsIGVycm9yKSk7XG4gIH1cblxuICBwdXNoRmlsZVByb2dyZXNzKGZpbGVFbCwgZW50cnlSZWYsIHByb2dyZXNzLCBvblJlcGx5ID0gZnVuY3Rpb24gKCkge30pIHtcbiAgICB0aGlzLmxpdmVTb2NrZXQud2l0aGluT3duZXJzKGZpbGVFbC5mb3JtLCAodmlldywgdGFyZ2V0Q3R4KSA9PiB7XG4gICAgICB2aWV3XG4gICAgICAgIC5wdXNoV2l0aFJlcGx5KG51bGwsIFwicHJvZ3Jlc3NcIiwge1xuICAgICAgICAgIGV2ZW50OiBmaWxlRWwuZ2V0QXR0cmlidXRlKHZpZXcuYmluZGluZyhQSFhfUFJPR1JFU1MpKSxcbiAgICAgICAgICByZWY6IGZpbGVFbC5nZXRBdHRyaWJ1dGUoUEhYX1VQTE9BRF9SRUYpLFxuICAgICAgICAgIGVudHJ5X3JlZjogZW50cnlSZWYsXG4gICAgICAgICAgcHJvZ3Jlc3M6IHByb2dyZXNzLFxuICAgICAgICAgIGNpZDogdmlldy50YXJnZXRDb21wb25lbnRJRChmaWxlRWwuZm9ybSwgdGFyZ2V0Q3R4KSxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKCkgPT4gb25SZXBseSgpKVxuICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiBsb2dFcnJvcihcIkZhaWxlZCB0byBwdXNoIGZpbGUgcHJvZ3Jlc3NcIiwgZXJyb3IpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1c2hJbnB1dChpbnB1dEVsLCB0YXJnZXRDdHgsIGZvcmNlQ2lkLCBwaHhFdmVudCwgb3B0cywgY2FsbGJhY2spIHtcbiAgICBpZiAoIWlucHV0RWwuZm9ybSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZm9ybSBldmVudHMgcmVxdWlyZSB0aGUgaW5wdXQgdG8gYmUgaW5zaWRlIGEgZm9ybVwiKTtcbiAgICB9XG5cbiAgICBsZXQgdXBsb2FkcztcbiAgICBjb25zdCBjaWQgPSBpc0NpZChmb3JjZUNpZClcbiAgICAgID8gZm9yY2VDaWRcbiAgICAgIDogdGhpcy50YXJnZXRDb21wb25lbnRJRChpbnB1dEVsLmZvcm0sIHRhcmdldEN0eCwgb3B0cyk7XG4gICAgY29uc3QgcmVmR2VuZXJhdG9yID0gKG1heWJlUGF5bG9hZCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMucHV0UmVmKFxuICAgICAgICBbXG4gICAgICAgICAgeyBlbDogaW5wdXRFbCwgbG9hZGluZzogdHJ1ZSwgbG9jazogdHJ1ZSB9LFxuICAgICAgICAgIHsgZWw6IGlucHV0RWwuZm9ybSwgbG9hZGluZzogdHJ1ZSwgbG9jazogdHJ1ZSB9LFxuICAgICAgICBdLFxuICAgICAgICBwaHhFdmVudCxcbiAgICAgICAgXCJjaGFuZ2VcIixcbiAgICAgICAgeyAuLi5vcHRzLCBwYXlsb2FkOiBtYXliZVBheWxvYWQ/LnBheWxvYWQgfSxcbiAgICAgICk7XG4gICAgfTtcbiAgICBsZXQgZm9ybURhdGE7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuZXh0cmFjdE1ldGEoaW5wdXRFbC5mb3JtLCB7fSwgb3B0cy52YWx1ZSk7XG4gICAgY29uc3Qgc2VyaWFsaXplT3B0cyA9IHt9O1xuICAgIGlmIChpbnB1dEVsIGluc3RhbmNlb2YgSFRNTEJ1dHRvbkVsZW1lbnQpIHtcbiAgICAgIHNlcmlhbGl6ZU9wdHMuc3VibWl0dGVyID0gaW5wdXRFbDtcbiAgICB9XG4gICAgaWYgKGlucHV0RWwuZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhcImNoYW5nZVwiKSkpIHtcbiAgICAgIGZvcm1EYXRhID0gc2VyaWFsaXplRm9ybShpbnB1dEVsLmZvcm0sIHNlcmlhbGl6ZU9wdHMsIFtpbnB1dEVsLm5hbWVdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9ybURhdGEgPSBzZXJpYWxpemVGb3JtKGlucHV0RWwuZm9ybSwgc2VyaWFsaXplT3B0cyk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIERPTS5pc1VwbG9hZElucHV0KGlucHV0RWwpICYmXG4gICAgICBpbnB1dEVsLmZpbGVzICYmXG4gICAgICBpbnB1dEVsLmZpbGVzLmxlbmd0aCA+IDBcbiAgICApIHtcbiAgICAgIExpdmVVcGxvYWRlci50cmFja0ZpbGVzKGlucHV0RWwsIEFycmF5LmZyb20oaW5wdXRFbC5maWxlcykpO1xuICAgIH1cbiAgICB1cGxvYWRzID0gTGl2ZVVwbG9hZGVyLnNlcmlhbGl6ZVVwbG9hZHMoaW5wdXRFbCk7XG5cbiAgICBjb25zdCBldmVudCA9IHtcbiAgICAgIHR5cGU6IFwiZm9ybVwiLFxuICAgICAgZXZlbnQ6IHBoeEV2ZW50LFxuICAgICAgdmFsdWU6IGZvcm1EYXRhLFxuICAgICAgbWV0YToge1xuICAgICAgICAvLyBubyB0YXJnZXQgd2FzIGltcGxpY2l0bHkgc2VudCBhcyBcInVuZGVmaW5lZFwiIGluIExWIDw9IDEuMC41LCB0aGVyZWZvcmVcbiAgICAgICAgLy8gd2UgaGF2ZSB0byBrZWVwIGl0LiBJbiAxLjAuNiB3ZSBzd2l0Y2hlZCBmcm9tIHBhc3NpbmcgbWV0YSBhcyBVUkwgZW5jb2RlZCBkYXRhXG4gICAgICAgIC8vIHRvIHBhc3NpbmcgaXQgZGlyZWN0bHkgaW4gdGhlIGV2ZW50LCBidXQgdGhlIEpTT04gZW5jb2RlIHdvdWxkIGRyb3Aga2V5cyB3aXRoXG4gICAgICAgIC8vIHVuZGVmaW5lZCB2YWx1ZXMuXG4gICAgICAgIF90YXJnZXQ6IG9wdHMuX3RhcmdldCB8fCBcInVuZGVmaW5lZFwiLFxuICAgICAgICAuLi5tZXRhLFxuICAgICAgfSxcbiAgICAgIHVwbG9hZHM6IHVwbG9hZHMsXG4gICAgICBjaWQ6IGNpZCxcbiAgICB9O1xuICAgIHRoaXMucHVzaFdpdGhSZXBseShyZWZHZW5lcmF0b3IsIFwiZXZlbnRcIiwgZXZlbnQpXG4gICAgICAudGhlbigoeyByZXNwIH0pID0+IHtcbiAgICAgICAgaWYgKERPTS5pc1VwbG9hZElucHV0KGlucHV0RWwpICYmIERPTS5pc0F1dG9VcGxvYWQoaW5wdXRFbCkpIHtcbiAgICAgICAgICAvLyB0aGUgZWxlbWVudCBjb3VsZCBiZSBpbnNpZGUgYSBsb2NrZWQgcGFyZW50IGZvciBvdGhlciB1bnJlbGF0ZWQgY2hhbmdlcztcbiAgICAgICAgICAvLyB3ZSBjYW4gb25seSBzdGFydCB1cGxvYWRzIHdoZW4gdGhlIHRyZWUgaXMgdW5sb2NrZWQgYW5kIHRoZVxuICAgICAgICAgIC8vIG5lY2Vzc2FyeSBkYXRhIGF0dHJpYnV0ZXMgYXJlIHNldCBpbiB0aGUgcmVhbCBET01cbiAgICAgICAgICBFbGVtZW50UmVmLm9uVW5sb2NrKGlucHV0RWwsICgpID0+IHtcbiAgICAgICAgICAgIGlmIChMaXZlVXBsb2FkZXIuZmlsZXNBd2FpdGluZ1ByZWZsaWdodChpbnB1dEVsKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIGNvbnN0IFtyZWYsIF9lbHNdID0gcmVmR2VuZXJhdG9yKCk7XG4gICAgICAgICAgICAgIHRoaXMudW5kb1JlZnMocmVmLCBwaHhFdmVudCwgW2lucHV0RWwuZm9ybV0pO1xuICAgICAgICAgICAgICB0aGlzLnVwbG9hZEZpbGVzKFxuICAgICAgICAgICAgICAgIGlucHV0RWwuZm9ybSxcbiAgICAgICAgICAgICAgICBwaHhFdmVudCxcbiAgICAgICAgICAgICAgICB0YXJnZXRDdHgsXG4gICAgICAgICAgICAgICAgcmVmLFxuICAgICAgICAgICAgICAgIGNpZCxcbiAgICAgICAgICAgICAgICAoX3VwbG9hZHMpID0+IHtcbiAgICAgICAgICAgICAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKHJlc3ApO1xuICAgICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyQXdhaXRpbmdTdWJtaXQoaW5wdXRFbC5mb3JtLCBwaHhFdmVudCk7XG4gICAgICAgICAgICAgICAgICB0aGlzLnVuZG9SZWZzKHJlZiwgcGh4RXZlbnQpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2socmVzcCk7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKGVycm9yKSA9PiBsb2dFcnJvcihcIkZhaWxlZCB0byBwdXNoIGlucHV0IGV2ZW50XCIsIGVycm9yKSk7XG4gIH1cblxuICB0cmlnZ2VyQXdhaXRpbmdTdWJtaXQoZm9ybUVsLCBwaHhFdmVudCkge1xuICAgIGNvbnN0IGF3YWl0aW5nU3VibWl0ID0gdGhpcy5nZXRTY2hlZHVsZWRTdWJtaXQoZm9ybUVsKTtcbiAgICBpZiAoYXdhaXRpbmdTdWJtaXQpIHtcbiAgICAgIGNvbnN0IFtfZWwsIF9yZWYsIF9vcHRzLCBjYWxsYmFja10gPSBhd2FpdGluZ1N1Ym1pdDtcbiAgICAgIHRoaXMuY2FuY2VsU3VibWl0KGZvcm1FbCwgcGh4RXZlbnQpO1xuICAgICAgY2FsbGJhY2soKTtcbiAgICB9XG4gIH1cblxuICBnZXRTY2hlZHVsZWRTdWJtaXQoZm9ybUVsKSB7XG4gICAgcmV0dXJuIHRoaXMuZm9ybVN1Ym1pdHMuZmluZCgoW2VsLCBfcmVmLCBfb3B0cywgX2NhbGxiYWNrXSkgPT5cbiAgICAgIGVsLmlzU2FtZU5vZGUoZm9ybUVsKSxcbiAgICApO1xuICB9XG5cbiAgc2NoZWR1bGVTdWJtaXQoZm9ybUVsLCByZWYsIG9wdHMsIGNhbGxiYWNrKSB7XG4gICAgaWYgKHRoaXMuZ2V0U2NoZWR1bGVkU3VibWl0KGZvcm1FbCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICB0aGlzLmZvcm1TdWJtaXRzLnB1c2goW2Zvcm1FbCwgcmVmLCBvcHRzLCBjYWxsYmFja10pO1xuICB9XG5cbiAgY2FuY2VsU3VibWl0KGZvcm1FbCwgcGh4RXZlbnQpIHtcbiAgICB0aGlzLmZvcm1TdWJtaXRzID0gdGhpcy5mb3JtU3VibWl0cy5maWx0ZXIoXG4gICAgICAoW2VsLCByZWYsIF9vcHRzLCBfY2FsbGJhY2tdKSA9PiB7XG4gICAgICAgIGlmIChlbC5pc1NhbWVOb2RlKGZvcm1FbCkpIHtcbiAgICAgICAgICB0aGlzLnVuZG9SZWZzKHJlZiwgcGh4RXZlbnQpO1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICApO1xuICB9XG5cbiAgZGlzYWJsZUZvcm0oZm9ybUVsLCBwaHhFdmVudCwgb3B0cyA9IHt9KSB7XG4gICAgY29uc3QgZmlsdGVySWdub3JlZCA9IChlbCkgPT4ge1xuICAgICAgY29uc3QgdXNlcklnbm9yZWQgPSBjbG9zZXN0UGh4QmluZGluZyhcbiAgICAgICAgZWwsXG4gICAgICAgIGAke3RoaXMuYmluZGluZyhQSFhfVVBEQVRFKX09aWdub3JlYCxcbiAgICAgICAgZWwuZm9ybSxcbiAgICAgICk7XG4gICAgICByZXR1cm4gIShcbiAgICAgICAgdXNlcklnbm9yZWQgfHwgY2xvc2VzdFBoeEJpbmRpbmcoZWwsIFwiZGF0YS1waHgtdXBkYXRlPWlnbm9yZVwiLCBlbC5mb3JtKVxuICAgICAgKTtcbiAgICB9O1xuICAgIGNvbnN0IGZpbHRlckRpc2FibGVzID0gKGVsKSA9PiB7XG4gICAgICByZXR1cm4gZWwuaGFzQXR0cmlidXRlKHRoaXMuYmluZGluZyhQSFhfRElTQUJMRV9XSVRIKSk7XG4gICAgfTtcbiAgICBjb25zdCBmaWx0ZXJCdXR0b24gPSAoZWwpID0+IGVsLnRhZ05hbWUgPT0gXCJCVVRUT05cIjtcblxuICAgIGNvbnN0IGZpbHRlcklucHV0ID0gKGVsKSA9PlxuICAgICAgW1wiSU5QVVRcIiwgXCJURVhUQVJFQVwiLCBcIlNFTEVDVFwiXS5pbmNsdWRlcyhlbC50YWdOYW1lKTtcblxuICAgIGNvbnN0IGZvcm1FbGVtZW50cyA9IEFycmF5LmZyb20oZm9ybUVsLmVsZW1lbnRzKTtcbiAgICBjb25zdCBkaXNhYmxlcyA9IGZvcm1FbGVtZW50cy5maWx0ZXIoZmlsdGVyRGlzYWJsZXMpO1xuICAgIGNvbnN0IGJ1dHRvbnMgPSBmb3JtRWxlbWVudHMuZmlsdGVyKGZpbHRlckJ1dHRvbikuZmlsdGVyKGZpbHRlcklnbm9yZWQpO1xuICAgIGNvbnN0IGlucHV0cyA9IGZvcm1FbGVtZW50cy5maWx0ZXIoZmlsdGVySW5wdXQpLmZpbHRlcihmaWx0ZXJJZ25vcmVkKTtcblxuICAgIGJ1dHRvbnMuZm9yRWFjaCgoYnV0dG9uKSA9PiB7XG4gICAgICBidXR0b24uc2V0QXR0cmlidXRlKFBIWF9ESVNBQkxFRCwgYnV0dG9uLmRpc2FibGVkKTtcbiAgICAgIGJ1dHRvbi5kaXNhYmxlZCA9IHRydWU7XG4gICAgfSk7XG4gICAgaW5wdXRzLmZvckVhY2goKGlucHV0KSA9PiB7XG4gICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoUEhYX1JFQURPTkxZLCBpbnB1dC5yZWFkT25seSk7XG4gICAgICBpbnB1dC5yZWFkT25seSA9IHRydWU7XG4gICAgICBpZiAoaW5wdXQuZmlsZXMpIHtcbiAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKFBIWF9ESVNBQkxFRCwgaW5wdXQuZGlzYWJsZWQpO1xuICAgICAgICBpbnB1dC5kaXNhYmxlZCA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgZm9ybUVscyA9IGRpc2FibGVzXG4gICAgICAuY29uY2F0KGJ1dHRvbnMpXG4gICAgICAuY29uY2F0KGlucHV0cylcbiAgICAgIC5tYXAoKGVsKSA9PiB7XG4gICAgICAgIHJldHVybiB7IGVsLCBsb2FkaW5nOiB0cnVlLCBsb2NrOiB0cnVlIH07XG4gICAgICB9KTtcblxuICAgIC8vIHdlIHJldmVyc2UgdGhlIG9yZGVyIHNvIGZvcm0gY2hpbGRyZW4gYXJlIGFscmVhZHkgbG9ja2VkIGJ5IHRoZSB0aW1lXG4gICAgLy8gdGhlIGZvcm0gaXMgbG9ja2VkXG4gICAgY29uc3QgZWxzID0gW3sgZWw6IGZvcm1FbCwgbG9hZGluZzogdHJ1ZSwgbG9jazogZmFsc2UgfV1cbiAgICAgIC5jb25jYXQoZm9ybUVscylcbiAgICAgIC5yZXZlcnNlKCk7XG4gICAgcmV0dXJuIHRoaXMucHV0UmVmKGVscywgcGh4RXZlbnQsIFwic3VibWl0XCIsIG9wdHMpO1xuICB9XG5cbiAgcHVzaEZvcm1TdWJtaXQoZm9ybUVsLCB0YXJnZXRDdHgsIHBoeEV2ZW50LCBzdWJtaXR0ZXIsIG9wdHMsIG9uUmVwbHkpIHtcbiAgICBjb25zdCByZWZHZW5lcmF0b3IgPSAobWF5YmVQYXlsb2FkKSA9PlxuICAgICAgdGhpcy5kaXNhYmxlRm9ybShmb3JtRWwsIHBoeEV2ZW50LCB7XG4gICAgICAgIC4uLm9wdHMsXG4gICAgICAgIGZvcm06IGZvcm1FbCxcbiAgICAgICAgcGF5bG9hZDogbWF5YmVQYXlsb2FkPy5wYXlsb2FkLFxuICAgICAgICBzdWJtaXR0ZXI6IHN1Ym1pdHRlcixcbiAgICAgIH0pO1xuICAgIC8vIHN0b3JlIHRoZSBzdWJtaXR0ZXIgaW4gdGhlIGZvcm0gZWxlbWVudCBpbiBvcmRlciB0byB0cmlnZ2VyIGl0XG4gICAgLy8gZm9yIHBoeC10cmlnZ2VyLWFjdGlvblxuICAgIERPTS5wdXRQcml2YXRlKGZvcm1FbCwgXCJzdWJtaXR0ZXJcIiwgc3VibWl0dGVyKTtcbiAgICBjb25zdCBjaWQgPSB0aGlzLnRhcmdldENvbXBvbmVudElEKGZvcm1FbCwgdGFyZ2V0Q3R4KTtcbiAgICBpZiAoTGl2ZVVwbG9hZGVyLmhhc1VwbG9hZHNJblByb2dyZXNzKGZvcm1FbCkpIHtcbiAgICAgIGNvbnN0IFtyZWYsIF9lbHNdID0gcmVmR2VuZXJhdG9yKCk7XG4gICAgICBjb25zdCBwdXNoID0gKCkgPT5cbiAgICAgICAgdGhpcy5wdXNoRm9ybVN1Ym1pdChcbiAgICAgICAgICBmb3JtRWwsXG4gICAgICAgICAgdGFyZ2V0Q3R4LFxuICAgICAgICAgIHBoeEV2ZW50LFxuICAgICAgICAgIHN1Ym1pdHRlcixcbiAgICAgICAgICBvcHRzLFxuICAgICAgICAgIG9uUmVwbHksXG4gICAgICAgICk7XG4gICAgICByZXR1cm4gdGhpcy5zY2hlZHVsZVN1Ym1pdChmb3JtRWwsIHJlZiwgb3B0cywgcHVzaCk7XG4gICAgfSBlbHNlIGlmIChMaXZlVXBsb2FkZXIuaW5wdXRzQXdhaXRpbmdQcmVmbGlnaHQoZm9ybUVsKS5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBbcmVmLCBlbHNdID0gcmVmR2VuZXJhdG9yKCk7XG4gICAgICBjb25zdCBwcm94eVJlZkdlbiA9ICgpID0+IFtyZWYsIGVscywgb3B0c107XG4gICAgICB0aGlzLnVwbG9hZEZpbGVzKGZvcm1FbCwgcGh4RXZlbnQsIHRhcmdldEN0eCwgcmVmLCBjaWQsIChfdXBsb2FkcykgPT4ge1xuICAgICAgICAvLyBpZiB3ZSBzdGlsbCBoYXZpbmcgcGVuZGluZyBwcmVmbGlnaHRzIGl0IG1lYW5zIHdlIGhhdmUgaW52YWxpZCBlbnRyaWVzXG4gICAgICAgIC8vIGFuZCB0aGUgcGh4LXN1Ym1pdCBjYW5ub3QgYmUgY29tcGxldGVkXG4gICAgICAgIGlmIChMaXZlVXBsb2FkZXIuaW5wdXRzQXdhaXRpbmdQcmVmbGlnaHQoZm9ybUVsKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudW5kb1JlZnMocmVmLCBwaHhFdmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuZXh0cmFjdE1ldGEoZm9ybUVsLCB7fSwgb3B0cy52YWx1ZSk7XG4gICAgICAgIGNvbnN0IGZvcm1EYXRhID0gc2VyaWFsaXplRm9ybShmb3JtRWwsIHsgc3VibWl0dGVyIH0pO1xuICAgICAgICB0aGlzLnB1c2hXaXRoUmVwbHkocHJveHlSZWZHZW4sIFwiZXZlbnRcIiwge1xuICAgICAgICAgIHR5cGU6IFwiZm9ybVwiLFxuICAgICAgICAgIGV2ZW50OiBwaHhFdmVudCxcbiAgICAgICAgICB2YWx1ZTogZm9ybURhdGEsXG4gICAgICAgICAgbWV0YTogbWV0YSxcbiAgICAgICAgICBjaWQ6IGNpZCxcbiAgICAgICAgfSlcbiAgICAgICAgICAudGhlbigoeyByZXNwIH0pID0+IG9uUmVwbHkocmVzcCkpXG4gICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gbG9nRXJyb3IoXCJGYWlsZWQgdG8gcHVzaCBmb3JtIHN1Ym1pdFwiLCBlcnJvcikpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgICEoXG4gICAgICAgIGZvcm1FbC5oYXNBdHRyaWJ1dGUoUEhYX1JFRl9TUkMpICYmXG4gICAgICAgIGZvcm1FbC5jbGFzc0xpc3QuY29udGFpbnMoXCJwaHgtc3VibWl0LWxvYWRpbmdcIilcbiAgICAgIClcbiAgICApIHtcbiAgICAgIGNvbnN0IG1ldGEgPSB0aGlzLmV4dHJhY3RNZXRhKGZvcm1FbCwge30sIG9wdHMudmFsdWUpO1xuICAgICAgY29uc3QgZm9ybURhdGEgPSBzZXJpYWxpemVGb3JtKGZvcm1FbCwgeyBzdWJtaXR0ZXIgfSk7XG4gICAgICB0aGlzLnB1c2hXaXRoUmVwbHkocmVmR2VuZXJhdG9yLCBcImV2ZW50XCIsIHtcbiAgICAgICAgdHlwZTogXCJmb3JtXCIsXG4gICAgICAgIGV2ZW50OiBwaHhFdmVudCxcbiAgICAgICAgdmFsdWU6IGZvcm1EYXRhLFxuICAgICAgICBtZXRhOiBtZXRhLFxuICAgICAgICBjaWQ6IGNpZCxcbiAgICAgIH0pXG4gICAgICAgIC50aGVuKCh7IHJlc3AgfSkgPT4gb25SZXBseShyZXNwKSlcbiAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gbG9nRXJyb3IoXCJGYWlsZWQgdG8gcHVzaCBmb3JtIHN1Ym1pdFwiLCBlcnJvcikpO1xuICAgIH1cbiAgfVxuXG4gIHVwbG9hZEZpbGVzKGZvcm1FbCwgcGh4RXZlbnQsIHRhcmdldEN0eCwgcmVmLCBjaWQsIG9uQ29tcGxldGUpIHtcbiAgICBjb25zdCBqb2luQ291bnRBdFVwbG9hZCA9IHRoaXMuam9pbkNvdW50O1xuICAgIGNvbnN0IGlucHV0RWxzID0gTGl2ZVVwbG9hZGVyLmFjdGl2ZUZpbGVJbnB1dHMoZm9ybUVsKTtcbiAgICBsZXQgbnVtRmlsZUlucHV0c0luUHJvZ3Jlc3MgPSBpbnB1dEVscy5sZW5ndGg7XG5cbiAgICAvLyBnZXQgZWFjaCBmaWxlIGlucHV0XG4gICAgaW5wdXRFbHMuZm9yRWFjaCgoaW5wdXRFbCkgPT4ge1xuICAgICAgY29uc3QgdXBsb2FkZXIgPSBuZXcgTGl2ZVVwbG9hZGVyKGlucHV0RWwsIHRoaXMsICgpID0+IHtcbiAgICAgICAgbnVtRmlsZUlucHV0c0luUHJvZ3Jlc3MtLTtcbiAgICAgICAgaWYgKG51bUZpbGVJbnB1dHNJblByb2dyZXNzID09PSAwKSB7XG4gICAgICAgICAgb25Db21wbGV0ZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgZW50cmllcyA9IHVwbG9hZGVyXG4gICAgICAgIC5lbnRyaWVzKClcbiAgICAgICAgLm1hcCgoZW50cnkpID0+IGVudHJ5LnRvUHJlZmxpZ2h0UGF5bG9hZCgpKTtcblxuICAgICAgaWYgKGVudHJpZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIG51bUZpbGVJbnB1dHNJblByb2dyZXNzLS07XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgcmVmOiBpbnB1dEVsLmdldEF0dHJpYnV0ZShQSFhfVVBMT0FEX1JFRiksXG4gICAgICAgIGVudHJpZXM6IGVudHJpZXMsXG4gICAgICAgIGNpZDogdGhpcy50YXJnZXRDb21wb25lbnRJRChpbnB1dEVsLmZvcm0sIHRhcmdldEN0eCksXG4gICAgICB9O1xuXG4gICAgICB0aGlzLmxvZyhcInVwbG9hZFwiLCAoKSA9PiBbXCJzZW5kaW5nIHByZWZsaWdodCByZXF1ZXN0XCIsIHBheWxvYWRdKTtcblxuICAgICAgdGhpcy5wdXNoV2l0aFJlcGx5KG51bGwsIFwiYWxsb3dfdXBsb2FkXCIsIHBheWxvYWQpXG4gICAgICAgIC50aGVuKCh7IHJlc3AgfSkgPT4ge1xuICAgICAgICAgIHRoaXMubG9nKFwidXBsb2FkXCIsICgpID0+IFtcImdvdCBwcmVmbGlnaHQgcmVzcG9uc2VcIiwgcmVzcF0pO1xuICAgICAgICAgIC8vIHRoZSBwcmVmbGlnaHQgd2lsbCByZWplY3QgZW50cmllcyBiZXlvbmQgdGhlIG1heCBlbnRyaWVzXG4gICAgICAgICAgLy8gc28gd2UgZXJyb3IgYW5kIGNhbmNlbCBlbnRyaWVzIG9uIHRoZSBjbGllbnQgdGhhdCBhcmUgbWlzc2luZyBmcm9tIHRoZSByZXNwb25zZVxuICAgICAgICAgIHVwbG9hZGVyLmVudHJpZXMoKS5mb3JFYWNoKChlbnRyeSkgPT4ge1xuICAgICAgICAgICAgaWYgKHJlc3AuZW50cmllcyAmJiAhcmVzcC5lbnRyaWVzW2VudHJ5LnJlZl0pIHtcbiAgICAgICAgICAgICAgdGhpcy5oYW5kbGVGYWlsZWRFbnRyeVByZWZsaWdodChcbiAgICAgICAgICAgICAgICBlbnRyeS5yZWYsXG4gICAgICAgICAgICAgICAgXCJmYWlsZWQgcHJlZmxpZ2h0XCIsXG4gICAgICAgICAgICAgICAgdXBsb2FkZXIsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgLy8gZm9yIGF1dG8gdXBsb2Fkcywgd2UgbWF5IGhhdmUgYW4gZW1wdHkgZW50cmllcyByZXNwb25zZSBmcm9tIHRoZSBzZXJ2ZXJcbiAgICAgICAgICAvLyBmb3IgZm9ybSBzdWJtaXRzIHRoYXQgY29udGFpbiBpbnZhbGlkIGVudHJpZXNcbiAgICAgICAgICBpZiAocmVzcC5lcnJvciB8fCBPYmplY3Qua2V5cyhyZXNwLmVudHJpZXMpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy51bmRvUmVmcyhyZWYsIHBoeEV2ZW50KTtcbiAgICAgICAgICAgIGNvbnN0IGVycm9ycyA9IHJlc3AuZXJyb3IgfHwgW107XG4gICAgICAgICAgICBlcnJvcnMubWFwKChbZW50cnlfcmVmLCByZWFzb25dKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuaGFuZGxlRmFpbGVkRW50cnlQcmVmbGlnaHQoZW50cnlfcmVmLCByZWFzb24sIHVwbG9hZGVyKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBvbkVycm9yID0gKGNhbGxiYWNrKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuY2hhbm5lbC5vbkVycm9yKCgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5qb2luQ291bnQgPT09IGpvaW5Db3VudEF0VXBsb2FkKSB7XG4gICAgICAgICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdXBsb2FkZXIuaW5pdEFkYXB0ZXJVcGxvYWQocmVzcCwgb25FcnJvciwgdGhpcy5saXZlU29ja2V0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IGxvZ0Vycm9yKFwiRmFpbGVkIHRvIHB1c2ggdXBsb2FkXCIsIGVycm9yKSk7XG4gICAgfSk7XG4gIH1cblxuICBoYW5kbGVGYWlsZWRFbnRyeVByZWZsaWdodCh1cGxvYWRSZWYsIHJlYXNvbiwgdXBsb2FkZXIpIHtcbiAgICBpZiAodXBsb2FkZXIuaXNBdXRvVXBsb2FkKCkpIHtcbiAgICAgIC8vIHVwbG9hZFJlZiBtYXkgYmUgdG9wIGxldmVsIHVwbG9hZCBjb25maWcgcmVmIG9yIGVudHJ5IHJlZlxuICAgICAgY29uc3QgZW50cnkgPSB1cGxvYWRlclxuICAgICAgICAuZW50cmllcygpXG4gICAgICAgIC5maW5kKChlbnRyeSkgPT4gZW50cnkucmVmID09PSB1cGxvYWRSZWYudG9TdHJpbmcoKSk7XG4gICAgICBpZiAoZW50cnkpIHtcbiAgICAgICAgZW50cnkuY2FuY2VsKCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHVwbG9hZGVyLmVudHJpZXMoKS5tYXAoKGVudHJ5KSA9PiBlbnRyeS5jYW5jZWwoKSk7XG4gICAgfVxuICAgIHRoaXMubG9nKFwidXBsb2FkXCIsICgpID0+IFtgZXJyb3IgZm9yIGVudHJ5ICR7dXBsb2FkUmVmfWAsIHJlYXNvbl0pO1xuICB9XG5cbiAgZGlzcGF0Y2hVcGxvYWRzKHRhcmdldEN0eCwgbmFtZSwgZmlsZXNPckJsb2JzKSB7XG4gICAgY29uc3QgdGFyZ2V0RWxlbWVudCA9IHRoaXMudGFyZ2V0Q3R4RWxlbWVudCh0YXJnZXRDdHgpIHx8IHRoaXMuZWw7XG4gICAgY29uc3QgaW5wdXRzID0gRE9NLmZpbmRVcGxvYWRJbnB1dHModGFyZ2V0RWxlbWVudCkuZmlsdGVyKFxuICAgICAgKGVsKSA9PiBlbC5uYW1lID09PSBuYW1lLFxuICAgICk7XG4gICAgaWYgKGlucHV0cy5sZW5ndGggPT09IDApIHtcbiAgICAgIGxvZ0Vycm9yKGBubyBsaXZlIGZpbGUgaW5wdXRzIGZvdW5kIG1hdGNoaW5nIHRoZSBuYW1lIFwiJHtuYW1lfVwiYCk7XG4gICAgfSBlbHNlIGlmIChpbnB1dHMubGVuZ3RoID4gMSkge1xuICAgICAgbG9nRXJyb3IoYGR1cGxpY2F0ZSBsaXZlIGZpbGUgaW5wdXRzIGZvdW5kIG1hdGNoaW5nIHRoZSBuYW1lIFwiJHtuYW1lfVwiYCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIERPTS5kaXNwYXRjaEV2ZW50KGlucHV0c1swXSwgUEhYX1RSQUNLX1VQTE9BRFMsIHtcbiAgICAgICAgZGV0YWlsOiB7IGZpbGVzOiBmaWxlc09yQmxvYnMgfSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHRhcmdldEN0eEVsZW1lbnQodGFyZ2V0Q3R4KSB7XG4gICAgaWYgKGlzQ2lkKHRhcmdldEN0eCkpIHtcbiAgICAgIGNvbnN0IFt0YXJnZXRdID0gRE9NLmZpbmRDb21wb25lbnROb2RlTGlzdCh0aGlzLmlkLCB0YXJnZXRDdHgpO1xuICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9IGVsc2UgaWYgKHRhcmdldEN0eCkge1xuICAgICAgcmV0dXJuIHRhcmdldEN0eDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHVzaEZvcm1SZWNvdmVyeShvbGRGb3JtLCBuZXdGb3JtLCB0ZW1wbGF0ZURvbSwgY2FsbGJhY2spIHtcbiAgICAvLyB3ZSBhcmUgb25seSByZWNvdmVyaW5nIGZvcm1zIGluc2lkZSB0aGUgY3VycmVudCB2aWV3LCB0aGVyZWZvcmUgaXQgaXMgc2FmZSB0b1xuICAgIC8vIHNraXAgd2l0aGluT3duZXJzIGhlcmUgYW5kIGFsd2F5cyB1c2UgdGhpcyB3aGVuIHJlZmVycmluZyB0byB0aGUgdmlld1xuICAgIGNvbnN0IHBoeENoYW5nZSA9IHRoaXMuYmluZGluZyhcImNoYW5nZVwiKTtcbiAgICBjb25zdCBwaHhUYXJnZXQgPSBuZXdGb3JtLmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoXCJ0YXJnZXRcIikpIHx8IG5ld0Zvcm07XG4gICAgY29uc3QgcGh4RXZlbnQgPVxuICAgICAgbmV3Rm9ybS5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFBIWF9BVVRPX1JFQ09WRVIpKSB8fFxuICAgICAgbmV3Rm9ybS5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFwiY2hhbmdlXCIpKTtcbiAgICBjb25zdCBpbnB1dHMgPSBBcnJheS5mcm9tKG9sZEZvcm0uZWxlbWVudHMpLmZpbHRlcihcbiAgICAgIChlbCkgPT4gRE9NLmlzRm9ybUlucHV0KGVsKSAmJiBlbC5uYW1lICYmICFlbC5oYXNBdHRyaWJ1dGUocGh4Q2hhbmdlKSxcbiAgICApO1xuICAgIGlmIChpbnB1dHMubGVuZ3RoID09PSAwKSB7XG4gICAgICBjYWxsYmFjaygpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHdlIG11c3QgY2xlYXIgdHJhY2tlZCB1cGxvYWRzIGJlZm9yZSByZWNvdmVyeSBhcyB0aGV5IG5vIGxvbmdlciBoYXZlIHZhbGlkIHJlZnNcbiAgICBpbnB1dHMuZm9yRWFjaChcbiAgICAgIChpbnB1dCkgPT5cbiAgICAgICAgaW5wdXQuaGFzQXR0cmlidXRlKFBIWF9VUExPQURfUkVGKSAmJiBMaXZlVXBsb2FkZXIuY2xlYXJGaWxlcyhpbnB1dCksXG4gICAgKTtcbiAgICAvLyBwdXNoSW5wdXQgYXNzdW1lcyB0aGF0IHRoZXJlIGlzIGEgc291cmNlIGVsZW1lbnQgdGhhdCBpbml0aWF0ZWQgdGhlIGNoYW5nZTtcbiAgICAvLyBiZWNhdXNlIHRoaXMgaXMgbm90IHRoZSBjYXNlIHdoZW4gd2UgcmVjb3ZlciBmb3Jtcywgd2UgcHJvdmlkZSB0aGUgZmlyc3QgaW5wdXQgd2UgZmluZFxuICAgIGNvbnN0IGlucHV0ID0gaW5wdXRzLmZpbmQoKGVsKSA9PiBlbC50eXBlICE9PSBcImhpZGRlblwiKSB8fCBpbnB1dHNbMF07XG5cbiAgICAvLyBpbiB0aGUgY2FzZSB0aGF0IHRoZXJlIGFyZSBtdWx0aXBsZSB0YXJnZXRzLCB3ZSBjb3VudCB0aGUgbnVtYmVyIG9mIHBlbmRpbmcgcmVjb3ZlcnkgZXZlbnRzXG4gICAgLy8gYW5kIG9ubHkgY2FsbCB0aGUgY2FsbGJhY2sgb25jZSBhbGwgZXZlbnRzIGhhdmUgYmVlbiBwcm9jZXNzZWRcbiAgICBsZXQgcGVuZGluZyA9IDA7XG4gICAgLy8gd2l0aGluVGFyZ2V0cyhwaHhUYXJnZXQsIGNhbGxiYWNrLCBkb20sIHZpZXdFbClcbiAgICB0aGlzLndpdGhpblRhcmdldHMoXG4gICAgICBwaHhUYXJnZXQsXG4gICAgICAodGFyZ2V0VmlldywgdGFyZ2V0Q3R4KSA9PiB7XG4gICAgICAgIGNvbnN0IGNpZCA9IHRoaXMudGFyZ2V0Q29tcG9uZW50SUQobmV3Rm9ybSwgdGFyZ2V0Q3R4KTtcbiAgICAgICAgcGVuZGluZysrO1xuICAgICAgICBsZXQgZSA9IG5ldyBDdXN0b21FdmVudChcInBoeDpmb3JtLXJlY292ZXJ5XCIsIHtcbiAgICAgICAgICBkZXRhaWw6IHsgc291cmNlRWxlbWVudDogb2xkRm9ybSB9LFxuICAgICAgICB9KTtcbiAgICAgICAgSlMuZXhlYyhlLCBcImNoYW5nZVwiLCBwaHhFdmVudCwgdGhpcywgaW5wdXQsIFtcbiAgICAgICAgICBcInB1c2hcIixcbiAgICAgICAgICB7XG4gICAgICAgICAgICBfdGFyZ2V0OiBpbnB1dC5uYW1lLFxuICAgICAgICAgICAgdGFyZ2V0VmlldyxcbiAgICAgICAgICAgIHRhcmdldEN0eCxcbiAgICAgICAgICAgIG5ld0NpZDogY2lkLFxuICAgICAgICAgICAgY2FsbGJhY2s6ICgpID0+IHtcbiAgICAgICAgICAgICAgcGVuZGluZy0tO1xuICAgICAgICAgICAgICBpZiAocGVuZGluZyA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG4gICAgICB9LFxuICAgICAgdGVtcGxhdGVEb20sXG4gICAgKTtcbiAgfVxuXG4gIHB1c2hMaW5rUGF0Y2goZSwgaHJlZiwgdGFyZ2V0RWwsIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgbGlua1JlZiA9IHRoaXMubGl2ZVNvY2tldC5zZXRQZW5kaW5nTGluayhocmVmKTtcbiAgICAvLyBvbmx5IGFkZCBsb2FkaW5nIHN0YXRlcyBpZiBldmVudCBpcyB0cnVzdGVkIChpdCB3YXMgdHJpZ2dlcmVkIGJ5IHVzZXIsIHN1Y2ggYXMgY2xpY2spIGFuZFxuICAgIC8vIGl0J3Mgbm90IGEgZm9yd2FyZC9iYWNrIG5hdmlnYXRpb24gZnJvbSBwb3BzdGF0ZVxuICAgIGNvbnN0IGxvYWRpbmcgPSBlLmlzVHJ1c3RlZCAmJiBlLnR5cGUgIT09IFwicG9wc3RhdGVcIjtcbiAgICBjb25zdCByZWZHZW4gPSB0YXJnZXRFbFxuICAgICAgPyAoKSA9PlxuICAgICAgICAgIHRoaXMucHV0UmVmKFxuICAgICAgICAgICAgW3sgZWw6IHRhcmdldEVsLCBsb2FkaW5nOiBsb2FkaW5nLCBsb2NrOiB0cnVlIH1dLFxuICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgIFwiY2xpY2tcIixcbiAgICAgICAgICApXG4gICAgICA6IG51bGw7XG4gICAgY29uc3QgZmFsbGJhY2sgPSAoKSA9PiB0aGlzLmxpdmVTb2NrZXQucmVkaXJlY3Qod2luZG93LmxvY2F0aW9uLmhyZWYpO1xuICAgIGNvbnN0IHVybCA9IGhyZWYuc3RhcnRzV2l0aChcIi9cIilcbiAgICAgID8gYCR7bG9jYXRpb24ucHJvdG9jb2x9Ly8ke2xvY2F0aW9uLmhvc3R9JHtocmVmfWBcbiAgICAgIDogaHJlZjtcblxuICAgIHRoaXMucHVzaFdpdGhSZXBseShyZWZHZW4sIFwibGl2ZV9wYXRjaFwiLCB7IHVybCB9KS50aGVuKFxuICAgICAgKHsgcmVzcCB9KSA9PiB7XG4gICAgICAgIHRoaXMubGl2ZVNvY2tldC5yZXF1ZXN0RE9NVXBkYXRlKCgpID0+IHtcbiAgICAgICAgICBpZiAocmVzcC5saW5rX3JlZGlyZWN0KSB7XG4gICAgICAgICAgICB0aGlzLmxpdmVTb2NrZXQucmVwbGFjZU1haW4oaHJlZiwgbnVsbCwgY2FsbGJhY2ssIGxpbmtSZWYpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAodGhpcy5saXZlU29ja2V0LmNvbW1pdFBlbmRpbmdMaW5rKGxpbmtSZWYpKSB7XG4gICAgICAgICAgICAgIHRoaXMuaHJlZiA9IGhyZWY7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmFwcGx5UGVuZGluZ1VwZGF0ZXMoKTtcbiAgICAgICAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKGxpbmtSZWYpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgKHsgZXJyb3I6IF9lcnJvciwgdGltZW91dDogX3RpbWVvdXQgfSkgPT4gZmFsbGJhY2soKSxcbiAgICApO1xuICB9XG5cbiAgZ2V0Rm9ybXNGb3JSZWNvdmVyeSgpIHtcbiAgICAvLyBGb3JtIHJlY292ZXJ5IGlzIGNvbXBsZXggaW4gTGl2ZVZpZXc6XG4gICAgLy8gV2Ugd2FudCB0byBzdXBwb3J0IG5lc3RlZCBMaXZlVmlld3MgYW5kIGFsc28gcHJvdmlkZSBhIGdvb2QgdXNlciBleHBlcmllbmNlLlxuICAgIC8vIFRoZXJlZm9yZSwgd2hlbiB0aGUgY2hhbm5lbCByZWpvaW5zLCB3ZSBjb3B5IGFsbCBmb3JtcyB0aGF0IGFyZSBlbGlnaWJsZSBmb3JcbiAgICAvLyByZWNvdmVyeSB0byBiZSBhYmxlIHRvIGFjY2VzcyB0aGVtIGxhdGVyLlxuICAgIC8vIFdoeSBkbyB3ZSBuZWVkIHRvIGNvcHkgdGhlbT8gQmVjYXVzZSB3aGVuIHRoZSBtYWluIExpdmVWaWV3IGpvaW5zLCBhbnkgZm9ybXNcbiAgICAvLyBpbiBuZXN0ZWQgTGl2ZVZpZXdzIHdvdWxkIGJlIGxvc3QuXG4gICAgLy9cbiAgICAvLyBXZSBzaG91bGQgcmV3b3JrIHRoaXMgaW4gdGhlIGZ1dHVyZSB0byBzZXJpYWxpemUgdGhlIGZvcm0gcGF5bG9hZCBoZXJlXG4gICAgLy8gaW5zdGVhZCBvZiBjbG9uaW5nIHRoZSBET00gbm9kZXMsIGJ1dCBtYWtpbmcgdGhpcyB3b3JrIGNvcnJlY3RseSBpcyB0ZWRpb3VzLFxuICAgIC8vIGFzIHNlbmRpbmcgdGhlIGNvcnJlY3QgZm9ybSBwYXlsb2FkIHJlbGllcyBvbiBKUy5wdXNoIHRvIGV4dHJhY3QgdmFsdWVzXG4gICAgLy8gZnJvbSBKUyBjb21tYW5kcyAocGh4LWNoYW5nZT17SlMucHVzaChcImV2ZW50XCIsIHZhbHVlOiAuLi4sIHRhcmdldDogLi4uKX0pLFxuICAgIC8vIGFzIHdlbGwgYXMgdmlldy5wdXNoSW5wdXQsIHdoaWNoIGV4cGVjdHMgRE9NIGVsZW1lbnRzLlxuXG4gICAgaWYgKHRoaXMuam9pbkNvdW50ID09PSAwKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuXG4gICAgY29uc3QgcGh4Q2hhbmdlID0gdGhpcy5iaW5kaW5nKFwiY2hhbmdlXCIpO1xuXG4gICAgcmV0dXJuIERPTS5hbGwoXG4gICAgICBkb2N1bWVudCxcbiAgICAgIGAjJHtDU1MuZXNjYXBlKHRoaXMuaWQpfSBmb3JtWyR7cGh4Q2hhbmdlfV0sIFske1BIWF9URUxFUE9SVEVEX1JFRn09XCIke0NTUy5lc2NhcGUodGhpcy5pZCl9XCJdIGZvcm1bJHtwaHhDaGFuZ2V9XWAsXG4gICAgKVxuICAgICAgLmZpbHRlcigoZm9ybSkgPT4gZm9ybS5pZClcbiAgICAgIC5maWx0ZXIoKGZvcm0pID0+IGZvcm0uZWxlbWVudHMubGVuZ3RoID4gMClcbiAgICAgIC5maWx0ZXIoXG4gICAgICAgIChmb3JtKSA9PlxuICAgICAgICAgIGZvcm0uZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhQSFhfQVVUT19SRUNPVkVSKSkgIT09IFwiaWdub3JlXCIsXG4gICAgICApXG4gICAgICAubWFwKChmb3JtKSA9PiB7XG4gICAgICAgIC8vIFdlIG5lZWQgdG8gY2xvbmUgdGhlIHdob2xlIGZvcm0sIGFzIHJlbHlpbmcgb24gZm9ybS5lbGVtZW50cyBjYW4gbGVhZCB0b1xuICAgICAgICAvLyBzaXR1YXRpb25zIHdoZXJlIHdlIGhhdmVcbiAgICAgICAgLy9cbiAgICAgICAgLy8gICA8Zm9ybT48ZmllbGRzZXQgZGlzYWJsZWQ+PGlucHV0IG5hbWU9XCJmb29cIiB2YWx1ZT1cImJhclwiPjwvZmllbGRzZXQ+PC9mb3JtPlxuICAgICAgICAvL1xuICAgICAgICAvLyBhbmQgZm9ybS5lbGVtZW50cyByZXR1cm5zIGJvdGggdGhlIGZpZWxkc2V0IGFuZCB0aGUgaW5wdXQgc2VwYXJhdGVseS5cbiAgICAgICAgLy8gQmVjYXVzZSB0aGUgZmllbGRzZXQgaXMgZGlzYWJsZWQsIHRoZSBpbnB1dCBzaG91bGQgTk9UIGJlIHNlbnQgdGhvdWdoLlxuICAgICAgICAvLyBXZSBjYW4gb25seSByZWxpYWJseSBzZXJpYWxpemUgdGhlIGZvcm0gYnkgY2xvbmluZyBpdCBmdWxseS5cbiAgICAgICAgY29uc3QgY2xvbmVkRm9ybSA9IGZvcm0uY2xvbmVOb2RlKHRydWUpO1xuICAgICAgICAvLyB3ZSBjYWxsIG1vcnBoZG9tIHRvIGNvcHkgYW55IHNwZWNpYWwgc3RhdGVcbiAgICAgICAgLy8gbGlrZSB0aGUgc2VsZWN0ZWQgb3B0aW9uIG9mIGEgPHNlbGVjdD4gZWxlbWVudDtcbiAgICAgICAgLy8gYW55IGFsc28gY29weSBvdmVyIHByaXZhdGVzICh3aGljaCBjb250YWluIGluZm9ybWF0aW9uIGFib3V0IHRvdWNoZWQgZmllbGRzKVxuICAgICAgICBtb3JwaGRvbShjbG9uZWRGb3JtLCBmb3JtLCB7XG4gICAgICAgICAgb25CZWZvcmVFbFVwZGF0ZWQ6IChmcm9tRWwsIHRvRWwpID0+IHtcbiAgICAgICAgICAgIERPTS5jb3B5UHJpdmF0ZXMoZnJvbUVsLCB0b0VsKTtcbiAgICAgICAgICAgIGlmIChmcm9tRWwuZ2V0QXR0cmlidXRlKFwiZm9ybVwiKSA9PT0gZm9ybS5pZCkge1xuICAgICAgICAgICAgICAvLyBJbiBjYXNlIHRoZSBmb3JtIGNvbnRhaW5zIGFuIGVsZW1lbnQgd2l0aCBmb3JtPVwiaWRcIiBwb2ludGluZ1xuICAgICAgICAgICAgICAvLyB0byB0aGUgZm9ybSBpdHNlbGYsIGZpcmVmb3ggc3RpbGwgYXNzb2NpYXRlcyB0aGUgZWxlbWVudCB3aXRoIHRoZVxuICAgICAgICAgICAgICAvLyBvcmlnaW5hbCBmb3JtIGVsZW1lbnQuIFRoaXMgaXMgbm90IGZpeGVkIGJ5IHJlbW92aW5nIHRoZSBwYXJhbWV0ZXIsXG4gICAgICAgICAgICAgIC8vIGluc3RlYWQgd2UgcmVtb3ZlIHRoZSBlbGVtZW50IGZyb20gdGhlIGZvcm0gYW5kIGFkZCBpdCBhZ2FpbiB3aXRob3V0XG4gICAgICAgICAgICAgIC8vIGZvcm0gcGFyYW1ldGVyIGJlbG93LlxuICAgICAgICAgICAgICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9waG9lbml4ZnJhbWV3b3JrL3Bob2VuaXhfbGl2ZV92aWV3L2lzc3Vlcy80MDIxXG4gICAgICAgICAgICAgIGZyb21FbC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGZyb21FbCk7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBuZXh0IHVwLCB3ZSBhbHNvIG5lZWQgdG8gY2xvbmUgYW55IGVsZW1lbnRzIHdpdGggZm9ybT1cImlkXCIgcGFyYW1ldGVyXG4gICAgICAgIGNvbnN0IGV4dGVybmFsRWxlbWVudHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgICAgIGBbZm9ybT1cIiR7Q1NTLmVzY2FwZShmb3JtLmlkKX1cIl1gLFxuICAgICAgICApO1xuICAgICAgICBBcnJheS5mcm9tKGV4dGVybmFsRWxlbWVudHMpLmZvckVhY2goKGVsKSA9PiB7XG4gICAgICAgICAgY29uc3QgY2xvbmVkRWwgPSAvKiogQHR5cGUge0hUTUxFbGVtZW50fSAqLyAoZWwuY2xvbmVOb2RlKHRydWUpKTtcbiAgICAgICAgICBtb3JwaGRvbShjbG9uZWRFbCwgZWwpO1xuICAgICAgICAgIERPTS5jb3B5UHJpdmF0ZXMoY2xvbmVkRWwsIGVsKTtcbiAgICAgICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3Bob2VuaXhmcmFtZXdvcmsvcGhvZW5peF9saXZlX3ZpZXcvaXNzdWVzLzQwMjFcbiAgICAgICAgICBjbG9uZWRFbC5yZW1vdmVBdHRyaWJ1dGUoXCJmb3JtXCIpO1xuICAgICAgICAgIGNsb25lZEZvcm0uYXBwZW5kQ2hpbGQoY2xvbmVkRWwpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNsb25lZEZvcm07XG4gICAgICB9KVxuICAgICAgLnJlZHVjZSgoYWNjLCBmb3JtKSA9PiB7XG4gICAgICAgIGFjY1tmb3JtLmlkXSA9IGZvcm07XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LCB7fSk7XG4gIH1cblxuICBtYXliZVB1c2hDb21wb25lbnRzRGVzdHJveWVkKGRlc3Ryb3llZENJRHMpIHtcbiAgICBsZXQgd2lsbERlc3Ryb3lDSURzID0gZGVzdHJveWVkQ0lEcy5maWx0ZXIoKGNpZCkgPT4ge1xuICAgICAgcmV0dXJuIERPTS5maW5kQ29tcG9uZW50Tm9kZUxpc3QodGhpcy5pZCwgY2lkKS5sZW5ndGggPT09IDA7XG4gICAgfSk7XG5cbiAgICBjb25zdCBvbkVycm9yID0gKGVycm9yKSA9PiB7XG4gICAgICBpZiAoIXRoaXMuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICBsb2dFcnJvcihcIkZhaWxlZCB0byBwdXNoIGNvbXBvbmVudHMgZGVzdHJveWVkXCIsIGVycm9yKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKHdpbGxEZXN0cm95Q0lEcy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyB3ZSBtdXN0IHJlc2V0IHRoZSByZW5kZXIgY2hhbmdlIHRyYWNraW5nIGZvciBjaWRzIHRoYXRcbiAgICAgIC8vIGNvdWxkIGJlIGFkZGVkIGJhY2sgZnJvbSB0aGUgc2VydmVyIHNvIHdlIGRvbid0IHNraXAgdGhlbVxuICAgICAgd2lsbERlc3Ryb3lDSURzLmZvckVhY2goKGNpZCkgPT4gdGhpcy5yZW5kZXJlZC5yZXNldFJlbmRlcihjaWQpKTtcblxuICAgICAgdGhpcy5wdXNoV2l0aFJlcGx5KG51bGwsIFwiY2lkc193aWxsX2Rlc3Ryb3lcIiwgeyBjaWRzOiB3aWxsRGVzdHJveUNJRHMgfSlcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIC8vIHdlIG11c3Qgd2FpdCBmb3IgcGVuZGluZyB0cmFuc2l0aW9ucyB0byBjb21wbGV0ZSBiZWZvcmUgZGV0ZXJtaW5pbmdcbiAgICAgICAgICAvLyBpZiB0aGUgY2lkcyB3ZXJlIGFkZGVkIGJhY2sgdG8gdGhlIERPTSBpbiB0aGUgbWVhbnRpbWUgKCMzMTM5KVxuICAgICAgICAgIHRoaXMubGl2ZVNvY2tldC5yZXF1ZXN0RE9NVXBkYXRlKCgpID0+IHtcbiAgICAgICAgICAgIC8vIFNlZSBpZiBhbnkgb2YgdGhlIGNpZHMgd2Ugd2FudGVkIHRvIGRlc3Ryb3kgd2VyZSBhZGRlZCBiYWNrLFxuICAgICAgICAgICAgLy8gaWYgdGhleSB3ZXJlIGFkZGVkIGJhY2ssIHdlIGRvbid0IGFjdHVhbGx5IGRlc3Ryb3kgdGhlbS5cbiAgICAgICAgICAgIGxldCBjb21wbGV0ZWx5RGVzdHJveUNJRHMgPSB3aWxsRGVzdHJveUNJRHMuZmlsdGVyKChjaWQpID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIERPTS5maW5kQ29tcG9uZW50Tm9kZUxpc3QodGhpcy5pZCwgY2lkKS5sZW5ndGggPT09IDA7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKGNvbXBsZXRlbHlEZXN0cm95Q0lEcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIHRoaXMucHVzaFdpdGhSZXBseShudWxsLCBcImNpZHNfZGVzdHJveWVkXCIsIHtcbiAgICAgICAgICAgICAgICBjaWRzOiBjb21wbGV0ZWx5RGVzdHJveUNJRHMsXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLnRoZW4oKHsgcmVzcCB9KSA9PiB7XG4gICAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVkLnBydW5lQ0lEcyhyZXNwLmNpZHMpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKG9uRXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2gob25FcnJvcik7XG4gICAgfVxuICB9XG5cbiAgb3duc0VsZW1lbnQoZWwpIHtcbiAgICBsZXQgcGFyZW50Vmlld0VsID0gRE9NLmNsb3Nlc3RWaWV3RWwoZWwpO1xuICAgIHJldHVybiAoXG4gICAgICBlbC5nZXRBdHRyaWJ1dGUoUEhYX1BBUkVOVF9JRCkgPT09IHRoaXMuaWQgfHxcbiAgICAgIChwYXJlbnRWaWV3RWwgJiYgcGFyZW50Vmlld0VsLmlkID09PSB0aGlzLmlkKSB8fFxuICAgICAgKCFwYXJlbnRWaWV3RWwgJiYgdGhpcy5pc0RlYWQpXG4gICAgKTtcbiAgfVxuXG4gIHN1Ym1pdEZvcm0oZm9ybSwgdGFyZ2V0Q3R4LCBwaHhFdmVudCwgc3VibWl0dGVyLCBvcHRzID0ge30pIHtcbiAgICBET00ucHV0UHJpdmF0ZShmb3JtLCBQSFhfSEFTX1NVQk1JVFRFRCwgdHJ1ZSk7XG4gICAgY29uc3QgaW5wdXRzID0gQXJyYXkuZnJvbShmb3JtLmVsZW1lbnRzKTtcbiAgICBpbnB1dHMuZm9yRWFjaCgoaW5wdXQpID0+IERPTS5wdXRQcml2YXRlKGlucHV0LCBQSFhfSEFTX1NVQk1JVFRFRCwgdHJ1ZSkpO1xuICAgIHRoaXMubGl2ZVNvY2tldC5ibHVyQWN0aXZlRWxlbWVudCh0aGlzKTtcbiAgICB0aGlzLnB1c2hGb3JtU3VibWl0KGZvcm0sIHRhcmdldEN0eCwgcGh4RXZlbnQsIHN1Ym1pdHRlciwgb3B0cywgKCkgPT4ge1xuICAgICAgdGhpcy5saXZlU29ja2V0LnJlc3RvcmVQcmV2aW91c2x5QWN0aXZlRm9jdXMoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGJpbmRpbmcoa2luZCkge1xuICAgIHJldHVybiB0aGlzLmxpdmVTb2NrZXQuYmluZGluZyhraW5kKTtcbiAgfVxuXG4gIC8vIHBoeC1wb3J0YWxcbiAgcHVzaFBvcnRhbEVsZW1lbnRJZChpZCkge1xuICAgIHRoaXMucG9ydGFsRWxlbWVudElkcy5hZGQoaWQpO1xuICB9XG5cbiAgZHJvcFBvcnRhbEVsZW1lbnRJZChpZCkge1xuICAgIHRoaXMucG9ydGFsRWxlbWVudElkcy5kZWxldGUoaWQpO1xuICB9XG5cbiAgZGVzdHJveVBvcnRhbEVsZW1lbnRzKCkge1xuICAgIHRoaXMucG9ydGFsRWxlbWVudElkcy5mb3JFYWNoKChpZCkgPT4ge1xuICAgICAgY29uc3QgZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7XG4gICAgICBpZiAoZWwpIHtcbiAgICAgICAgZWwucmVtb3ZlKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cbiIsICJpbXBvcnQge1xuICBCSU5ESU5HX1BSRUZJWCxcbiAgQ09OU0VDVVRJVkVfUkVMT0FEUyxcbiAgREVGQVVMVFMsXG4gIEZBSUxTQUZFX0pJVFRFUixcbiAgTE9BREVSX1RJTUVPVVQsXG4gIERJU0NPTk5FQ1RFRF9USU1FT1VULFxuICBNQVhfUkVMT0FEUyxcbiAgUEhYX0RFQk9VTkNFLFxuICBQSFhfRFJPUF9UQVJHRVQsXG4gIFBIWF9IQVNfRk9DVVNFRCxcbiAgUEhYX0tFWSxcbiAgUEhYX0xJTktfU1RBVEUsXG4gIFBIWF9MSVZFX0xJTkssXG4gIFBIWF9MVl9ERUJVRyxcbiAgUEhYX0xWX0xBVEVOQ1lfU0lNLFxuICBQSFhfTFZfUFJPRklMRSxcbiAgUEhYX0xWX0hJU1RPUllfUE9TSVRJT04sXG4gIFBIWF9NQUlOLFxuICBQSFhfUEFSRU5UX0lELFxuICBQSFhfVklFV19TRUxFQ1RPUixcbiAgUEhYX1JPT1RfSUQsXG4gIFBIWF9USFJPVFRMRSxcbiAgUEhYX1RSQUNLX1VQTE9BRFMsXG4gIFBIWF9TRVNTSU9OLFxuICBSRUxPQURfSklUVEVSX01JTixcbiAgUkVMT0FEX0pJVFRFUl9NQVgsXG4gIFBIWF9SRUZfU1JDLFxuICBQSFhfUkVMT0FEX1NUQVRVUyxcbiAgUEhYX1JVTlRJTUVfSE9PSyxcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cbmltcG9ydCB7XG4gIGNsb25lLFxuICBjbG9zZXN0UGh4QmluZGluZyxcbiAgY2xvc3VyZSxcbiAgZGVidWcsXG4gIG1heWJlLFxuICBsb2dFcnJvcixcbn0gZnJvbSBcIi4vdXRpbHNcIjtcblxuaW1wb3J0IEJyb3dzZXIgZnJvbSBcIi4vYnJvd3NlclwiO1xuaW1wb3J0IERPTSBmcm9tIFwiLi9kb21cIjtcbmltcG9ydCBIb29rcyBmcm9tIFwiLi9ob29rc1wiO1xuaW1wb3J0IExpdmVVcGxvYWRlciBmcm9tIFwiLi9saXZlX3VwbG9hZGVyXCI7XG5pbXBvcnQgVmlldyBmcm9tIFwiLi92aWV3XCI7XG5pbXBvcnQgSlMgZnJvbSBcIi4vanNcIjtcbmltcG9ydCBqc0NvbW1hbmRzIGZyb20gXCIuL2pzX2NvbW1hbmRzXCI7XG5cbmV4cG9ydCBjb25zdCBpc1VzZWRJbnB1dCA9IChlbCkgPT4gRE9NLmlzVXNlZElucHV0KGVsKTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTGl2ZVNvY2tldCB7XG4gIGNvbnN0cnVjdG9yKHVybCwgcGh4U29ja2V0LCBvcHRzID0ge30pIHtcbiAgICB0aGlzLnVubG9hZGVkID0gZmFsc2U7XG4gICAgaWYgKCFwaHhTb2NrZXQgfHwgcGh4U29ja2V0LmNvbnN0cnVjdG9yLm5hbWUgPT09IFwiT2JqZWN0XCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgXG4gICAgICBhIHBob2VuaXggU29ja2V0IG11c3QgYmUgcHJvdmlkZWQgYXMgdGhlIHNlY29uZCBhcmd1bWVudCB0byB0aGUgTGl2ZVNvY2tldCBjb25zdHJ1Y3Rvci4gRm9yIGV4YW1wbGU6XG5cbiAgICAgICAgICBpbXBvcnQge1NvY2tldH0gZnJvbSBcInBob2VuaXhcIlxuICAgICAgICAgIGltcG9ydCB7TGl2ZVNvY2tldH0gZnJvbSBcInBob2VuaXhfbGl2ZV92aWV3XCJcbiAgICAgICAgICBsZXQgbGl2ZVNvY2tldCA9IG5ldyBMaXZlU29ja2V0KFwiL2xpdmVcIiwgU29ja2V0LCB7Li4ufSlcbiAgICAgIGApO1xuICAgIH1cbiAgICB0aGlzLnNvY2tldCA9IG5ldyBwaHhTb2NrZXQodXJsLCBvcHRzKTtcbiAgICB0aGlzLmJpbmRpbmdQcmVmaXggPSBvcHRzLmJpbmRpbmdQcmVmaXggfHwgQklORElOR19QUkVGSVg7XG4gICAgdGhpcy5vcHRzID0gb3B0cztcbiAgICB0aGlzLnBhcmFtcyA9IGNsb3N1cmUob3B0cy5wYXJhbXMgfHwge30pO1xuICAgIHRoaXMudmlld0xvZ2dlciA9IG9wdHMudmlld0xvZ2dlcjtcbiAgICB0aGlzLm1ldGFkYXRhQ2FsbGJhY2tzID0gb3B0cy5tZXRhZGF0YSB8fCB7fTtcbiAgICB0aGlzLmRlZmF1bHRzID0gT2JqZWN0LmFzc2lnbihjbG9uZShERUZBVUxUUyksIG9wdHMuZGVmYXVsdHMgfHwge30pO1xuICAgIHRoaXMucHJldkFjdGl2ZSA9IG51bGw7XG4gICAgdGhpcy5zaWxlbmNlZCA9IGZhbHNlO1xuICAgIHRoaXMubWFpbiA9IG51bGw7XG4gICAgdGhpcy5vdXRnb2luZ01haW5FbCA9IG51bGw7XG4gICAgdGhpcy5jbGlja1N0YXJ0ZWRBdFRhcmdldCA9IG51bGw7XG4gICAgdGhpcy5saW5rUmVmID0gMTtcbiAgICB0aGlzLnJvb3RzID0ge307XG4gICAgdGhpcy5ocmVmID0gd2luZG93LmxvY2F0aW9uLmhyZWY7XG4gICAgdGhpcy5wZW5kaW5nTGluayA9IG51bGw7XG4gICAgdGhpcy5jdXJyZW50TG9jYXRpb24gPSBjbG9uZSh3aW5kb3cubG9jYXRpb24pO1xuICAgIHRoaXMuaG9va3MgPSBvcHRzLmhvb2tzIHx8IHt9O1xuICAgIHRoaXMudXBsb2FkZXJzID0gb3B0cy51cGxvYWRlcnMgfHwge307XG4gICAgdGhpcy5sb2FkZXJUaW1lb3V0ID0gb3B0cy5sb2FkZXJUaW1lb3V0IHx8IExPQURFUl9USU1FT1VUO1xuICAgIHRoaXMuZGlzY29ubmVjdGVkVGltZW91dCA9IG9wdHMuZGlzY29ubmVjdGVkVGltZW91dCB8fCBESVNDT05ORUNURURfVElNRU9VVDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7UmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCBudWxsfVxuICAgICAqL1xuICAgIHRoaXMucmVsb2FkV2l0aEppdHRlclRpbWVyID0gbnVsbDtcbiAgICB0aGlzLm1heFJlbG9hZHMgPSBvcHRzLm1heFJlbG9hZHMgfHwgTUFYX1JFTE9BRFM7XG4gICAgdGhpcy5yZWxvYWRKaXR0ZXJNaW4gPSBvcHRzLnJlbG9hZEppdHRlck1pbiB8fCBSRUxPQURfSklUVEVSX01JTjtcbiAgICB0aGlzLnJlbG9hZEppdHRlck1heCA9IG9wdHMucmVsb2FkSml0dGVyTWF4IHx8IFJFTE9BRF9KSVRURVJfTUFYO1xuICAgIHRoaXMuZmFpbHNhZmVKaXR0ZXIgPSBvcHRzLmZhaWxzYWZlSml0dGVyIHx8IEZBSUxTQUZFX0pJVFRFUjtcbiAgICB0aGlzLmxvY2FsU3RvcmFnZSA9IG9wdHMubG9jYWxTdG9yYWdlIHx8IHdpbmRvdy5sb2NhbFN0b3JhZ2U7XG4gICAgdGhpcy5zZXNzaW9uU3RvcmFnZSA9IG9wdHMuc2Vzc2lvblN0b3JhZ2UgfHwgd2luZG93LnNlc3Npb25TdG9yYWdlO1xuICAgIHRoaXMuYm91bmRUb3BMZXZlbEV2ZW50cyA9IGZhbHNlO1xuICAgIHRoaXMuYm91bmRFdmVudE5hbWVzID0gbmV3IFNldCgpO1xuICAgIHRoaXMuYmxvY2tQaHhDaGFuZ2VXaGlsZUNvbXBvc2luZyA9XG4gICAgICBvcHRzLmJsb2NrUGh4Q2hhbmdlV2hpbGVDb21wb3NpbmcgfHwgZmFsc2U7XG4gICAgdGhpcy5zZXJ2ZXJDbG9zZVJlZiA9IG51bGw7XG4gICAgdGhpcy5kb21DYWxsYmFja3MgPSBPYmplY3QuYXNzaWduKFxuICAgICAge1xuICAgICAgICBqc1F1ZXJ5U2VsZWN0b3JBbGw6IG51bGwsXG4gICAgICAgIG9uUGF0Y2hTdGFydDogY2xvc3VyZSgpLFxuICAgICAgICBvblBhdGNoRW5kOiBjbG9zdXJlKCksXG4gICAgICAgIG9uTm9kZUFkZGVkOiBjbG9zdXJlKCksXG4gICAgICAgIG9uQmVmb3JlRWxVcGRhdGVkOiBjbG9zdXJlKCksXG4gICAgICB9LFxuICAgICAgb3B0cy5kb20gfHwge30sXG4gICAgKTtcbiAgICB0aGlzLnRyYW5zaXRpb25zID0gbmV3IFRyYW5zaXRpb25TZXQoKTtcbiAgICB0aGlzLmN1cnJlbnRIaXN0b3J5UG9zaXRpb24gPVxuICAgICAgcGFyc2VJbnQodGhpcy5zZXNzaW9uU3RvcmFnZS5nZXRJdGVtKFBIWF9MVl9ISVNUT1JZX1BPU0lUSU9OKSkgfHwgMDtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInBhZ2VoaWRlXCIsIChfZSkgPT4ge1xuICAgICAgdGhpcy51bmxvYWRlZCA9IHRydWU7XG4gICAgfSk7XG4gICAgdGhpcy5zb2NrZXQub25PcGVuKCgpID0+IHtcbiAgICAgIGlmICh0aGlzLmlzVW5sb2FkZWQoKSkge1xuICAgICAgICAvLyByZWxvYWQgcGFnZSBpZiBiZWluZyByZXN0b3JlZCBmcm9tIGJhY2svZm9yd2FyZCBjYWNoZSBhbmQgYnJvd3NlciBkb2VzIG5vdCBlbWl0IFwicGFnZXNob3dcIlxuICAgICAgICB3aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBwdWJsaWNcblxuICB2ZXJzaW9uKCkge1xuICAgIHJldHVybiBMVl9WU047XG4gIH1cblxuICBpc1Byb2ZpbGVFbmFibGVkKCkge1xuICAgIHJldHVybiB0aGlzLnNlc3Npb25TdG9yYWdlLmdldEl0ZW0oUEhYX0xWX1BST0ZJTEUpID09PSBcInRydWVcIjtcbiAgfVxuXG4gIGlzRGVidWdFbmFibGVkKCkge1xuICAgIHJldHVybiB0aGlzLnNlc3Npb25TdG9yYWdlLmdldEl0ZW0oUEhYX0xWX0RFQlVHKSA9PT0gXCJ0cnVlXCI7XG4gIH1cblxuICBpc0RlYnVnRGlzYWJsZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbShQSFhfTFZfREVCVUcpID09PSBcImZhbHNlXCI7XG4gIH1cblxuICBlbmFibGVEZWJ1ZygpIHtcbiAgICB0aGlzLnNlc3Npb25TdG9yYWdlLnNldEl0ZW0oUEhYX0xWX0RFQlVHLCBcInRydWVcIik7XG4gIH1cblxuICBlbmFibGVQcm9maWxpbmcoKSB7XG4gICAgdGhpcy5zZXNzaW9uU3RvcmFnZS5zZXRJdGVtKFBIWF9MVl9QUk9GSUxFLCBcInRydWVcIik7XG4gIH1cblxuICBkaXNhYmxlRGVidWcoKSB7XG4gICAgdGhpcy5zZXNzaW9uU3RvcmFnZS5zZXRJdGVtKFBIWF9MVl9ERUJVRywgXCJmYWxzZVwiKTtcbiAgfVxuXG4gIGRpc2FibGVQcm9maWxpbmcoKSB7XG4gICAgdGhpcy5zZXNzaW9uU3RvcmFnZS5yZW1vdmVJdGVtKFBIWF9MVl9QUk9GSUxFKTtcbiAgfVxuXG4gIGVuYWJsZUxhdGVuY3lTaW0odXBwZXJCb3VuZE1zKSB7XG4gICAgdGhpcy5lbmFibGVEZWJ1ZygpO1xuICAgIGNvbnNvbGUubG9nKFxuICAgICAgXCJsYXRlbmN5IHNpbXVsYXRvciBlbmFibGVkIGZvciB0aGUgZHVyYXRpb24gb2YgdGhpcyBicm93c2VyIHNlc3Npb24uIENhbGwgZGlzYWJsZUxhdGVuY3lTaW0oKSB0byBkaXNhYmxlXCIsXG4gICAgKTtcbiAgICB0aGlzLnNlc3Npb25TdG9yYWdlLnNldEl0ZW0oUEhYX0xWX0xBVEVOQ1lfU0lNLCB1cHBlckJvdW5kTXMpO1xuICB9XG5cbiAgZGlzYWJsZUxhdGVuY3lTaW0oKSB7XG4gICAgdGhpcy5zZXNzaW9uU3RvcmFnZS5yZW1vdmVJdGVtKFBIWF9MVl9MQVRFTkNZX1NJTSk7XG4gIH1cblxuICBnZXRMYXRlbmN5U2ltKCkge1xuICAgIGNvbnN0IHN0ciA9IHRoaXMuc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbShQSFhfTFZfTEFURU5DWV9TSU0pO1xuICAgIHJldHVybiBzdHIgPyBwYXJzZUludChzdHIpIDogbnVsbDtcbiAgfVxuXG4gIGdldFNvY2tldCgpIHtcbiAgICByZXR1cm4gdGhpcy5zb2NrZXQ7XG4gIH1cblxuICBjb25uZWN0KCkge1xuICAgIC8vIGVuYWJsZSBkZWJ1ZyBieSBkZWZhdWx0IGlmIG9uIGxvY2FsaG9zdCBhbmQgbm90IGV4cGxpY2l0bHkgZGlzYWJsZWRcbiAgICBpZiAod2luZG93LmxvY2F0aW9uLmhvc3RuYW1lID09PSBcImxvY2FsaG9zdFwiICYmICF0aGlzLmlzRGVidWdEaXNhYmxlZCgpKSB7XG4gICAgICB0aGlzLmVuYWJsZURlYnVnKCk7XG4gICAgfVxuICAgIGNvbnN0IGRvQ29ubmVjdCA9ICgpID0+IHtcbiAgICAgIHRoaXMucmVzZXRSZWxvYWRTdGF0dXMoKTtcbiAgICAgIGlmICh0aGlzLmpvaW5Sb290Vmlld3MoKSkge1xuICAgICAgICB0aGlzLmJpbmRUb3BMZXZlbEV2ZW50cygpO1xuICAgICAgICB0aGlzLnNvY2tldC5jb25uZWN0KCk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMubWFpbikge1xuICAgICAgICB0aGlzLnNvY2tldC5jb25uZWN0KCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmJpbmRUb3BMZXZlbEV2ZW50cyh7IGRlYWQ6IHRydWUgfSk7XG4gICAgICB9XG4gICAgICB0aGlzLmpvaW5EZWFkVmlldygpO1xuICAgIH07XG4gICAgaWYgKFxuICAgICAgW1wiY29tcGxldGVcIiwgXCJsb2FkZWRcIiwgXCJpbnRlcmFjdGl2ZVwiXS5pbmRleE9mKGRvY3VtZW50LnJlYWR5U3RhdGUpID49IDBcbiAgICApIHtcbiAgICAgIGRvQ29ubmVjdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiRE9NQ29udGVudExvYWRlZFwiLCAoKSA9PiBkb0Nvbm5lY3QoKSk7XG4gICAgfVxuICB9XG5cbiAgZGlzY29ubmVjdChjYWxsYmFjaykge1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnJlbG9hZFdpdGhKaXR0ZXJUaW1lcik7XG4gICAgLy8gcmVtb3ZlIHRoZSBzb2NrZXQgY2xvc2UgbGlzdGVuZXIgdG8gYXZvaWQgdHJ5aW5nIHRvIGhhbmRsZVxuICAgIC8vIGEgc2VydmVyIGNsb3NlIGV2ZW50IHdoZW4gaXQgaXMgYWN0dWFsbHkgY2F1c2VkIGJ5IHVzIGRpc2Nvbm5lY3RpbmdcbiAgICBpZiAodGhpcy5zZXJ2ZXJDbG9zZVJlZikge1xuICAgICAgdGhpcy5zb2NrZXQub2ZmKHRoaXMuc2VydmVyQ2xvc2VSZWYpO1xuICAgICAgdGhpcy5zZXJ2ZXJDbG9zZVJlZiA9IG51bGw7XG4gICAgfVxuICAgIHRoaXMuc29ja2V0LmRpc2Nvbm5lY3QoY2FsbGJhY2spO1xuICB9XG5cbiAgcmVwbGFjZVRyYW5zcG9ydCh0cmFuc3BvcnQpIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5yZWxvYWRXaXRoSml0dGVyVGltZXIpO1xuICAgIHRoaXMuc29ja2V0LnJlcGxhY2VUcmFuc3BvcnQodHJhbnNwb3J0KTtcbiAgICB0aGlzLmNvbm5lY3QoKTtcbiAgfVxuXG4gIGV4ZWNKUyhlbCwgZW5jb2RlZEpTLCBldmVudFR5cGUgPSBudWxsKSB7XG4gICAgY29uc3QgZSA9IG5ldyBDdXN0b21FdmVudChcInBoeDpleGVjXCIsIHsgZGV0YWlsOiB7IHNvdXJjZUVsZW1lbnQ6IGVsIH0gfSk7XG4gICAgdGhpcy5vd25lcihlbCwgKHZpZXcpID0+IEpTLmV4ZWMoZSwgZXZlbnRUeXBlLCBlbmNvZGVkSlMsIHZpZXcsIGVsKSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbiBvYmplY3Qgd2l0aCBtZXRob2RzIHRvIG1hbmlwbHVhdGUgdGhlIERPTSBhbmQgZXhlY3V0ZSBKYXZhU2NyaXB0LlxuICAgKiBUaGUgYXBwbGllZCBjaGFuZ2VzIGludGVncmF0ZSB3aXRoIHNlcnZlciBET00gcGF0Y2hpbmcuXG4gICAqXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL2pzX2NvbW1hbmRzXCIpLkxpdmVTb2NrZXRKU0NvbW1hbmRzfVxuICAgKi9cbiAganMoKSB7XG4gICAgcmV0dXJuIGpzQ29tbWFuZHModGhpcywgXCJqc1wiKTtcbiAgfVxuXG4gIC8vIHByaXZhdGVcblxuICB1bmxvYWQoKSB7XG4gICAgaWYgKHRoaXMudW5sb2FkZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMubWFpbiAmJiB0aGlzLmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgIHRoaXMubG9nKHRoaXMubWFpbiwgXCJzb2NrZXRcIiwgKCkgPT4gW1wiZGlzY29ubmVjdCBmb3IgcGFnZSBuYXZcIl0pO1xuICAgIH1cbiAgICB0aGlzLnVubG9hZGVkID0gdHJ1ZTtcbiAgICB0aGlzLmRlc3Ryb3lBbGxWaWV3cygpO1xuICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICB9XG5cbiAgdHJpZ2dlckRPTShraW5kLCBhcmdzKSB7XG4gICAgdGhpcy5kb21DYWxsYmFja3Nba2luZF0oLi4uYXJncyk7XG4gIH1cblxuICB0aW1lKG5hbWUsIGZ1bmMpIHtcbiAgICBpZiAoIXRoaXMuaXNQcm9maWxlRW5hYmxlZCgpIHx8ICFjb25zb2xlLnRpbWUpIHtcbiAgICAgIHJldHVybiBmdW5jKCk7XG4gICAgfVxuICAgIGNvbnNvbGUudGltZShuYW1lKTtcbiAgICBjb25zdCByZXN1bHQgPSBmdW5jKCk7XG4gICAgY29uc29sZS50aW1lRW5kKG5hbWUpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBsb2codmlldywga2luZCwgbXNnQ2FsbGJhY2spIHtcbiAgICBpZiAodGhpcy52aWV3TG9nZ2VyKSB7XG4gICAgICBjb25zdCBbbXNnLCBvYmpdID0gbXNnQ2FsbGJhY2soKTtcbiAgICAgIHRoaXMudmlld0xvZ2dlcih2aWV3LCBraW5kLCBtc2csIG9iaik7XG4gICAgfSBlbHNlIGlmICh0aGlzLmlzRGVidWdFbmFibGVkKCkpIHtcbiAgICAgIGNvbnN0IFttc2csIG9ial0gPSBtc2dDYWxsYmFjaygpO1xuICAgICAgZGVidWcodmlldywga2luZCwgbXNnLCBvYmopO1xuICAgIH1cbiAgfVxuXG4gIHJlcXVlc3RET01VcGRhdGUoY2FsbGJhY2spIHtcbiAgICB0aGlzLnRyYW5zaXRpb25zLmFmdGVyKGNhbGxiYWNrKTtcbiAgfVxuXG4gIGFzeW5jVHJhbnNpdGlvbihwcm9taXNlKSB7XG4gICAgdGhpcy50cmFuc2l0aW9ucy5hZGRBc3luY1RyYW5zaXRpb24ocHJvbWlzZSk7XG4gIH1cblxuICB0cmFuc2l0aW9uKHRpbWUsIG9uU3RhcnQsIG9uRG9uZSA9IGZ1bmN0aW9uICgpIHt9KSB7XG4gICAgdGhpcy50cmFuc2l0aW9ucy5hZGRUcmFuc2l0aW9uKHRpbWUsIG9uU3RhcnQsIG9uRG9uZSk7XG4gIH1cblxuICBvbkNoYW5uZWwoY2hhbm5lbCwgZXZlbnQsIGNiKSB7XG4gICAgY2hhbm5lbC5vbihldmVudCwgKGRhdGEpID0+IHtcbiAgICAgIGNvbnN0IGxhdGVuY3kgPSB0aGlzLmdldExhdGVuY3lTaW0oKTtcbiAgICAgIGlmICghbGF0ZW5jeSkge1xuICAgICAgICBjYihkYXRhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gY2IoZGF0YSksIGxhdGVuY3kpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcmVsb2FkV2l0aEppdHRlcih2aWV3LCBsb2cpIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5yZWxvYWRXaXRoSml0dGVyVGltZXIpO1xuICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICAgIGNvbnN0IG1pbk1zID0gdGhpcy5yZWxvYWRKaXR0ZXJNaW47XG4gICAgY29uc3QgbWF4TXMgPSB0aGlzLnJlbG9hZEppdHRlck1heDtcbiAgICBsZXQgYWZ0ZXJNcyA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIChtYXhNcyAtIG1pbk1zICsgMSkpICsgbWluTXM7XG4gICAgY29uc3QgdHJpZXMgPSBCcm93c2VyLnVwZGF0ZUxvY2FsKFxuICAgICAgdGhpcy5sb2NhbFN0b3JhZ2UsXG4gICAgICB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUsXG4gICAgICBDT05TRUNVVElWRV9SRUxPQURTLFxuICAgICAgMCxcbiAgICAgIChjb3VudCkgPT4gY291bnQgKyAxLFxuICAgICk7XG4gICAgaWYgKHRyaWVzID49IHRoaXMubWF4UmVsb2Fkcykge1xuICAgICAgYWZ0ZXJNcyA9IHRoaXMuZmFpbHNhZmVKaXR0ZXI7XG4gICAgfVxuICAgIHRoaXMucmVsb2FkV2l0aEppdHRlclRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAvLyBpZiB2aWV3IGhhcyByZWNvdmVyZWQsIHN1Y2ggYXMgdHJhbnNwb3J0IHJlcGxhY2VkLCB0aGVuIGNhbmNlbFxuICAgICAgaWYgKHZpZXcuaXNEZXN0cm95ZWQoKSB8fCB2aWV3LmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdmlldy5kZXN0cm95KCk7XG4gICAgICBsb2dcbiAgICAgICAgPyBsb2coKVxuICAgICAgICA6IHRoaXMubG9nKHZpZXcsIFwiam9pblwiLCAoKSA9PiBbXG4gICAgICAgICAgICBgZW5jb3VudGVyZWQgJHt0cmllc30gY29uc2VjdXRpdmUgcmVsb2Fkc2AsXG4gICAgICAgICAgXSk7XG4gICAgICBpZiAodHJpZXMgPj0gdGhpcy5tYXhSZWxvYWRzKSB7XG4gICAgICAgIHRoaXMubG9nKHZpZXcsIFwiam9pblwiLCAoKSA9PiBbXG4gICAgICAgICAgYGV4Y2VlZGVkICR7dGhpcy5tYXhSZWxvYWRzfSBjb25zZWN1dGl2ZSByZWxvYWRzLiBFbnRlcmluZyBmYWlsc2FmZSBtb2RlYCxcbiAgICAgICAgXSk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5oYXNQZW5kaW5nTGluaygpKSB7XG4gICAgICAgIHdpbmRvdy5sb2NhdGlvbiA9IHRoaXMucGVuZGluZ0xpbms7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7XG4gICAgICB9XG4gICAgfSwgYWZ0ZXJNcyk7XG4gIH1cblxuICBnZXRIb29rRGVmaW5pdGlvbihuYW1lKSB7XG4gICAgaWYgKCFuYW1lKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJldHVybiAoXG4gICAgICB0aGlzLm1heWJlSW50ZXJuYWxIb29rKG5hbWUpIHx8XG4gICAgICB0aGlzLmhvb2tzW25hbWVdIHx8XG4gICAgICB0aGlzLm1heWJlUnVudGltZUhvb2sobmFtZSlcbiAgICApO1xuICB9XG5cbiAgbWF5YmVJbnRlcm5hbEhvb2sobmFtZSkge1xuICAgIHJldHVybiBuYW1lICYmIG5hbWUuc3RhcnRzV2l0aChcIlBob2VuaXguXCIpICYmIEhvb2tzW25hbWUuc3BsaXQoXCIuXCIpWzFdXTtcbiAgfVxuXG4gIG1heWJlUnVudGltZUhvb2sobmFtZSkge1xuICAgIGNvbnN0IHJ1bnRpbWVIb29rID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgIGBzY3JpcHRbJHtQSFhfUlVOVElNRV9IT09LfT1cIiR7Q1NTLmVzY2FwZShuYW1lKX1cIl1gLFxuICAgICk7XG4gICAgaWYgKCFydW50aW1lSG9vaykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgY2FsbGJhY2tzID0gd2luZG93W2BwaHhfaG9va18ke25hbWV9YF07XG4gICAgaWYgKCFjYWxsYmFja3MgfHwgdHlwZW9mIGNhbGxiYWNrcyAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICBsb2dFcnJvcihcImEgcnVudGltZSBob29rIG11c3QgYmUgYSBmdW5jdGlvblwiLCBydW50aW1lSG9vayk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGhvb2tEZWZpbml0b24gPSBjYWxsYmFja3MoKTtcbiAgICBpZiAoXG4gICAgICBob29rRGVmaW5pdG9uICYmXG4gICAgICAodHlwZW9mIGhvb2tEZWZpbml0b24gPT09IFwib2JqZWN0XCIgfHwgdHlwZW9mIGhvb2tEZWZpbml0b24gPT09IFwiZnVuY3Rpb25cIilcbiAgICApIHtcbiAgICAgIHJldHVybiBob29rRGVmaW5pdG9uO1xuICAgIH1cbiAgICBsb2dFcnJvcihcbiAgICAgIFwicnVudGltZSBob29rIG11c3QgcmV0dXJuIGFuIG9iamVjdCB3aXRoIGhvb2sgY2FsbGJhY2tzIG9yIGFuIGluc3RhbmNlIG9mIFZpZXdIb29rXCIsXG4gICAgICBydW50aW1lSG9vayxcbiAgICApO1xuICB9XG5cbiAgaXNVbmxvYWRlZCgpIHtcbiAgICByZXR1cm4gdGhpcy51bmxvYWRlZDtcbiAgfVxuXG4gIGlzQ29ubmVjdGVkKCkge1xuICAgIHJldHVybiB0aGlzLnNvY2tldC5pc0Nvbm5lY3RlZCgpO1xuICB9XG5cbiAgZ2V0QmluZGluZ1ByZWZpeCgpIHtcbiAgICByZXR1cm4gdGhpcy5iaW5kaW5nUHJlZml4O1xuICB9XG5cbiAgYmluZGluZyhraW5kKSB7XG4gICAgcmV0dXJuIGAke3RoaXMuZ2V0QmluZGluZ1ByZWZpeCgpfSR7a2luZH1gO1xuICB9XG5cbiAgY2hhbm5lbCh0b3BpYywgcGFyYW1zKSB7XG4gICAgcmV0dXJuIHRoaXMuc29ja2V0LmNoYW5uZWwodG9waWMsIHBhcmFtcyk7XG4gIH1cblxuICBqb2luRGVhZFZpZXcoKSB7XG4gICAgY29uc3QgYm9keSA9IGRvY3VtZW50LmJvZHk7XG4gICAgaWYgKFxuICAgICAgYm9keSAmJlxuICAgICAgIXRoaXMuaXNQaHhWaWV3KGJvZHkpICYmXG4gICAgICAhdGhpcy5pc1BoeFZpZXcoZG9jdW1lbnQuZmlyc3RFbGVtZW50Q2hpbGQpXG4gICAgKSB7XG4gICAgICBjb25zdCB2aWV3ID0gdGhpcy5uZXdSb290Vmlldyhib2R5KTtcbiAgICAgIHZpZXcuc2V0SHJlZih0aGlzLmdldEhyZWYoKSk7XG4gICAgICB2aWV3LmpvaW5EZWFkKCk7XG4gICAgICBpZiAoIXRoaXMubWFpbikge1xuICAgICAgICB0aGlzLm1haW4gPSB2aWV3O1xuICAgICAgfVxuICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgIHZpZXcuZXhlY05ld01vdW50ZWQoKTtcbiAgICAgICAgLy8gcmVzdG9yZSBzY3JvbGwgcG9zaXRpb24gd2hlbiBuYXZpZ2F0aW5nIGZyb20gYW4gZXh0ZXJuYWwgLyBub24tbGl2ZSBwYWdlXG4gICAgICAgIHRoaXMubWF5YmVTY3JvbGwoaGlzdG9yeS5zdGF0ZT8uc2Nyb2xsKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGpvaW5Sb290Vmlld3MoKSB7XG4gICAgbGV0IHJvb3RzRm91bmQgPSBmYWxzZTtcbiAgICBET00uYWxsKFxuICAgICAgZG9jdW1lbnQsXG4gICAgICBgJHtQSFhfVklFV19TRUxFQ1RPUn06bm90KFske1BIWF9QQVJFTlRfSUR9XSlgLFxuICAgICAgKHJvb3RFbCkgPT4ge1xuICAgICAgICBpZiAoIXRoaXMuZ2V0Um9vdEJ5SWQocm9vdEVsLmlkKSkge1xuICAgICAgICAgIGNvbnN0IHZpZXcgPSB0aGlzLm5ld1Jvb3RWaWV3KHJvb3RFbCk7XG4gICAgICAgICAgLy8gc3RpY2tpZXMgY2Fubm90IGJlIG1vdW50ZWQgYXQgdGhlIHJvdXRlciBhbmQgdGhlcmVmb3JlIHNob3VsZCBub3RcbiAgICAgICAgICAvLyBnZXQgYSBocmVmIHNldCBvbiB0aGVtXG4gICAgICAgICAgaWYgKCFET00uaXNQaHhTdGlja3kocm9vdEVsKSkge1xuICAgICAgICAgICAgdmlldy5zZXRIcmVmKHRoaXMuZ2V0SHJlZigpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmlldy5qb2luKCk7XG4gICAgICAgICAgaWYgKHJvb3RFbC5oYXNBdHRyaWJ1dGUoUEhYX01BSU4pKSB7XG4gICAgICAgICAgICB0aGlzLm1haW4gPSB2aWV3O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByb290c0ZvdW5kID0gdHJ1ZTtcbiAgICAgIH0sXG4gICAgKTtcbiAgICByZXR1cm4gcm9vdHNGb3VuZDtcbiAgfVxuXG4gIHJlZGlyZWN0KHRvLCBmbGFzaCwgcmVsb2FkVG9rZW4pIHtcbiAgICBpZiAocmVsb2FkVG9rZW4pIHtcbiAgICAgIEJyb3dzZXIuc2V0Q29va2llKFBIWF9SRUxPQURfU1RBVFVTLCByZWxvYWRUb2tlbiwgNjApO1xuICAgIH1cbiAgICB0aGlzLnVubG9hZCgpO1xuICAgIEJyb3dzZXIucmVkaXJlY3QodG8sIGZsYXNoKTtcbiAgfVxuXG4gIHJlcGxhY2VNYWluKFxuICAgIGhyZWYsXG4gICAgZmxhc2gsXG4gICAgY2FsbGJhY2sgPSBudWxsLFxuICAgIGxpbmtSZWYgPSB0aGlzLnNldFBlbmRpbmdMaW5rKGhyZWYpLFxuICApIHtcbiAgICBjb25zdCBsaXZlUmVmZXJlciA9IHRoaXMuY3VycmVudExvY2F0aW9uLmhyZWY7XG4gICAgdGhpcy5vdXRnb2luZ01haW5FbCA9IHRoaXMub3V0Z29pbmdNYWluRWwgfHwgdGhpcy5tYWluLmVsO1xuXG4gICAgY29uc3Qgc3RpY2tpZXMgPSBET00uZmluZFBoeFN0aWNreShkb2N1bWVudCkgfHwgW107XG4gICAgY29uc3QgcmVtb3ZlRWxzID0gRE9NLmFsbChcbiAgICAgIHRoaXMub3V0Z29pbmdNYWluRWwsXG4gICAgICBgWyR7dGhpcy5iaW5kaW5nKFwicmVtb3ZlXCIpfV1gLFxuICAgICkuZmlsdGVyKChlbCkgPT4gIURPTS5pc0NoaWxkT2ZBbnkoZWwsIHN0aWNraWVzKSk7XG5cbiAgICBjb25zdCBuZXdNYWluRWwgPSBET00uY2xvbmVOb2RlKHRoaXMub3V0Z29pbmdNYWluRWwsIFwiXCIpO1xuICAgIHRoaXMubWFpbi5zaG93TG9hZGVyKHRoaXMubG9hZGVyVGltZW91dCk7XG4gICAgdGhpcy5tYWluLmRlc3Ryb3koKTtcblxuICAgIHRoaXMubWFpbiA9IHRoaXMubmV3Um9vdFZpZXcobmV3TWFpbkVsLCBmbGFzaCwgbGl2ZVJlZmVyZXIpO1xuICAgIHRoaXMubWFpbi5zZXRSZWRpcmVjdChocmVmKTtcbiAgICB0aGlzLnRyYW5zaXRpb25SZW1vdmVzKHJlbW92ZUVscyk7XG4gICAgdGhpcy5tYWluLmpvaW4oKGpvaW5Db3VudCwgb25Eb25lKSA9PiB7XG4gICAgICBpZiAoam9pbkNvdW50ID09PSAxICYmIHRoaXMuY29tbWl0UGVuZGluZ0xpbmsobGlua1JlZikpIHtcbiAgICAgICAgdGhpcy5yZXF1ZXN0RE9NVXBkYXRlKCgpID0+IHtcbiAgICAgICAgICAvLyByZW1vdmUgcGh4LXJlbW92ZSBlbHMgcmlnaHQgYmVmb3JlIHdlIHJlcGxhY2UgdGhlIG1haW4gZWxlbWVudFxuICAgICAgICAgIHJlbW92ZUVscy5mb3JFYWNoKChlbCkgPT4gZWwucmVtb3ZlKCkpO1xuICAgICAgICAgIHN0aWNraWVzLmZvckVhY2goKGVsKSA9PiBuZXdNYWluRWwuYXBwZW5kQ2hpbGQoZWwpKTtcbiAgICAgICAgICB0aGlzLm91dGdvaW5nTWFpbkVsLnJlcGxhY2VXaXRoKG5ld01haW5FbCk7XG4gICAgICAgICAgdGhpcy5vdXRnb2luZ01haW5FbCA9IG51bGw7XG4gICAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2sobGlua1JlZik7XG4gICAgICAgICAgb25Eb25lKCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgdHJhbnNpdGlvblJlbW92ZXMoZWxlbWVudHMsIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgcmVtb3ZlQXR0ciA9IHRoaXMuYmluZGluZyhcInJlbW92ZVwiKTtcbiAgICBjb25zdCBzaWxlbmNlRXZlbnRzID0gKGUpID0+IHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgfTtcbiAgICBlbGVtZW50cy5mb3JFYWNoKChlbCkgPT4ge1xuICAgICAgLy8gcHJldmVudCBhbGwgbGlzdGVuZXJzIHdlIGNhcmUgYWJvdXQgZnJvbSBidWJibGluZyB0byB3aW5kb3dcbiAgICAgIC8vIHNpbmNlIHdlIGFyZSByZW1vdmluZyB0aGUgZWxlbWVudFxuICAgICAgZm9yIChjb25zdCBldmVudCBvZiB0aGlzLmJvdW5kRXZlbnROYW1lcykge1xuICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKGV2ZW50LCBzaWxlbmNlRXZlbnRzLCB0cnVlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZXhlY0pTKGVsLCBlbC5nZXRBdHRyaWJ1dGUocmVtb3ZlQXR0ciksIFwicmVtb3ZlXCIpO1xuICAgIH0pO1xuICAgIC8vIHJlbW92ZSB0aGUgc2lsZW5jZWQgbGlzdGVuZXJzIHdoZW4gdHJhbnNpdGlvbnMgYXJlIGRvbmUgaW5jYXNlIHRoZSBlbGVtZW50IGlzIHJlLXVzZWRcbiAgICAvLyBhbmQgY2FsbCBjYWxsZXIncyBjYWxsYmFjayBhcyBzb29uIGFzIHdlIGFyZSBkb25lIHdpdGggdHJhbnNpdGlvbnNcbiAgICB0aGlzLnJlcXVlc3RET01VcGRhdGUoKCkgPT4ge1xuICAgICAgZWxlbWVudHMuZm9yRWFjaCgoZWwpID0+IHtcbiAgICAgICAgZm9yIChjb25zdCBldmVudCBvZiB0aGlzLmJvdW5kRXZlbnROYW1lcykge1xuICAgICAgICAgIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnQsIHNpbGVuY2VFdmVudHMsIHRydWUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKCk7XG4gICAgfSk7XG4gIH1cblxuICBpc1BoeFZpZXcoZWwpIHtcbiAgICByZXR1cm4gZWwuZ2V0QXR0cmlidXRlICYmIGVsLmdldEF0dHJpYnV0ZShQSFhfU0VTU0lPTikgIT09IG51bGw7XG4gIH1cblxuICBuZXdSb290VmlldyhlbCwgZmxhc2gsIGxpdmVSZWZlcmVyKSB7XG4gICAgY29uc3QgdmlldyA9IG5ldyBWaWV3KGVsLCB0aGlzLCBudWxsLCBmbGFzaCwgbGl2ZVJlZmVyZXIpO1xuICAgIHRoaXMucm9vdHNbdmlldy5pZF0gPSB2aWV3O1xuICAgIHJldHVybiB2aWV3O1xuICB9XG5cbiAgb3duZXIoY2hpbGRFbCwgY2FsbGJhY2spIHtcbiAgICBsZXQgdmlldztcbiAgICBjb25zdCB2aWV3RWwgPSBET00uY2xvc2VzdFZpZXdFbChjaGlsZEVsKTtcbiAgICBpZiAodmlld0VsKSB7XG4gICAgICAvLyBpdCBjYW4gaGFwcGVuIHRoYXQgd2UgZmluZCBhIHZpZXcgdGhhdCBpcyBhbHJlYWR5IGRlc3Ryb3llZDtcbiAgICAgIC8vIGluIHRoYXQgY2FzZSB3ZSBETyBOT1Qgd2FudCB0byBmYWxsYmFjayB0byB0aGUgbWFpbiBlbGVtZW50XG4gICAgICB2aWV3ID0gdGhpcy5nZXRWaWV3QnlFbCh2aWV3RWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2aWV3ID0gdGhpcy5tYWluO1xuICAgIH1cbiAgICByZXR1cm4gdmlldyAmJiBjYWxsYmFjayA/IGNhbGxiYWNrKHZpZXcpIDogdmlldztcbiAgfVxuXG4gIHdpdGhpbk93bmVycyhjaGlsZEVsLCBjYWxsYmFjaykge1xuICAgIHRoaXMub3duZXIoY2hpbGRFbCwgKHZpZXcpID0+IGNhbGxiYWNrKHZpZXcsIGNoaWxkRWwpKTtcbiAgfVxuXG4gIGdldFZpZXdCeUVsKGVsKSB7XG4gICAgY29uc3Qgcm9vdElkID0gZWwuZ2V0QXR0cmlidXRlKFBIWF9ST09UX0lEKTtcbiAgICByZXR1cm4gbWF5YmUodGhpcy5nZXRSb290QnlJZChyb290SWQpLCAocm9vdCkgPT5cbiAgICAgIHJvb3QuZ2V0RGVzY2VuZGVudEJ5RWwoZWwpLFxuICAgICk7XG4gIH1cblxuICBnZXRSb290QnlJZChpZCkge1xuICAgIHJldHVybiB0aGlzLnJvb3RzW2lkXTtcbiAgfVxuXG4gIGRlc3Ryb3lBbGxWaWV3cygpIHtcbiAgICBmb3IgKGNvbnN0IGlkIGluIHRoaXMucm9vdHMpIHtcbiAgICAgIHRoaXMucm9vdHNbaWRdLmRlc3Ryb3koKTtcbiAgICAgIGRlbGV0ZSB0aGlzLnJvb3RzW2lkXTtcbiAgICB9XG4gICAgdGhpcy5tYWluID0gbnVsbDtcbiAgfVxuXG4gIGRlc3Ryb3lWaWV3QnlFbChlbCkge1xuICAgIGNvbnN0IHJvb3QgPSB0aGlzLmdldFJvb3RCeUlkKGVsLmdldEF0dHJpYnV0ZShQSFhfUk9PVF9JRCkpO1xuICAgIGlmIChyb290ICYmIHJvb3QuaWQgPT09IGVsLmlkKSB7XG4gICAgICByb290LmRlc3Ryb3koKTtcbiAgICAgIGRlbGV0ZSB0aGlzLnJvb3RzW3Jvb3QuaWRdO1xuICAgIH0gZWxzZSBpZiAocm9vdCkge1xuICAgICAgcm9vdC5kZXN0cm95RGVzY2VuZGVudChlbC5pZCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0QWN0aXZlRWxlbWVudCgpIHtcbiAgICByZXR1cm4gZG9jdW1lbnQuYWN0aXZlRWxlbWVudDtcbiAgfVxuXG4gIGRyb3BBY3RpdmVFbGVtZW50KHZpZXcpIHtcbiAgICBpZiAodGhpcy5wcmV2QWN0aXZlICYmIHZpZXcub3duc0VsZW1lbnQodGhpcy5wcmV2QWN0aXZlKSkge1xuICAgICAgdGhpcy5wcmV2QWN0aXZlID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICByZXN0b3JlUHJldmlvdXNseUFjdGl2ZUZvY3VzKCkge1xuICAgIGlmIChcbiAgICAgIHRoaXMucHJldkFjdGl2ZSAmJlxuICAgICAgdGhpcy5wcmV2QWN0aXZlICE9PSBkb2N1bWVudC5ib2R5ICYmXG4gICAgICB0aGlzLnByZXZBY3RpdmUgaW5zdGFuY2VvZiBIVE1MRWxlbWVudFxuICAgICkge1xuICAgICAgdGhpcy5wcmV2QWN0aXZlLmZvY3VzKCk7XG4gICAgfVxuICB9XG5cbiAgYmx1ckFjdGl2ZUVsZW1lbnQoKSB7XG4gICAgdGhpcy5wcmV2QWN0aXZlID0gdGhpcy5nZXRBY3RpdmVFbGVtZW50KCk7XG4gICAgaWYgKFxuICAgICAgdGhpcy5wcmV2QWN0aXZlICE9PSBkb2N1bWVudC5ib2R5ICYmXG4gICAgICB0aGlzLnByZXZBY3RpdmUgaW5zdGFuY2VvZiBIVE1MRWxlbWVudFxuICAgICkge1xuICAgICAgdGhpcy5wcmV2QWN0aXZlLmJsdXIoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHt7ZGVhZD86IGJvb2xlYW59fSBbb3B0aW9ucz17fV1cbiAgICovXG4gIGJpbmRUb3BMZXZlbEV2ZW50cyh7IGRlYWQgfSA9IHt9KSB7XG4gICAgaWYgKHRoaXMuYm91bmRUb3BMZXZlbEV2ZW50cykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuYm91bmRUb3BMZXZlbEV2ZW50cyA9IHRydWU7XG4gICAgLy8gZW50ZXIgZmFpbHNhZmUgcmVsb2FkIGlmIHNlcnZlciBoYXMgZ29uZSBhd2F5IGludGVudGlvbmFsbHksIHN1Y2ggYXMgXCJkaXNjb25uZWN0XCIgYnJvYWRjYXN0XG4gICAgdGhpcy5zZXJ2ZXJDbG9zZVJlZiA9IHRoaXMuc29ja2V0Lm9uQ2xvc2UoKGV2ZW50KSA9PiB7XG4gICAgICAvLyBmYWlsc2FmZSByZWxvYWQgaWYgbm9ybWFsIGNsb3N1cmUgYW5kIHdlIHN0aWxsIGhhdmUgYSBtYWluIExWXG4gICAgICBpZiAoZXZlbnQgJiYgZXZlbnQuY29kZSA9PT0gMTAwMCAmJiB0aGlzLm1haW4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVsb2FkV2l0aEppdHRlcih0aGlzLm1haW4pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGRvY3VtZW50LmJvZHkuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIGZ1bmN0aW9uICgpIHt9KTsgLy8gZW5zdXJlIGFsbCBjbGljayBldmVudHMgYnViYmxlIGZvciBtb2JpbGUgU2FmYXJpXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBcInBhZ2VzaG93XCIsXG4gICAgICAoZSkgPT4ge1xuICAgICAgICBpZiAoZS5wZXJzaXN0ZWQpIHtcbiAgICAgICAgICAvLyByZWxvYWQgcGFnZSBpZiBiZWluZyByZXN0b3JlZCBmcm9tIGJhY2svZm9yd2FyZCBjYWNoZVxuICAgICAgICAgIHRoaXMuZ2V0U29ja2V0KCkuZGlzY29ubmVjdCgpO1xuICAgICAgICAgIHRoaXMud2l0aFBhZ2VMb2FkaW5nKHsgdG86IHdpbmRvdy5sb2NhdGlvbi5ocmVmLCBraW5kOiBcInJlZGlyZWN0XCIgfSk7XG4gICAgICAgICAgd2luZG93LmxvY2F0aW9uLnJlbG9hZCgpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgdHJ1ZSxcbiAgICApO1xuICAgIGlmICghZGVhZCkge1xuICAgICAgdGhpcy5iaW5kTmF2KCk7XG4gICAgfVxuICAgIHRoaXMuYmluZENsaWNrcygpO1xuICAgIGlmICghZGVhZCkge1xuICAgICAgdGhpcy5iaW5kRm9ybXMoKTtcbiAgICB9XG4gICAgdGhpcy5iaW5kKFxuICAgICAgeyBrZXl1cDogXCJrZXl1cFwiLCBrZXlkb3duOiBcImtleWRvd25cIiB9LFxuICAgICAgKGUsIHR5cGUsIHZpZXcsIHRhcmdldEVsLCBwaHhFdmVudCwgX3BoeFRhcmdldCkgPT4ge1xuICAgICAgICBjb25zdCBtYXRjaEtleSA9IHRhcmdldEVsLmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoUEhYX0tFWSkpO1xuICAgICAgICBjb25zdCBwcmVzc2VkS2V5ID0gZS5rZXkgJiYgZS5rZXkudG9Mb3dlckNhc2UoKTsgLy8gY2hyb21lIGNsaWNrZWQgYXV0b2NvbXBsZXRlcyBzZW5kIGEga2V5ZG93biB3aXRob3V0IGtleVxuICAgICAgICBpZiAobWF0Y2hLZXkgJiYgbWF0Y2hLZXkudG9Mb3dlckNhc2UoKSAhPT0gcHJlc3NlZEtleSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGRhdGEgPSB7IGtleTogZS5rZXksIC4uLnRoaXMuZXZlbnRNZXRhKHR5cGUsIGUsIHRhcmdldEVsKSB9O1xuICAgICAgICBKUy5leGVjKGUsIHR5cGUsIHBoeEV2ZW50LCB2aWV3LCB0YXJnZXRFbCwgW1wicHVzaFwiLCB7IGRhdGEgfV0pO1xuICAgICAgfSxcbiAgICApO1xuICAgIHRoaXMuYmluZChcbiAgICAgIHsgYmx1cjogXCJmb2N1c291dFwiLCBmb2N1czogXCJmb2N1c2luXCIgfSxcbiAgICAgIChlLCB0eXBlLCB2aWV3LCB0YXJnZXRFbCwgcGh4RXZlbnQsIHBoeFRhcmdldCkgPT4ge1xuICAgICAgICBpZiAoIXBoeFRhcmdldCkge1xuICAgICAgICAgIGNvbnN0IGRhdGEgPSB7IGtleTogZS5rZXksIC4uLnRoaXMuZXZlbnRNZXRhKHR5cGUsIGUsIHRhcmdldEVsKSB9O1xuICAgICAgICAgIEpTLmV4ZWMoZSwgdHlwZSwgcGh4RXZlbnQsIHZpZXcsIHRhcmdldEVsLCBbXCJwdXNoXCIsIHsgZGF0YSB9XSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgKTtcbiAgICB0aGlzLmJpbmQoXG4gICAgICB7IGJsdXI6IFwiYmx1clwiLCBmb2N1czogXCJmb2N1c1wiIH0sXG4gICAgICAoZSwgdHlwZSwgdmlldywgdGFyZ2V0RWwsIHBoeEV2ZW50LCBwaHhUYXJnZXQpID0+IHtcbiAgICAgICAgLy8gYmx1ciBhbmQgZm9jdXMgYXJlIHRyaWdnZXJlZCBvbiBkb2N1bWVudCBhbmQgd2luZG93LiBEaXNjYXJkIG9uZSB0byBhdm9pZCBkdXBzXG4gICAgICAgIGlmIChwaHhUYXJnZXQgPT09IFwid2luZG93XCIpIHtcbiAgICAgICAgICBjb25zdCBkYXRhID0gdGhpcy5ldmVudE1ldGEodHlwZSwgZSwgdGFyZ2V0RWwpO1xuICAgICAgICAgIEpTLmV4ZWMoZSwgdHlwZSwgcGh4RXZlbnQsIHZpZXcsIHRhcmdldEVsLCBbXCJwdXNoXCIsIHsgZGF0YSB9XSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgKTtcbiAgICB0aGlzLm9uKFwiZHJhZ292ZXJcIiwgKGUpID0+IGUucHJldmVudERlZmF1bHQoKSk7XG4gICAgdGhpcy5vbihcImRyb3BcIiwgKGUpID0+IHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGNvbnN0IGRyb3BUYXJnZXRJZCA9IG1heWJlKFxuICAgICAgICBjbG9zZXN0UGh4QmluZGluZyhlLnRhcmdldCwgdGhpcy5iaW5kaW5nKFBIWF9EUk9QX1RBUkdFVCkpLFxuICAgICAgICAodHJ1ZVRhcmdldCkgPT4ge1xuICAgICAgICAgIHJldHVybiB0cnVlVGFyZ2V0LmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoUEhYX0RST1BfVEFSR0VUKSk7XG4gICAgICAgIH0sXG4gICAgICApO1xuICAgICAgY29uc3QgZHJvcFRhcmdldCA9IGRyb3BUYXJnZXRJZCAmJiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChkcm9wVGFyZ2V0SWQpO1xuICAgICAgY29uc3QgZmlsZXMgPSBBcnJheS5mcm9tKGUuZGF0YVRyYW5zZmVyLmZpbGVzIHx8IFtdKTtcbiAgICAgIGlmIChcbiAgICAgICAgIWRyb3BUYXJnZXQgfHxcbiAgICAgICAgIShkcm9wVGFyZ2V0IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCkgfHxcbiAgICAgICAgZHJvcFRhcmdldC5kaXNhYmxlZCB8fFxuICAgICAgICBmaWxlcy5sZW5ndGggPT09IDAgfHxcbiAgICAgICAgIShkcm9wVGFyZ2V0LmZpbGVzIGluc3RhbmNlb2YgRmlsZUxpc3QpXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBMaXZlVXBsb2FkZXIudHJhY2tGaWxlcyhkcm9wVGFyZ2V0LCBmaWxlcywgZS5kYXRhVHJhbnNmZXIpO1xuICAgICAgZHJvcFRhcmdldC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcImlucHV0XCIsIHsgYnViYmxlczogdHJ1ZSB9KSk7XG4gICAgfSk7XG4gICAgdGhpcy5vbihQSFhfVFJBQ0tfVVBMT0FEUywgKGUpID0+IHtcbiAgICAgIGNvbnN0IHVwbG9hZFRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgaWYgKCFET00uaXNVcGxvYWRJbnB1dCh1cGxvYWRUYXJnZXQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZpbGVzID0gQXJyYXkuZnJvbShlLmRldGFpbC5maWxlcyB8fCBbXSkuZmlsdGVyKFxuICAgICAgICAoZikgPT4gZiBpbnN0YW5jZW9mIEZpbGUgfHwgZiBpbnN0YW5jZW9mIEJsb2IsXG4gICAgICApO1xuICAgICAgTGl2ZVVwbG9hZGVyLnRyYWNrRmlsZXModXBsb2FkVGFyZ2V0LCBmaWxlcyk7XG4gICAgICB1cGxvYWRUYXJnZXQuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJpbnB1dFwiLCB7IGJ1YmJsZXM6IHRydWUgfSkpO1xuICAgIH0pO1xuICB9XG5cbiAgZXZlbnRNZXRhKGV2ZW50TmFtZSwgZSwgdGFyZ2V0RWwpIHtcbiAgICBjb25zdCBjYWxsYmFjayA9IHRoaXMubWV0YWRhdGFDYWxsYmFja3NbZXZlbnROYW1lXTtcbiAgICByZXR1cm4gY2FsbGJhY2sgPyBjYWxsYmFjayhlLCB0YXJnZXRFbCkgOiB7fTtcbiAgfVxuXG4gIHNldFBlbmRpbmdMaW5rKGhyZWYpIHtcbiAgICB0aGlzLmxpbmtSZWYrKztcbiAgICB0aGlzLnBlbmRpbmdMaW5rID0gaHJlZjtcbiAgICB0aGlzLnJlc2V0UmVsb2FkU3RhdHVzKCk7XG4gICAgcmV0dXJuIHRoaXMubGlua1JlZjtcbiAgfVxuXG4gIC8vIGFueXRpbWUgd2UgYXJlIG5hdmlnYXRpbmcgb3IgY29ubmVjdGluZywgZHJvcCByZWxvYWQgY29va2llIGluIGNhc2VcbiAgLy8gd2UgaXNzdWUgdGhlIGNvb2tpZSBidXQgdGhlIG5leHQgcmVxdWVzdCB3YXMgaW50ZXJydXB0ZWQgYW5kIHRoZSBzZXJ2ZXIgbmV2ZXIgZHJvcHBlZCBpdFxuICByZXNldFJlbG9hZFN0YXR1cygpIHtcbiAgICBCcm93c2VyLmRlbGV0ZUNvb2tpZShQSFhfUkVMT0FEX1NUQVRVUyk7XG4gIH1cblxuICBjb21taXRQZW5kaW5nTGluayhsaW5rUmVmKSB7XG4gICAgaWYgKHRoaXMubGlua1JlZiAhPT0gbGlua1JlZikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmhyZWYgPSB0aGlzLnBlbmRpbmdMaW5rO1xuICAgICAgdGhpcy5wZW5kaW5nTGluayA9IG51bGw7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBnZXRIcmVmKCkge1xuICAgIHJldHVybiB0aGlzLmhyZWY7XG4gIH1cblxuICBoYXNQZW5kaW5nTGluaygpIHtcbiAgICByZXR1cm4gISF0aGlzLnBlbmRpbmdMaW5rO1xuICB9XG5cbiAgYmluZChldmVudHMsIGNhbGxiYWNrKSB7XG4gICAgZm9yIChjb25zdCBldmVudCBpbiBldmVudHMpIHtcbiAgICAgIGNvbnN0IGJyb3dzZXJFdmVudE5hbWUgPSBldmVudHNbZXZlbnRdO1xuXG4gICAgICB0aGlzLm9uKGJyb3dzZXJFdmVudE5hbWUsIChlKSA9PiB7XG4gICAgICAgIGNvbnN0IGJpbmRpbmcgPSB0aGlzLmJpbmRpbmcoZXZlbnQpO1xuICAgICAgICBjb25zdCB3aW5kb3dCaW5kaW5nID0gdGhpcy5iaW5kaW5nKGB3aW5kb3ctJHtldmVudH1gKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0UGh4RXZlbnQgPVxuICAgICAgICAgIGUudGFyZ2V0LmdldEF0dHJpYnV0ZSAmJiBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoYmluZGluZyk7XG4gICAgICAgIGlmICh0YXJnZXRQaHhFdmVudCkge1xuICAgICAgICAgIHRoaXMuZGVib3VuY2UoZS50YXJnZXQsIGUsIGJyb3dzZXJFdmVudE5hbWUsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMud2l0aGluT3duZXJzKGUudGFyZ2V0LCAodmlldykgPT4ge1xuICAgICAgICAgICAgICBjYWxsYmFjayhlLCBldmVudCwgdmlldywgZS50YXJnZXQsIHRhcmdldFBoeEV2ZW50LCBudWxsKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIERPTS5hbGwoZG9jdW1lbnQsIGBbJHt3aW5kb3dCaW5kaW5nfV1gLCAoZWwpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBoeEV2ZW50ID0gZWwuZ2V0QXR0cmlidXRlKHdpbmRvd0JpbmRpbmcpO1xuICAgICAgICAgICAgdGhpcy5kZWJvdW5jZShlbCwgZSwgYnJvd3NlckV2ZW50TmFtZSwgKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLndpdGhpbk93bmVycyhlbCwgKHZpZXcpID0+IHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlLCBldmVudCwgdmlldywgZWwsIHBoeEV2ZW50LCBcIndpbmRvd1wiKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgYmluZENsaWNrcygpIHtcbiAgICB0aGlzLm9uKFwibW91c2Vkb3duXCIsIChlKSA9PiAodGhpcy5jbGlja1N0YXJ0ZWRBdFRhcmdldCA9IGUudGFyZ2V0KSk7XG4gICAgdGhpcy5iaW5kQ2xpY2soXCJjbGlja1wiLCBcImNsaWNrXCIpO1xuICB9XG5cbiAgYmluZENsaWNrKGV2ZW50TmFtZSwgYmluZGluZ05hbWUpIHtcbiAgICBjb25zdCBjbGljayA9IHRoaXMuYmluZGluZyhiaW5kaW5nTmFtZSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBldmVudE5hbWUsXG4gICAgICAoZSkgPT4ge1xuICAgICAgICBsZXQgdGFyZ2V0ID0gbnVsbDtcbiAgICAgICAgLy8gYSBzeW50aGV0aWMgY2xpY2sgZXZlbnQgKGRldGFpbCAwKSB3aWxsIG5vdCBoYXZlIGNhdXNlZCBhIG1vdXNlZG93biBldmVudCxcbiAgICAgICAgLy8gdGhlcmVmb3JlIHRoZSBjbGlja1N0YXJ0ZWRBdFRhcmdldCBpcyBzdGFsZVxuICAgICAgICBpZiAoZS5kZXRhaWwgPT09IDApIHRoaXMuY2xpY2tTdGFydGVkQXRUYXJnZXQgPSBlLnRhcmdldDtcbiAgICAgICAgY29uc3QgY2xpY2tTdGFydGVkQXRUYXJnZXQgPSB0aGlzLmNsaWNrU3RhcnRlZEF0VGFyZ2V0IHx8IGUudGFyZ2V0O1xuICAgICAgICAvLyB3aGVuIHNlYXJjaGluZyB0aGUgdGFyZ2V0IGZvciB0aGUgY2xpY2sgZXZlbnQsIHdlIGFsd2F5cyB3YW50IHRvXG4gICAgICAgIC8vIHVzZSB0aGUgYWN0dWFsIGV2ZW50IHRhcmdldCwgc2VlICMzMzcyXG4gICAgICAgIHRhcmdldCA9IGNsb3Nlc3RQaHhCaW5kaW5nKGUudGFyZ2V0LCBjbGljayk7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hDbGlja0F3YXkoZSwgY2xpY2tTdGFydGVkQXRUYXJnZXQpO1xuICAgICAgICB0aGlzLmNsaWNrU3RhcnRlZEF0VGFyZ2V0ID0gbnVsbDtcbiAgICAgICAgY29uc3QgcGh4RXZlbnQgPSB0YXJnZXQgJiYgdGFyZ2V0LmdldEF0dHJpYnV0ZShjbGljayk7XG4gICAgICAgIGlmICghcGh4RXZlbnQpIHtcbiAgICAgICAgICBpZiAoRE9NLmlzTmV3UGFnZUNsaWNrKGUsIHdpbmRvdy5sb2NhdGlvbikpIHtcbiAgICAgICAgICAgIHRoaXMudW5sb2FkKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0YXJnZXQuZ2V0QXR0cmlidXRlKFwiaHJlZlwiKSA9PT0gXCIjXCIpIHtcbiAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBub29wIGlmIHdlIGFyZSBpbiB0aGUgbWlkZGxlIG9mIGF3YWl0aW5nIGFuIGFjayBmb3IgdGhpcyBlbCBhbHJlYWR5XG4gICAgICAgIGlmICh0YXJnZXQuaGFzQXR0cmlidXRlKFBIWF9SRUZfU1JDKSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZGVib3VuY2UodGFyZ2V0LCBlLCBcImNsaWNrXCIsICgpID0+IHtcbiAgICAgICAgICB0aGlzLndpdGhpbk93bmVycyh0YXJnZXQsICh2aWV3KSA9PiB7XG4gICAgICAgICAgICBKUy5leGVjKGUsIFwiY2xpY2tcIiwgcGh4RXZlbnQsIHZpZXcsIHRhcmdldCwgW1xuICAgICAgICAgICAgICBcInB1c2hcIixcbiAgICAgICAgICAgICAgeyBkYXRhOiB0aGlzLmV2ZW50TWV0YShcImNsaWNrXCIsIGUsIHRhcmdldCkgfSxcbiAgICAgICAgICAgIF0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICBmYWxzZSxcbiAgICApO1xuICB9XG5cbiAgZGlzcGF0Y2hDbGlja0F3YXkoZSwgY2xpY2tTdGFydGVkQXQpIHtcbiAgICBjb25zdCBwaHhDbGlja0F3YXkgPSB0aGlzLmJpbmRpbmcoXCJjbGljay1hd2F5XCIpO1xuICAgIERPTS5hbGwoZG9jdW1lbnQsIGBbJHtwaHhDbGlja0F3YXl9XWAsIChlbCkgPT4ge1xuICAgICAgaWYgKCEoZWwuaXNTYW1lTm9kZShjbGlja1N0YXJ0ZWRBdCkgfHwgZWwuY29udGFpbnMoY2xpY2tTdGFydGVkQXQpKSkge1xuICAgICAgICB0aGlzLndpdGhpbk93bmVycyhlbCwgKHZpZXcpID0+IHtcbiAgICAgICAgICBjb25zdCBwaHhFdmVudCA9IGVsLmdldEF0dHJpYnV0ZShwaHhDbGlja0F3YXkpO1xuICAgICAgICAgIGlmIChKUy5pc1Zpc2libGUoZWwpICYmIEpTLmlzSW5WaWV3cG9ydChlbCkpIHtcbiAgICAgICAgICAgIEpTLmV4ZWMoZSwgXCJjbGlja1wiLCBwaHhFdmVudCwgdmlldywgZWwsIFtcbiAgICAgICAgICAgICAgXCJwdXNoXCIsXG4gICAgICAgICAgICAgIHsgZGF0YTogdGhpcy5ldmVudE1ldGEoXCJjbGlja1wiLCBlLCBlLnRhcmdldCkgfSxcbiAgICAgICAgICAgIF0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBiaW5kTmF2KCkge1xuICAgIGlmICghQnJvd3Nlci5jYW5QdXNoU3RhdGUoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoaGlzdG9yeS5zY3JvbGxSZXN0b3JhdGlvbikge1xuICAgICAgaGlzdG9yeS5zY3JvbGxSZXN0b3JhdGlvbiA9IFwibWFudWFsXCI7XG4gICAgfVxuICAgIGxldCBzY3JvbGxUaW1lciA9IG51bGw7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgKF9lKSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQoc2Nyb2xsVGltZXIpO1xuICAgICAgc2Nyb2xsVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgQnJvd3Nlci51cGRhdGVDdXJyZW50U3RhdGUoKHN0YXRlKSA9PlxuICAgICAgICAgIE9iamVjdC5hc3NpZ24oc3RhdGUsIHsgc2Nyb2xsOiB3aW5kb3cuc2Nyb2xsWSB9KSxcbiAgICAgICAgKTtcbiAgICAgIH0sIDEwMCk7XG4gICAgfSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBcInBvcHN0YXRlXCIsXG4gICAgICAoZXZlbnQpID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLnJlZ2lzdGVyTmV3TG9jYXRpb24od2luZG93LmxvY2F0aW9uKSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IHR5cGUsIGJhY2tUeXBlLCBpZCwgc2Nyb2xsLCBwb3NpdGlvbiB9ID0gZXZlbnQuc3RhdGUgfHwge307XG4gICAgICAgIGNvbnN0IGhyZWYgPSB3aW5kb3cubG9jYXRpb24uaHJlZjtcblxuICAgICAgICAvLyBDb21wYXJlIHBvc2l0aW9ucyB0byBkZXRlcm1pbmUgZGlyZWN0aW9uXG4gICAgICAgIGNvbnN0IGlzRm9yd2FyZCA9IHBvc2l0aW9uID4gdGhpcy5jdXJyZW50SGlzdG9yeVBvc2l0aW9uO1xuICAgICAgICBjb25zdCBuYXZUeXBlID0gaXNGb3J3YXJkID8gdHlwZSA6IGJhY2tUeXBlIHx8IHR5cGU7XG5cbiAgICAgICAgLy8gVXBkYXRlIGN1cnJlbnQgcG9zaXRpb25cbiAgICAgICAgdGhpcy5jdXJyZW50SGlzdG9yeVBvc2l0aW9uID0gcG9zaXRpb24gfHwgMDtcbiAgICAgICAgdGhpcy5zZXNzaW9uU3RvcmFnZS5zZXRJdGVtKFxuICAgICAgICAgIFBIWF9MVl9ISVNUT1JZX1BPU0lUSU9OLFxuICAgICAgICAgIHRoaXMuY3VycmVudEhpc3RvcnlQb3NpdGlvbi50b1N0cmluZygpLFxuICAgICAgICApO1xuXG4gICAgICAgIERPTS5kaXNwYXRjaEV2ZW50KHdpbmRvdywgXCJwaHg6bmF2aWdhdGVcIiwge1xuICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgaHJlZixcbiAgICAgICAgICAgIHBhdGNoOiBuYXZUeXBlID09PSBcInBhdGNoXCIsXG4gICAgICAgICAgICBwb3A6IHRydWUsXG4gICAgICAgICAgICBkaXJlY3Rpb246IGlzRm9yd2FyZCA/IFwiZm9yd2FyZFwiIDogXCJiYWNrd2FyZFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnJlcXVlc3RET01VcGRhdGUoKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5tYXliZVNjcm9sbChzY3JvbGwpO1xuICAgICAgICAgIH07XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5tYWluLmlzQ29ubmVjdGVkKCkgJiZcbiAgICAgICAgICAgIG5hdlR5cGUgPT09IFwicGF0Y2hcIiAmJlxuICAgICAgICAgICAgaWQgPT09IHRoaXMubWFpbi5pZFxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy5tYWluLnB1c2hMaW5rUGF0Y2goZXZlbnQsIGhyZWYsIG51bGwsIGNhbGxiYWNrKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5yZXBsYWNlTWFpbihocmVmLCBudWxsLCBjYWxsYmFjayk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgXCJjbGlja1wiLFxuICAgICAgKGUpID0+IHtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gY2xvc2VzdFBoeEJpbmRpbmcoZS50YXJnZXQsIFBIWF9MSVZFX0xJTkspO1xuICAgICAgICBjb25zdCB0eXBlID0gdGFyZ2V0ICYmIHRhcmdldC5nZXRBdHRyaWJ1dGUoUEhYX0xJVkVfTElOSyk7XG4gICAgICAgIGlmICghdHlwZSB8fCAhdGhpcy5pc0Nvbm5lY3RlZCgpIHx8ICF0aGlzLm1haW4gfHwgRE9NLndhbnRzTmV3VGFiKGUpKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gV2hlbiB3cmFwcGluZyBhbiBTVkcgZWxlbWVudCBpbiBhbiBhbmNob3IgdGFnLCB0aGUgaHJlZiBjYW4gYmUgYW4gU1ZHQW5pbWF0ZWRTdHJpbmdcbiAgICAgICAgY29uc3QgaHJlZiA9XG4gICAgICAgICAgdGFyZ2V0LmhyZWYgaW5zdGFuY2VvZiBTVkdBbmltYXRlZFN0cmluZ1xuICAgICAgICAgICAgPyB0YXJnZXQuaHJlZi5iYXNlVmFsXG4gICAgICAgICAgICA6IHRhcmdldC5ocmVmO1xuXG4gICAgICAgIGNvbnN0IGxpbmtTdGF0ZSA9IHRhcmdldC5nZXRBdHRyaWJ1dGUoUEhYX0xJTktfU1RBVEUpO1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7IC8vIGRvIG5vdCBidWJibGUgY2xpY2sgdG8gcmVndWxhciBwaHgtY2xpY2sgYmluZGluZ3NcbiAgICAgICAgaWYgKHRoaXMucGVuZGluZ0xpbmsgPT09IGhyZWYpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlcXVlc3RET01VcGRhdGUoKCkgPT4ge1xuICAgICAgICAgIGlmICh0eXBlID09PSBcInBhdGNoXCIpIHtcbiAgICAgICAgICAgIHRoaXMucHVzaEhpc3RvcnlQYXRjaChlLCBocmVmLCBsaW5rU3RhdGUsIHRhcmdldCk7XG4gICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSBcInJlZGlyZWN0XCIpIHtcbiAgICAgICAgICAgIHRoaXMuaGlzdG9yeVJlZGlyZWN0KGUsIGhyZWYsIGxpbmtTdGF0ZSwgbnVsbCwgdGFyZ2V0KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICBgZXhwZWN0ZWQgJHtQSFhfTElWRV9MSU5LfSB0byBiZSBcInBhdGNoXCIgb3IgXCJyZWRpcmVjdFwiLCBnb3Q6ICR7dHlwZX1gLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgcGh4Q2xpY2sgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhcImNsaWNrXCIpKTtcbiAgICAgICAgICBpZiAocGh4Q2xpY2spIHtcbiAgICAgICAgICAgIHRoaXMucmVxdWVzdERPTVVwZGF0ZSgoKSA9PiB0aGlzLmV4ZWNKUyh0YXJnZXQsIHBoeENsaWNrLCBcImNsaWNrXCIpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gIH1cblxuICBtYXliZVNjcm9sbChzY3JvbGwpIHtcbiAgICBpZiAodHlwZW9mIHNjcm9sbCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgd2luZG93LnNjcm9sbFRvKDAsIHNjcm9sbCk7XG4gICAgICB9KTsgLy8gdGhlIGJvZHkgbmVlZHMgdG8gcmVuZGVyIGJlZm9yZSB3ZSBzY3JvbGwuXG4gICAgfVxuICB9XG5cbiAgZGlzcGF0Y2hFdmVudChldmVudCwgcGF5bG9hZCA9IHt9KSB7XG4gICAgRE9NLmRpc3BhdGNoRXZlbnQod2luZG93LCBgcGh4OiR7ZXZlbnR9YCwgeyBkZXRhaWw6IHBheWxvYWQgfSk7XG4gIH1cblxuICBkaXNwYXRjaEV2ZW50cyhldmVudHMpIHtcbiAgICBldmVudHMuZm9yRWFjaCgoW2V2ZW50LCBwYXlsb2FkXSkgPT4gdGhpcy5kaXNwYXRjaEV2ZW50KGV2ZW50LCBwYXlsb2FkKSk7XG4gIH1cblxuICB3aXRoUGFnZUxvYWRpbmcoaW5mbywgY2FsbGJhY2spIHtcbiAgICBET00uZGlzcGF0Y2hFdmVudCh3aW5kb3csIFwicGh4OnBhZ2UtbG9hZGluZy1zdGFydFwiLCB7IGRldGFpbDogaW5mbyB9KTtcbiAgICBjb25zdCBkb25lID0gKCkgPT5cbiAgICAgIERPTS5kaXNwYXRjaEV2ZW50KHdpbmRvdywgXCJwaHg6cGFnZS1sb2FkaW5nLXN0b3BcIiwgeyBkZXRhaWw6IGluZm8gfSk7XG4gICAgcmV0dXJuIGNhbGxiYWNrID8gY2FsbGJhY2soZG9uZSkgOiBkb25lO1xuICB9XG5cbiAgcHVzaEhpc3RvcnlQYXRjaChlLCBocmVmLCBsaW5rU3RhdGUsIHRhcmdldEVsKSB7XG4gICAgaWYgKCF0aGlzLmlzQ29ubmVjdGVkKCkgfHwgIXRoaXMubWFpbi5pc01haW4oKSkge1xuICAgICAgcmV0dXJuIEJyb3dzZXIucmVkaXJlY3QoaHJlZik7XG4gICAgfVxuXG4gICAgdGhpcy53aXRoUGFnZUxvYWRpbmcoeyB0bzogaHJlZiwga2luZDogXCJwYXRjaFwiIH0sIChkb25lKSA9PiB7XG4gICAgICB0aGlzLm1haW4ucHVzaExpbmtQYXRjaChlLCBocmVmLCB0YXJnZXRFbCwgKGxpbmtSZWYpID0+IHtcbiAgICAgICAgdGhpcy5oaXN0b3J5UGF0Y2goaHJlZiwgbGlua1N0YXRlLCBsaW5rUmVmKTtcbiAgICAgICAgZG9uZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBoaXN0b3J5UGF0Y2goaHJlZiwgbGlua1N0YXRlLCBsaW5rUmVmID0gdGhpcy5zZXRQZW5kaW5nTGluayhocmVmKSkge1xuICAgIGlmICghdGhpcy5jb21taXRQZW5kaW5nTGluayhsaW5rUmVmKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEluY3JlbWVudCBwb3NpdGlvbiBmb3IgbmV3IHN0YXRlXG4gICAgdGhpcy5jdXJyZW50SGlzdG9yeVBvc2l0aW9uKys7XG4gICAgdGhpcy5zZXNzaW9uU3RvcmFnZS5zZXRJdGVtKFxuICAgICAgUEhYX0xWX0hJU1RPUllfUE9TSVRJT04sXG4gICAgICB0aGlzLmN1cnJlbnRIaXN0b3J5UG9zaXRpb24udG9TdHJpbmcoKSxcbiAgICApO1xuXG4gICAgLy8gc3RvcmUgdGhlIHR5cGUgZm9yIGJhY2sgbmF2aWdhdGlvblxuICAgIEJyb3dzZXIudXBkYXRlQ3VycmVudFN0YXRlKChzdGF0ZSkgPT4gKHsgLi4uc3RhdGUsIGJhY2tUeXBlOiBcInBhdGNoXCIgfSkpO1xuXG4gICAgQnJvd3Nlci5wdXNoU3RhdGUoXG4gICAgICBsaW5rU3RhdGUsXG4gICAgICB7XG4gICAgICAgIHR5cGU6IFwicGF0Y2hcIixcbiAgICAgICAgaWQ6IHRoaXMubWFpbi5pZCxcbiAgICAgICAgcG9zaXRpb246IHRoaXMuY3VycmVudEhpc3RvcnlQb3NpdGlvbixcbiAgICAgIH0sXG4gICAgICBocmVmLFxuICAgICk7XG5cbiAgICBET00uZGlzcGF0Y2hFdmVudCh3aW5kb3csIFwicGh4Om5hdmlnYXRlXCIsIHtcbiAgICAgIGRldGFpbDogeyBwYXRjaDogdHJ1ZSwgaHJlZiwgcG9wOiBmYWxzZSwgZGlyZWN0aW9uOiBcImZvcndhcmRcIiB9LFxuICAgIH0pO1xuICAgIHRoaXMucmVnaXN0ZXJOZXdMb2NhdGlvbih3aW5kb3cubG9jYXRpb24pO1xuICB9XG5cbiAgaGlzdG9yeVJlZGlyZWN0KGUsIGhyZWYsIGxpbmtTdGF0ZSwgZmxhc2gsIHRhcmdldEVsKSB7XG4gICAgY29uc3QgY2xpY2tMb2FkaW5nID0gdGFyZ2V0RWwgJiYgZS5pc1RydXN0ZWQgJiYgZS50eXBlICE9PSBcInBvcHN0YXRlXCI7XG4gICAgaWYgKGNsaWNrTG9hZGluZykge1xuICAgICAgdGFyZ2V0RWwuY2xhc3NMaXN0LmFkZChcInBoeC1jbGljay1sb2FkaW5nXCIpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuaXNDb25uZWN0ZWQoKSB8fCAhdGhpcy5tYWluLmlzTWFpbigpKSB7XG4gICAgICByZXR1cm4gQnJvd3Nlci5yZWRpcmVjdChocmVmLCBmbGFzaCk7XG4gICAgfVxuXG4gICAgLy8gY29udmVydCB0byBmdWxsIGhyZWYgaWYgb25seSBwYXRoIHByZWZpeFxuICAgIGlmICgvXlxcLyR8XlxcL1teXFwvXSsuKiQvLnRlc3QoaHJlZikpIHtcbiAgICAgIGNvbnN0IHsgcHJvdG9jb2wsIGhvc3QgfSA9IHdpbmRvdy5sb2NhdGlvbjtcbiAgICAgIGhyZWYgPSBgJHtwcm90b2NvbH0vLyR7aG9zdH0ke2hyZWZ9YDtcbiAgICB9XG4gICAgY29uc3Qgc2Nyb2xsID0gd2luZG93LnNjcm9sbFk7XG4gICAgdGhpcy53aXRoUGFnZUxvYWRpbmcoeyB0bzogaHJlZiwga2luZDogXCJyZWRpcmVjdFwiIH0sIChkb25lKSA9PiB7XG4gICAgICB0aGlzLnJlcGxhY2VNYWluKGhyZWYsIGZsYXNoLCAobGlua1JlZikgPT4ge1xuICAgICAgICBpZiAobGlua1JlZiA9PT0gdGhpcy5saW5rUmVmKSB7XG4gICAgICAgICAgLy8gSW5jcmVtZW50IHBvc2l0aW9uIGZvciBuZXcgc3RhdGVcbiAgICAgICAgICB0aGlzLmN1cnJlbnRIaXN0b3J5UG9zaXRpb24rKztcbiAgICAgICAgICB0aGlzLnNlc3Npb25TdG9yYWdlLnNldEl0ZW0oXG4gICAgICAgICAgICBQSFhfTFZfSElTVE9SWV9QT1NJVElPTixcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhpc3RvcnlQb3NpdGlvbi50b1N0cmluZygpLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICAvLyBzdG9yZSB0aGUgdHlwZSBmb3IgYmFjayBuYXZpZ2F0aW9uXG4gICAgICAgICAgQnJvd3Nlci51cGRhdGVDdXJyZW50U3RhdGUoKHN0YXRlKSA9PiAoe1xuICAgICAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgICAgICBiYWNrVHlwZTogXCJyZWRpcmVjdFwiLFxuICAgICAgICAgIH0pKTtcblxuICAgICAgICAgIEJyb3dzZXIucHVzaFN0YXRlKFxuICAgICAgICAgICAgbGlua1N0YXRlLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB0eXBlOiBcInJlZGlyZWN0XCIsXG4gICAgICAgICAgICAgIGlkOiB0aGlzLm1haW4uaWQsXG4gICAgICAgICAgICAgIHNjcm9sbDogc2Nyb2xsLFxuICAgICAgICAgICAgICBwb3NpdGlvbjogdGhpcy5jdXJyZW50SGlzdG9yeVBvc2l0aW9uLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGhyZWYsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIERPTS5kaXNwYXRjaEV2ZW50KHdpbmRvdywgXCJwaHg6bmF2aWdhdGVcIiwge1xuICAgICAgICAgICAgZGV0YWlsOiB7IGhyZWYsIHBhdGNoOiBmYWxzZSwgcG9wOiBmYWxzZSwgZGlyZWN0aW9uOiBcImZvcndhcmRcIiB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRoaXMucmVnaXN0ZXJOZXdMb2NhdGlvbih3aW5kb3cubG9jYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIC8vIGV4cGxpY2l0bHkgdW5kbyBjbGljay1sb2FkaW5nIGNsYXNzXG4gICAgICAgIC8vIChpbiBjYXNlIGl0IG9yaWdpbmF0ZWQgaW4gYSBzdGlja3kgbGl2ZSB2aWV3LCBvdGhlcndpc2UgaXQgd291bGQgYmUgcmVtb3ZlZCBhbnl3YXkpXG4gICAgICAgIGlmIChjbGlja0xvYWRpbmcpIHtcbiAgICAgICAgICB0YXJnZXRFbC5jbGFzc0xpc3QucmVtb3ZlKFwicGh4LWNsaWNrLWxvYWRpbmdcIik7XG4gICAgICAgIH1cbiAgICAgICAgZG9uZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICByZWdpc3Rlck5ld0xvY2F0aW9uKG5ld0xvY2F0aW9uKSB7XG4gICAgY29uc3QgeyBwYXRobmFtZSwgc2VhcmNoIH0gPSB0aGlzLmN1cnJlbnRMb2NhdGlvbjtcbiAgICBpZiAocGF0aG5hbWUgKyBzZWFyY2ggPT09IG5ld0xvY2F0aW9uLnBhdGhuYW1lICsgbmV3TG9jYXRpb24uc2VhcmNoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3VycmVudExvY2F0aW9uID0gY2xvbmUobmV3TG9jYXRpb24pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgYmluZEZvcm1zKCkge1xuICAgIGxldCBpdGVyYXRpb25zID0gMDtcbiAgICBsZXQgZXh0ZXJuYWxGb3JtU3VibWl0dGVkID0gZmFsc2U7XG5cbiAgICAvLyBkaXNhYmxlIGZvcm1zIG9uIHN1Ym1pdCB0aGF0IHRyYWNrIHBoeC1jaGFuZ2UgYnV0IHBlcmZvcm0gZXh0ZXJuYWwgc3VibWl0XG4gICAgdGhpcy5vbihcInN1Ym1pdFwiLCAoZSkgPT4ge1xuICAgICAgY29uc3QgcGh4U3VibWl0ID0gZS50YXJnZXQuZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhcInN1Ym1pdFwiKSk7XG4gICAgICBjb25zdCBwaHhDaGFuZ2UgPSBlLnRhcmdldC5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFwiY2hhbmdlXCIpKTtcbiAgICAgIGlmICghZXh0ZXJuYWxGb3JtU3VibWl0dGVkICYmIHBoeENoYW5nZSAmJiAhcGh4U3VibWl0KSB7XG4gICAgICAgIGV4dGVybmFsRm9ybVN1Ym1pdHRlZCA9IHRydWU7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy53aXRoaW5Pd25lcnMoZS50YXJnZXQsICh2aWV3KSA9PiB7XG4gICAgICAgICAgdmlldy5kaXNhYmxlRm9ybShlLnRhcmdldCk7XG4gICAgICAgICAgLy8gc2FmYXJpIG5lZWRzIG5leHQgdGlja1xuICAgICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKERPTS5pc1VubG9hZGFibGVGb3JtU3VibWl0KGUpKSB7XG4gICAgICAgICAgICAgIHRoaXMudW5sb2FkKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlLnRhcmdldC5zdWJtaXQoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLm9uKFwic3VibWl0XCIsIChlKSA9PiB7XG4gICAgICBjb25zdCBwaHhFdmVudCA9IGUudGFyZ2V0LmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoXCJzdWJtaXRcIikpO1xuICAgICAgaWYgKCFwaHhFdmVudCkge1xuICAgICAgICBpZiAoRE9NLmlzVW5sb2FkYWJsZUZvcm1TdWJtaXQoZSkpIHtcbiAgICAgICAgICB0aGlzLnVubG9hZCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGUudGFyZ2V0LmRpc2FibGVkID0gdHJ1ZTtcbiAgICAgIHRoaXMud2l0aGluT3duZXJzKGUudGFyZ2V0LCAodmlldykgPT4ge1xuICAgICAgICBKUy5leGVjKGUsIFwic3VibWl0XCIsIHBoeEV2ZW50LCB2aWV3LCBlLnRhcmdldCwgW1xuICAgICAgICAgIFwicHVzaFwiLFxuICAgICAgICAgIHsgc3VibWl0dGVyOiBlLnN1Ym1pdHRlciB9LFxuICAgICAgICBdKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZm9yIChjb25zdCB0eXBlIG9mIFtcImNoYW5nZVwiLCBcImlucHV0XCJdKSB7XG4gICAgICB0aGlzLm9uKHR5cGUsIChlKSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBlIGluc3RhbmNlb2YgQ3VzdG9tRXZlbnQgJiZcbiAgICAgICAgICAoZS50YXJnZXQgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50IHx8XG4gICAgICAgICAgICBlLnRhcmdldCBpbnN0YW5jZW9mIEhUTUxTZWxlY3RFbGVtZW50IHx8XG4gICAgICAgICAgICBlLnRhcmdldCBpbnN0YW5jZW9mIEhUTUxUZXh0QXJlYUVsZW1lbnQpICYmXG4gICAgICAgICAgZS50YXJnZXQuZm9ybSA9PT0gdW5kZWZpbmVkXG4gICAgICAgICkge1xuICAgICAgICAgIC8vIHRocm93IG9uIGludmFsaWQgSlMuZGlzcGF0Y2ggdGFyZ2V0IGFuZCBub29wIGlmIEN1c3RvbUV2ZW50IHRyaWdnZXJlZCBvdXRzaWRlIEpTLmRpc3BhdGNoXG4gICAgICAgICAgaWYgKGUuZGV0YWlsICYmIGUuZGV0YWlsLmRpc3BhdGNoZXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgYGRpc3BhdGNoaW5nIGEgY3VzdG9tICR7dHlwZX0gZXZlbnQgaXMgb25seSBzdXBwb3J0ZWQgb24gaW5wdXQgZWxlbWVudHMgaW5zaWRlIGEgZm9ybWAsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGh4Q2hhbmdlID0gdGhpcy5iaW5kaW5nKFwiY2hhbmdlXCIpO1xuICAgICAgICBjb25zdCBpbnB1dCA9IGUudGFyZ2V0O1xuICAgICAgICBpZiAodGhpcy5ibG9ja1BoeENoYW5nZVdoaWxlQ29tcG9zaW5nICYmIGUuaXNDb21wb3NpbmcpIHtcbiAgICAgICAgICBjb25zdCBrZXkgPSBgY29tcG9zaXRpb24tbGlzdGVuZXItJHt0eXBlfWA7XG4gICAgICAgICAgaWYgKCFET00ucHJpdmF0ZShpbnB1dCwga2V5KSkge1xuICAgICAgICAgICAgRE9NLnB1dFByaXZhdGUoaW5wdXQsIGtleSwgdHJ1ZSk7XG4gICAgICAgICAgICBpbnB1dC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICBcImNvbXBvc2l0aW9uZW5kXCIsXG4gICAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICAvLyB0cmlnZ2VyIGEgbmV3IGlucHV0L2NoYW5nZSBldmVudFxuICAgICAgICAgICAgICAgIGlucHV0LmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KHR5cGUsIHsgYnViYmxlczogdHJ1ZSB9KSk7XG4gICAgICAgICAgICAgICAgRE9NLmRlbGV0ZVByaXZhdGUoaW5wdXQsIGtleSk7XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHsgb25jZTogdHJ1ZSB9LFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGlucHV0RXZlbnQgPSBpbnB1dC5nZXRBdHRyaWJ1dGUocGh4Q2hhbmdlKTtcbiAgICAgICAgY29uc3QgZm9ybUV2ZW50ID0gaW5wdXQuZm9ybSAmJiBpbnB1dC5mb3JtLmdldEF0dHJpYnV0ZShwaHhDaGFuZ2UpO1xuICAgICAgICBjb25zdCBwaHhFdmVudCA9IGlucHV0RXZlbnQgfHwgZm9ybUV2ZW50O1xuICAgICAgICBpZiAoIXBoeEV2ZW50KSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChcbiAgICAgICAgICBpbnB1dC50eXBlID09PSBcIm51bWJlclwiICYmXG4gICAgICAgICAgaW5wdXQudmFsaWRpdHkgJiZcbiAgICAgICAgICBpbnB1dC52YWxpZGl0eS5iYWRJbnB1dFxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkaXNwYXRjaGVyID0gaW5wdXRFdmVudCA/IGlucHV0IDogaW5wdXQuZm9ybTtcbiAgICAgICAgY29uc3QgY3VycmVudEl0ZXJhdGlvbnMgPSBpdGVyYXRpb25zO1xuICAgICAgICBpdGVyYXRpb25zKys7XG4gICAgICAgIGNvbnN0IHsgYXQ6IGF0LCB0eXBlOiBsYXN0VHlwZSB9ID1cbiAgICAgICAgICBET00ucHJpdmF0ZShpbnB1dCwgXCJwcmV2LWl0ZXJhdGlvblwiKSB8fCB7fTtcbiAgICAgICAgLy8gQnJvd3NlcnMgc2hvdWxkIGFsd2F5cyBmaXJlIGF0IGxlYXN0IG9uZSBcImlucHV0XCIgZXZlbnQgYmVmb3JlIGV2ZXJ5IFwiY2hhbmdlXCJcbiAgICAgICAgLy8gSWdub3JlIFwiY2hhbmdlXCIgZXZlbnRzLCB1bmxlc3MgdGhlcmUgd2FzIG5vIHByaW9yIFwiaW5wdXRcIiBldmVudC5cbiAgICAgICAgLy8gVGhpcyBjb3VsZCBoYXBwZW4gaWYgdXNlciBjb2RlIHRyaWdnZXJzIGEgXCJjaGFuZ2VcIiBldmVudCwgb3IgaWYgdGhlIGJyb3dzZXIgaXMgbm9uLWNvbmZvcm1pbmcuXG4gICAgICAgIGlmIChcbiAgICAgICAgICBhdCA9PT0gY3VycmVudEl0ZXJhdGlvbnMgLSAxICYmXG4gICAgICAgICAgdHlwZSA9PT0gXCJjaGFuZ2VcIiAmJlxuICAgICAgICAgIGxhc3RUeXBlID09PSBcImlucHV0XCJcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgRE9NLnB1dFByaXZhdGUoaW5wdXQsIFwicHJldi1pdGVyYXRpb25cIiwge1xuICAgICAgICAgIGF0OiBjdXJyZW50SXRlcmF0aW9ucyxcbiAgICAgICAgICB0eXBlOiB0eXBlLFxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmRlYm91bmNlKGlucHV0LCBlLCB0eXBlLCAoKSA9PiB7XG4gICAgICAgICAgdGhpcy53aXRoaW5Pd25lcnMoZGlzcGF0Y2hlciwgKHZpZXcpID0+IHtcbiAgICAgICAgICAgIERPTS5wdXRQcml2YXRlKGlucHV0LCBQSFhfSEFTX0ZPQ1VTRUQsIHRydWUpO1xuICAgICAgICAgICAgSlMuZXhlYyhlLCBcImNoYW5nZVwiLCBwaHhFdmVudCwgdmlldywgaW5wdXQsIFtcbiAgICAgICAgICAgICAgXCJwdXNoXCIsXG4gICAgICAgICAgICAgIHsgX3RhcmdldDogZS50YXJnZXQubmFtZSwgZGlzcGF0Y2hlcjogZGlzcGF0Y2hlciB9LFxuICAgICAgICAgICAgXSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMub24oXCJyZXNldFwiLCAoZSkgPT4ge1xuICAgICAgY29uc3QgZm9ybSA9IGUudGFyZ2V0O1xuICAgICAgRE9NLnJlc2V0Rm9ybShmb3JtKTtcbiAgICAgIGNvbnN0IGlucHV0ID0gQXJyYXkuZnJvbShmb3JtLmVsZW1lbnRzKS5maW5kKChlbCkgPT4gZWwudHlwZSA9PT0gXCJyZXNldFwiKTtcbiAgICAgIGlmIChpbnB1dCkge1xuICAgICAgICAvLyB3YWl0IHVudGlsIG5leHQgdGljayB0byBnZXQgdXBkYXRlZCBpbnB1dCB2YWx1ZVxuICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICBpbnB1dC5kaXNwYXRjaEV2ZW50KFxuICAgICAgICAgICAgbmV3IEV2ZW50KFwiaW5wdXRcIiwgeyBidWJibGVzOiB0cnVlLCBjYW5jZWxhYmxlOiBmYWxzZSB9KSxcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGRlYm91bmNlKGVsLCBldmVudCwgZXZlbnRUeXBlLCBjYWxsYmFjaykge1xuICAgIGlmIChldmVudFR5cGUgPT09IFwiYmx1clwiIHx8IGV2ZW50VHlwZSA9PT0gXCJmb2N1c291dFwiKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgICB9XG5cbiAgICBjb25zdCBwaHhEZWJvdW5jZSA9IHRoaXMuYmluZGluZyhQSFhfREVCT1VOQ0UpO1xuICAgIGNvbnN0IHBoeFRocm90dGxlID0gdGhpcy5iaW5kaW5nKFBIWF9USFJPVFRMRSk7XG4gICAgY29uc3QgZGVmYXVsdERlYm91bmNlID0gdGhpcy5kZWZhdWx0cy5kZWJvdW5jZS50b1N0cmluZygpO1xuICAgIGNvbnN0IGRlZmF1bHRUaHJvdHRsZSA9IHRoaXMuZGVmYXVsdHMudGhyb3R0bGUudG9TdHJpbmcoKTtcblxuICAgIHRoaXMud2l0aGluT3duZXJzKGVsLCAodmlldykgPT4ge1xuICAgICAgY29uc3QgYXN5bmNGaWx0ZXIgPSAoKSA9PlxuICAgICAgICAhdmlldy5pc0Rlc3Ryb3llZCgpICYmIGRvY3VtZW50LmJvZHkuY29udGFpbnMoZWwpO1xuICAgICAgRE9NLmRlYm91bmNlKFxuICAgICAgICBlbCxcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIHBoeERlYm91bmNlLFxuICAgICAgICBkZWZhdWx0RGVib3VuY2UsXG4gICAgICAgIHBoeFRocm90dGxlLFxuICAgICAgICBkZWZhdWx0VGhyb3R0bGUsXG4gICAgICAgIGFzeW5jRmlsdGVyLFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBzaWxlbmNlRXZlbnRzKGNhbGxiYWNrKSB7XG4gICAgdGhpcy5zaWxlbmNlZCA9IHRydWU7XG4gICAgY2FsbGJhY2soKTtcbiAgICB0aGlzLnNpbGVuY2VkID0gZmFsc2U7XG4gIH1cblxuICBvbihldmVudCwgY2FsbGJhY2spIHtcbiAgICB0aGlzLmJvdW5kRXZlbnROYW1lcy5hZGQoZXZlbnQpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKGV2ZW50LCAoZSkgPT4ge1xuICAgICAgaWYgKCF0aGlzLnNpbGVuY2VkKSB7XG4gICAgICAgIGNhbGxiYWNrKGUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAganNRdWVyeVNlbGVjdG9yQWxsKHNvdXJjZUVsLCBxdWVyeSwgZGVmYXVsdFF1ZXJ5KSB7XG4gICAgY29uc3QgYWxsID0gdGhpcy5kb21DYWxsYmFja3MuanNRdWVyeVNlbGVjdG9yQWxsO1xuICAgIHJldHVybiBhbGwgPyBhbGwoc291cmNlRWwsIHF1ZXJ5LCBkZWZhdWx0UXVlcnkpIDogZGVmYXVsdFF1ZXJ5KCk7XG4gIH1cbn1cblxuY2xhc3MgVHJhbnNpdGlvblNldCB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMudHJhbnNpdGlvbnMgPSBuZXcgU2V0KCk7XG4gICAgdGhpcy5wcm9taXNlcyA9IG5ldyBTZXQoKTtcbiAgICB0aGlzLnBlbmRpbmdPcHMgPSBbXTtcbiAgfVxuXG4gIHJlc2V0KCkge1xuICAgIHRoaXMudHJhbnNpdGlvbnMuZm9yRWFjaCgodGltZXIpID0+IHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICB0aGlzLnRyYW5zaXRpb25zLmRlbGV0ZSh0aW1lcik7XG4gICAgfSk7XG4gICAgdGhpcy5wcm9taXNlcy5jbGVhcigpO1xuICAgIHRoaXMuZmx1c2hQZW5kaW5nT3BzKCk7XG4gIH1cblxuICBhZnRlcihjYWxsYmFjaykge1xuICAgIGlmICh0aGlzLnNpemUoKSA9PT0gMCkge1xuICAgICAgY2FsbGJhY2soKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wdXNoUGVuZGluZ09wKGNhbGxiYWNrKTtcbiAgICB9XG4gIH1cblxuICBhZGRUcmFuc2l0aW9uKHRpbWUsIG9uU3RhcnQsIG9uRG9uZSkge1xuICAgIG9uU3RhcnQoKTtcbiAgICBjb25zdCB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy50cmFuc2l0aW9ucy5kZWxldGUodGltZXIpO1xuICAgICAgb25Eb25lKCk7XG4gICAgICB0aGlzLmZsdXNoUGVuZGluZ09wcygpO1xuICAgIH0sIHRpbWUpO1xuICAgIHRoaXMudHJhbnNpdGlvbnMuYWRkKHRpbWVyKTtcbiAgfVxuXG4gIGFkZEFzeW5jVHJhbnNpdGlvbihwcm9taXNlKSB7XG4gICAgdGhpcy5wcm9taXNlcy5hZGQocHJvbWlzZSk7XG4gICAgcHJvbWlzZS50aGVuKCgpID0+IHtcbiAgICAgIHRoaXMucHJvbWlzZXMuZGVsZXRlKHByb21pc2UpO1xuICAgICAgdGhpcy5mbHVzaFBlbmRpbmdPcHMoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1c2hQZW5kaW5nT3Aob3ApIHtcbiAgICB0aGlzLnBlbmRpbmdPcHMucHVzaChvcCk7XG4gIH1cblxuICBzaXplKCkge1xuICAgIHJldHVybiB0aGlzLnRyYW5zaXRpb25zLnNpemUgKyB0aGlzLnByb21pc2VzLnNpemU7XG4gIH1cblxuICBmbHVzaFBlbmRpbmdPcHMoKSB7XG4gICAgaWYgKHRoaXMuc2l6ZSgpID4gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBvcCA9IHRoaXMucGVuZGluZ09wcy5zaGlmdCgpO1xuICAgIGlmIChvcCkge1xuICAgICAgb3AoKTtcbiAgICAgIHRoaXMuZmx1c2hQZW5kaW5nT3BzKCk7XG4gICAgfVxuICB9XG59XG4iLCAiLypcbj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5QaG9lbml4IExpdmVWaWV3IEphdmFTY3JpcHQgQ2xpZW50XG49PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5TZWUgdGhlIGhleGRvY3MgYXQgYGh0dHBzOi8vaGV4ZG9jcy5wbS9waG9lbml4X2xpdmVfdmlld2AgZm9yIGRvY3VtZW50YXRpb24uXG4qL1xuXG5pbXBvcnQgT3JpZ2luYWxMaXZlU29ja2V0LCB7IGlzVXNlZElucHV0IH0gZnJvbSBcIi4vbGl2ZV9zb2NrZXRcIjtcbmltcG9ydCBET00gZnJvbSBcIi4vZG9tXCI7XG5pbXBvcnQgeyBWaWV3SG9vayB9IGZyb20gXCIuL3ZpZXdfaG9va1wiO1xuaW1wb3J0IFZpZXcgZnJvbSBcIi4vdmlld1wiO1xuXG5pbXBvcnQgdHlwZSB7IExpdmVTb2NrZXRKU0NvbW1hbmRzIH0gZnJvbSBcIi4vanNfY29tbWFuZHNcIjtcbmltcG9ydCB0eXBlIHsgSG9vaywgSG9va3NPcHRpb25zIH0gZnJvbSBcIi4vdmlld19ob29rXCI7XG5pbXBvcnQgdHlwZSB7IFNvY2tldCBhcyBQaG9lbml4U29ja2V0IH0gZnJvbSBcInBob2VuaXhcIjtcblxuLyoqXG4gKiBPcHRpb25zIGZvciBjb25maWd1cmluZyB0aGUgTGl2ZVNvY2tldCBpbnN0YW5jZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBMaXZlU29ja2V0T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBEZWZhdWx0cyBmb3IgcGh4LWRlYm91bmNlIGFuZCBwaHgtdGhyb3R0bGUuXG4gICAqL1xuICBkZWZhdWx0cz86IHtcbiAgICAvKiogVGhlIG1pbGxpc2Vjb25kIHBoeC1kZWJvdW5jZSB0aW1lLiBEZWZhdWx0cyAzMDAgKi9cbiAgICBkZWJvdW5jZT86IG51bWJlcjtcbiAgICAvKiogVGhlIG1pbGxpc2Vjb25kIHBoeC10aHJvdHRsZSB0aW1lLiBEZWZhdWx0cyAzMDAgKi9cbiAgICB0aHJvdHRsZT86IG51bWJlcjtcbiAgfTtcbiAgLyoqXG4gICAqIEFuIG9iamVjdCBvciBmdW5jdGlvbiBmb3IgcGFzc2luZyBjb25uZWN0IHBhcmFtcy5cbiAgICogVGhlIGZ1bmN0aW9uIHJlY2VpdmVzIHRoZSBlbGVtZW50IGFzc29jaWF0ZWQgd2l0aCBhIGdpdmVuIExpdmVWaWV3LiBGb3IgZXhhbXBsZTpcbiAgICpcbiAgICogICAgIChlbCkgPT4ge3ZpZXc6IGVsLmdldEF0dHJpYnV0ZShcImRhdGEtbXktdmlldy1uYW1lXCIsIHRva2VuOiB3aW5kb3cubXlUb2tlbn1cbiAgICpcbiAgICovXG4gIHBhcmFtcz86XG4gICAgfCAoKGVsOiBIVE1MRWxlbWVudCkgPT4geyBba2V5OiBzdHJpbmddOiBhbnkgfSlcbiAgICB8IHsgW2tleTogc3RyaW5nXTogYW55IH07XG4gIC8qKlxuICAgKiBUaGUgb3B0aW9uYWwgcHJlZml4IHRvIHVzZSBmb3IgYWxsIHBoeCBET00gYW5ub3RhdGlvbnMuXG4gICAqXG4gICAqIERlZmF1bHRzIHRvIFwicGh4LVwiLlxuICAgKi9cbiAgYmluZGluZ1ByZWZpeD86IHN0cmluZztcbiAgLyoqXG4gICAqIENhbGxiYWNrcyBmb3IgTGl2ZVZpZXcgaG9va3MuXG4gICAqXG4gICAqIFNlZSBbQ2xpZW50IGhvb2tzIHZpYSBgcGh4LWhvb2tgXShodHRwczovL2hleGRvY3MucG0vcGhvZW5peF9saXZlX3ZpZXcvanMtaW50ZXJvcC5odG1sI2NsaWVudC1ob29rcy12aWEtcGh4LWhvb2spIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICAgKi9cbiAgaG9va3M/OiBIb29rc09wdGlvbnM7XG4gIC8qKiBDYWxsYmFja3MgZm9yIExpdmVWaWV3IHVwbG9hZGVycy4gKi9cbiAgdXBsb2FkZXJzPzogeyBba2V5OiBzdHJpbmddOiBhbnkgfTsgLy8gVE9ETzogZGVmaW5lIG1vcmUgc3BlY2lmaWNhbGx5XG4gIC8qKiBEZWxheSBpbiBtaWxsaXNlY29uZHMgYmVmb3JlIGFwcGx5aW5nIGxvYWRpbmcgc3RhdGVzLiAqL1xuICBsb2FkZXJUaW1lb3V0PzogbnVtYmVyO1xuICAvKiogRGVsYXkgaW4gbWlsbGlzZWNvbmRzIGJlZm9yZSBleGVjdXRpbmcgcGh4LWRpc2Nvbm5lY3RlZCBjb21tYW5kcy4gKi9cbiAgZGlzY29ubmVjdGVkVGltZW91dD86IG51bWJlcjtcbiAgLyoqIE1heGltdW0gcmVsb2FkcyBiZWZvcmUgZW50ZXJpbmcgZmFpbHNhZmUgbW9kZS4gKi9cbiAgbWF4UmVsb2Fkcz86IG51bWJlcjtcbiAgLyoqIE1pbmltdW0gdGltZSBiZXR3ZWVuIG5vcm1hbCByZWxvYWQgYXR0ZW1wdHMuICovXG4gIHJlbG9hZEppdHRlck1pbj86IG51bWJlcjtcbiAgLyoqIE1heGltdW0gdGltZSBiZXR3ZWVuIG5vcm1hbCByZWxvYWQgYXR0ZW1wdHMuICovXG4gIHJlbG9hZEppdHRlck1heD86IG51bWJlcjtcbiAgLyoqIFRpbWUgYmV0d2VlbiByZWxvYWQgYXR0ZW1wdHMgaW4gZmFpbHNhZmUgbW9kZS4gKi9cbiAgZmFpbHNhZmVKaXR0ZXI/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBGdW5jdGlvbiB0byBsb2cgZGVidWcgaW5mb3JtYXRpb24uIEZvciBleGFtcGxlOlxuICAgKlxuICAgKiAgICAgKHZpZXcsIGtpbmQsIG1zZywgb2JqKSA9PiBjb25zb2xlLmxvZyhgJHt2aWV3LmlkfSAke2tpbmR9OiAke21zZ30gLSBgLCBvYmopXG4gICAqL1xuICB2aWV3TG9nZ2VyPzogKHZpZXc6IFZpZXcsIGtpbmQ6IHN0cmluZywgbXNnOiBzdHJpbmcsIG9iajogYW55KSA9PiB2b2lkO1xuICAvKipcbiAgICogT2JqZWN0IG1hcHBpbmcgZXZlbnQgbmFtZXMgdG8gZnVuY3Rpb25zIGZvciBwb3B1bGF0aW5nIGV2ZW50IG1ldGFkYXRhLlxuICAgKlxuICAgKiAgICAgbWV0YWRhdGE6IHtcbiAgICogICAgICAgY2xpY2s6IChlLCBlbCkgPT4ge1xuICAgKiAgICAgICAgIHJldHVybiB7XG4gICAqICAgICAgICAgICBjdHJsS2V5OiBlLmN0cmxLZXksXG4gICAqICAgICAgICAgICBtZXRhS2V5OiBlLm1ldGFLZXksXG4gICAqICAgICAgICAgICBkZXRhaWw6IGUuZGV0YWlsIHx8IDEsXG4gICAqICAgICAgICAgfVxuICAgKiAgICAgICB9LFxuICAgKiAgICAgICBrZXlkb3duOiAoZSwgZWwpID0+IHtcbiAgICogICAgICAgICByZXR1cm4ge1xuICAgKiAgICAgICAgICAga2V5OiBlLmtleSxcbiAgICogICAgICAgICAgIGN0cmxLZXk6IGUuY3RybEtleSxcbiAgICogICAgICAgICAgIG1ldGFLZXk6IGUubWV0YUtleSxcbiAgICogICAgICAgICAgIHNoaWZ0S2V5OiBlLnNoaWZ0S2V5XG4gICAqICAgICAgICAgfVxuICAgKiAgICAgICB9XG4gICAqICAgICB9XG4gICAqXG4gICAqL1xuICBtZXRhZGF0YT86IHsgW2V2ZW50TmFtZTogc3RyaW5nXTogKGU6IEV2ZW50LCBlbDogSFRNTEVsZW1lbnQpID0+IG9iamVjdCB9O1xuICAvKipcbiAgICogQW4gb3B0aW9uYWwgU3RvcmFnZSBjb21wYXRpYmxlIG9iamVjdFxuICAgKiBVc2VmdWwgd2hlbiBMaXZlVmlldyB3b24ndCBoYXZlIGFjY2VzcyB0byBgc2Vzc2lvblN0b3JhZ2VgLiBGb3IgZXhhbXBsZSwgVGhpcyBjb3VsZFxuICAgKiBoYXBwZW4gaWYgYSBzaXRlIGxvYWRzIGEgY3Jvc3MtZG9tYWluIExpdmVWaWV3IGluIGFuIGlmcmFtZS5cbiAgICpcbiAgICogRXhhbXBsZSB1c2FnZTpcbiAgICpcbiAgICogICAgIGNsYXNzIEluTWVtb3J5U3RvcmFnZSB7XG4gICAqICAgICAgIGNvbnN0cnVjdG9yKCkgeyB0aGlzLnN0b3JhZ2UgPSB7fSB9XG4gICAqICAgICAgIGdldEl0ZW0oa2V5TmFtZSkgeyByZXR1cm4gdGhpcy5zdG9yYWdlW2tleU5hbWVdIHx8IG51bGwgfVxuICAgKiAgICAgICByZW1vdmVJdGVtKGtleU5hbWUpIHsgZGVsZXRlIHRoaXMuc3RvcmFnZVtrZXlOYW1lXSB9XG4gICAqICAgICAgIHNldEl0ZW0oa2V5TmFtZSwga2V5VmFsdWUpIHsgdGhpcy5zdG9yYWdlW2tleU5hbWVdID0ga2V5VmFsdWUgfVxuICAgKiAgICAgfVxuICAgKi9cbiAgc2Vzc2lvblN0b3JhZ2U/OiBTdG9yYWdlO1xuICAvKipcbiAgICogQW4gb3B0aW9uYWwgU3RvcmFnZSBjb21wYXRpYmxlIG9iamVjdFxuICAgKiBVc2VmdWwgd2hlbiBMaXZlVmlldyB3b24ndCBoYXZlIGFjY2VzcyB0byBgbG9jYWxTdG9yYWdlYC5cbiAgICpcbiAgICogU2VlIGBzZXNzaW9uU3RvcmFnZWAgZm9yIGFuIGV4YW1wbGUuXG4gICAqL1xuICBsb2NhbFN0b3JhZ2U/OiBTdG9yYWdlO1xuICAvKipcbiAgICogSWYgc2V0IHRvIGB0cnVlYCwgYHBoeC1jaGFuZ2VgIGV2ZW50cyB3aWxsIGJlIGJsb2NrZWQgKHdpbGwgbm90IGZpcmUpXG4gICAqIHdoaWxlIHRoZSB1c2VyIGlzIGNvbXBvc2luZyBpbnB1dCB1c2luZyBhbiBJTUUgKElucHV0IE1ldGhvZCBFZGl0b3IpLlxuICAgKiBUaGlzIGlzIGRldGVybWluZWQgYnkgdGhlIGBlLmlzQ29tcG9zaW5nYCBwcm9wZXJ0eSBvbiBrZXlib2FyZCBldmVudHMsXG4gICAqIHdoaWNoIGlzIGB0cnVlYCB3aGVuIHRoZSB1c2VyIGlzIGluIHRoZSBwcm9jZXNzIG9mIGVudGVyaW5nIGNvbXBvc2VkIGNoYXJhY3RlcnMgKGZvciBleGFtcGxlLFxuICAgKiB3aGVuIHR5cGluZyBKYXBhbmVzZSBvciBDaGluZXNlIHVzaW5nIHJvbWFqaSBvciBwaW55aW4gaW5wdXQgbWV0aG9kcykuXG4gICAqIEJ5IGRlZmF1bHQsIGBwaHgtY2hhbmdlYCB3aWxsIG5vdCBiZSBibG9ja2VkIGR1cmluZyBhIGNvbXBvc2l0aW9uIHNlc3Npb24sXG4gICAqIGJ1dCBub3RlIHRoYXQgdGhlcmUgd2VyZSBpc3N1ZXMgcmVwb3J0ZWQgaW4gb2xkZXIgdmVyc2lvbnMgb2YgU2FmYXJpLFxuICAgKiB3aGVyZSBhIExpdmVWaWV3IHBhdGNoIHRvIHRoZSBpbnB1dCBjYXVzZWQgdW5leHBlY3RlZCBiZWhhdmlvci5cbiAgICpcbiAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZVxuICAgKiAtIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9LZXlib2FyZEV2ZW50L2lzQ29tcG9zaW5nXG4gICAqIC0gaHR0cHM6Ly9naXRodWIuY29tL3Bob2VuaXhmcmFtZXdvcmsvcGhvZW5peF9saXZlX3ZpZXcvaXNzdWVzLzMzMjJcbiAgICpcbiAgICogRGVmYXVsdHMgdG8gYGZhbHNlYC5cbiAgICovXG4gIGJsb2NrUGh4Q2hhbmdlV2hpbGVDb21wb3Npbmc/OiBib29sZWFuO1xuICAvKiogRE9NIGNhbGxiYWNrcy4gKi9cbiAgZG9tPzoge1xuICAgIC8qKlxuICAgICAqIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIG1vZGlmeSB0aGUgYmVoYXZpb3Igb2YgcXVlcnlpbmcgZWxlbWVudHMgaW4gSlMgY29tbWFuZHMuXG4gICAgICogQHBhcmFtIHNvdXJjZUVsIC0gVGhlIHNvdXJjZSBlbGVtZW50LCBlLmcuIHRoZSBidXR0b24gdGhhdCB3YXMgY2xpY2tlZC5cbiAgICAgKiBAcGFyYW0gcXVlcnkgLSBUaGUgcXVlcnkgdmFsdWUuXG4gICAgICogQHBhcmFtIGRlZmF1bHRRdWVyeSAtIEEgZGVmYXVsdCBxdWVyeSBmdW5jdGlvbiB0aGF0IGNhbiBiZSB1c2VkIGlmIG5vIGN1c3RvbSBxdWVyeSBzaG91bGQgYmUgYXBwbGllZC5cbiAgICAgKiBAcmV0dXJucyBBIGxpc3Qgb2YgRE9NIGVsZW1lbnRzLlxuICAgICAqL1xuICAgIGpzUXVlcnlTZWxlY3RvckFsbD86IChcbiAgICAgIHNvdXJjZUVsOiBIVE1MRWxlbWVudCxcbiAgICAgIHF1ZXJ5OiBzdHJpbmcsXG4gICAgICBkZWZhdWx0UXVlcnk6ICgpID0+IEVsZW1lbnRbXSxcbiAgICApID0+IEVsZW1lbnRbXTtcbiAgICAvKipcbiAgICAgKiBDYWxsZWQgaW1tZWRpYXRlbHkgYmVmb3JlIGEgRE9NIHBhdGNoIGlzIGFwcGxpZWQuXG4gICAgICovXG4gICAgb25QYXRjaFN0YXJ0PzogKGNvbnRhaW5lcjogSFRNTEVsZW1lbnQpID0+IHZvaWQ7XG4gICAgLyoqXG4gICAgICogQ2FsbGVkIGltbWVkaWF0ZWx5IGFmdGVyIGEgRE9NIHBhdGNoIGlzIGFwcGxpZWQuXG4gICAgICovXG4gICAgb25QYXRjaEVuZD86IChjb250YWluZXI6IEhUTUxFbGVtZW50KSA9PiB2b2lkO1xuICAgIC8qKlxuICAgICAqIENhbGxlZCB3aGVuIGEgbmV3IERPTSBub2RlIGlzIGFkZGVkLlxuICAgICAqL1xuICAgIG9uTm9kZUFkZGVkPzogKG5vZGU6IE5vZGUpID0+IHZvaWQ7XG4gICAgLyoqXG4gICAgICogQ2FsbGVkIGJlZm9yZSBhbiBlbGVtZW50IGlzIHVwZGF0ZWQuXG4gICAgICovXG4gICAgb25CZWZvcmVFbFVwZGF0ZWQ/OiAoZnJvbUVsOiBFbGVtZW50LCB0b0VsOiBFbGVtZW50KSA9PiB2b2lkO1xuICB9O1xuICAvKiogQWxsb3cgcGFzc3Rocm91Z2ggb2Ygb3RoZXIgb3B0aW9ucyB0byB0aGUgUGhvZW5peCBTb2NrZXQgY29uc3RydWN0b3IuICovXG4gIFtrZXk6IHN0cmluZ106IGFueTtcbn1cblxuLyoqXG4gKiBJbnRlcmZhY2UgZGVzY3JpYmluZyB0aGUgcHVibGljIEFQSSBvZiBhIExpdmVTb2NrZXQgaW5zdGFuY2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTGl2ZVNvY2tldEluc3RhbmNlSW50ZXJmYWNlIHtcbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHZlcnNpb24gb2YgdGhlIExpdmVWaWV3IGNsaWVudC5cbiAgICovXG4gIHZlcnNpb24oKTogc3RyaW5nO1xuICAvKipcbiAgICogUmV0dXJucyB0cnVlIGlmIHByb2ZpbGluZyBpcyBlbmFibGVkLiBTZWUgYGVuYWJsZVByb2ZpbGluZ2AgYW5kIGBkaXNhYmxlUHJvZmlsaW5nYC5cbiAgICovXG4gIGlzUHJvZmlsZUVuYWJsZWQoKTogYm9vbGVhbjtcbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiBkZWJ1Z2dpbmcgaXMgZW5hYmxlZC4gU2VlIGBlbmFibGVEZWJ1Z2AgYW5kIGBkaXNhYmxlRGVidWdgLlxuICAgKi9cbiAgaXNEZWJ1Z0VuYWJsZWQoKTogYm9vbGVhbjtcbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiBkZWJ1Z2dpbmcgaXMgZGlzYWJsZWQuIFNlZSBgZW5hYmxlRGVidWdgIGFuZCBgZGlzYWJsZURlYnVnYC5cbiAgICovXG4gIGlzRGVidWdEaXNhYmxlZCgpOiBib29sZWFuO1xuICAvKipcbiAgICogRW5hYmxlcyBkZWJ1Z2dpbmcuXG4gICAqXG4gICAqIFdoZW4gZGVidWdnaW5nIGlzIGVuYWJsZWQsIHRoZSBMaXZlVmlldyBjbGllbnQgd2lsbCBsb2cgZGVidWcgaW5mb3JtYXRpb24gdG8gdGhlIGNvbnNvbGUuXG4gICAqIFNlZSBbRGVidWdnaW5nIGNsaWVudCBldmVudHNdKGh0dHBzOi8vaGV4ZG9jcy5wbS9waG9lbml4X2xpdmVfdmlldy9qcy1pbnRlcm9wLmh0bWwjZGVidWdnaW5nLWNsaWVudC1ldmVudHMpIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICAgKi9cbiAgZW5hYmxlRGVidWcoKTogdm9pZDtcbiAgLyoqXG4gICAqIEVuYWJsZXMgcHJvZmlsaW5nLlxuICAgKlxuICAgKiBXaGVuIHByb2ZpbGluZyBpcyBlbmFibGVkLCB0aGUgTGl2ZVZpZXcgY2xpZW50IHdpbGwgbG9nIHByb2ZpbGluZyBpbmZvcm1hdGlvbiB0byB0aGUgY29uc29sZS5cbiAgICovXG4gIGVuYWJsZVByb2ZpbGluZygpOiB2b2lkO1xuICAvKipcbiAgICogRGlzYWJsZXMgZGVidWdnaW5nLlxuICAgKi9cbiAgZGlzYWJsZURlYnVnKCk6IHZvaWQ7XG4gIC8qKlxuICAgKiBEaXNhYmxlcyBwcm9maWxpbmcuXG4gICAqL1xuICBkaXNhYmxlUHJvZmlsaW5nKCk6IHZvaWQ7XG4gIC8qKlxuICAgKiBFbmFibGVzIGxhdGVuY3kgc2ltdWxhdGlvbi5cbiAgICpcbiAgICogV2hlbiBsYXRlbmN5IHNpbXVsYXRpb24gaXMgZW5hYmxlZCwgdGhlIExpdmVWaWV3IGNsaWVudCB3aWxsIGFkZCBhIGRlbGF5IHRvIHJlcXVlc3RzIGFuZCByZXNwb25zZXMgZnJvbSB0aGUgc2VydmVyLlxuICAgKiBTZWUgW1NpbXVsYXRpbmcgTGF0ZW5jeV0oaHR0cHM6Ly9oZXhkb2NzLnBtL3Bob2VuaXhfbGl2ZV92aWV3L2pzLWludGVyb3AuaHRtbCNzaW11bGF0aW5nLWxhdGVuY3kpIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICAgKi9cbiAgZW5hYmxlTGF0ZW5jeVNpbSh1cHBlckJvdW5kTXM6IG51bWJlcik6IHZvaWQ7XG4gIC8qKlxuICAgKiBEaXNhYmxlcyBsYXRlbmN5IHNpbXVsYXRpb24uXG4gICAqL1xuICBkaXNhYmxlTGF0ZW5jeVNpbSgpOiB2b2lkO1xuICAvKipcbiAgICogUmV0dXJucyB0aGUgY3VycmVudCBsYXRlbmN5IHNpbXVsYXRpb24gdXBwZXIgYm91bmQuXG4gICAqL1xuICBnZXRMYXRlbmN5U2ltKCk6IG51bWJlciB8IG51bGw7XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBQaG9lbml4IFNvY2tldCBpbnN0YW5jZS5cbiAgICovXG4gIGdldFNvY2tldCgpOiBQaG9lbml4U29ja2V0O1xuICAvKipcbiAgICogQ29ubmVjdHMgdG8gdGhlIExpdmVWaWV3IHNlcnZlci5cbiAgICovXG4gIGNvbm5lY3QoKTogdm9pZDtcbiAgLyoqXG4gICAqIERpc2Nvbm5lY3RzIGZyb20gdGhlIExpdmVWaWV3IHNlcnZlci5cbiAgICovXG4gIGRpc2Nvbm5lY3QoY2FsbGJhY2s/OiAoKSA9PiB2b2lkKTogdm9pZDtcbiAgLyoqXG4gICAqIENhbiBiZSB1c2VkIHRvIHJlcGxhY2UgdGhlIHRyYW5zcG9ydCB1c2VkIGJ5IHRoZSB1bmRlcmx5aW5nIFBob2VuaXggU29ja2V0LlxuICAgKi9cbiAgcmVwbGFjZVRyYW5zcG9ydCh0cmFuc3BvcnQ6IGFueSk6IHZvaWQ7XG4gIC8qKlxuICAgKiBFeGVjdXRlcyBhbiBlbmNvZGVkIEpTIGNvbW1hbmQsIHRhcmdldGluZyB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICpcbiAgICogU2VlIFtgUGhvZW5peC5MaXZlVmlldy5KU2BdKGh0dHBzOi8vaGV4ZG9jcy5wbS9waG9lbml4X2xpdmVfdmlldy9QaG9lbml4LkxpdmVWaWV3LkpTLmh0bWwpIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICAgKi9cbiAgZXhlY0pTKGVsOiBIVE1MRWxlbWVudCwgZW5jb2RlZEpTOiBzdHJpbmcsIGV2ZW50VHlwZT86IHN0cmluZyB8IG51bGwpOiB2b2lkO1xuICAvKipcbiAgICogUmV0dXJucyBhbiBvYmplY3Qgd2l0aCBtZXRob2RzIHRvIG1hbmlwbHVhdGUgdGhlIERPTSBhbmQgZXhlY3V0ZSBKYXZhU2NyaXB0LlxuICAgKiBUaGUgYXBwbGllZCBjaGFuZ2VzIGludGVncmF0ZSB3aXRoIHNlcnZlciBET00gcGF0Y2hpbmcuXG4gICAqXG4gICAqIFNlZSBbSmF2YVNjcmlwdCBpbnRlcm9wZXJhYmlsaXR5XShodHRwczovL2hleGRvY3MucG0vcGhvZW5peF9saXZlX3ZpZXcvanMtaW50ZXJvcC5odG1sKSBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAgICovXG4gIGpzKCk6IExpdmVTb2NrZXRKU0NvbW1hbmRzO1xufVxuXG4vKipcbiAqIEludGVyZmFjZSBkZXNjcmliaW5nIHRoZSBMaXZlU29ja2V0IGNvbnN0cnVjdG9yLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIExpdmVTb2NrZXRDb25zdHJ1Y3RvciB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IExpdmVTb2NrZXQgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSBlbmRwb2ludCAtIFRoZSBzdHJpbmcgV2ViU29ja2V0IGVuZHBvaW50LCBpZSwgYFwid3NzOi8vZXhhbXBsZS5jb20vbGl2ZVwiYCxcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBcIi9saXZlXCJgIChpbmhlcml0ZWQgaG9zdCAmIHByb3RvY29sKVxuICAgKiBAcGFyYW0gc29ja2V0IC0gdGhlIHJlcXVpcmVkIFBob2VuaXggU29ja2V0IGNsYXNzIGltcG9ydGVkIGZyb20gXCJwaG9lbml4XCIuIEZvciBleGFtcGxlOlxuICAgKlxuICAgKiAgICAgaW1wb3J0IHtTb2NrZXR9IGZyb20gXCJwaG9lbml4XCJcbiAgICogICAgIGltcG9ydCB7TGl2ZVNvY2tldH0gZnJvbSBcInBob2VuaXhfbGl2ZV92aWV3XCJcbiAgICogICAgIGxldCBsaXZlU29ja2V0ID0gbmV3IExpdmVTb2NrZXQoXCIvbGl2ZVwiLCBTb2NrZXQsIHsuLi59KVxuICAgKlxuICAgKiBAcGFyYW0gb3B0cyAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBuZXcgKFxuICAgIGVuZHBvaW50OiBzdHJpbmcsXG4gICAgc29ja2V0OiB0eXBlb2YgUGhvZW5peFNvY2tldCxcbiAgICBvcHRzPzogTGl2ZVNvY2tldE9wdGlvbnMsXG4gICk6IExpdmVTb2NrZXRJbnN0YW5jZUludGVyZmFjZTtcbn1cblxuLy8gYmVjYXVzZSBMaXZlU29ja2V0IGlzIGluIEpTIChmb3Igbm93KSwgd2UgY2FzdCBpdCB0byBvdXIgZGVmaW5lZCBUeXBlU2NyaXB0IGNvbnN0cnVjdG9yLlxuY29uc3QgTGl2ZVNvY2tldCA9IE9yaWdpbmFsTGl2ZVNvY2tldCBhcyB1bmtub3duIGFzIExpdmVTb2NrZXRDb25zdHJ1Y3RvcjtcblxuLyoqIENyZWF0ZXMgYSBob29rIGluc3RhbmNlIGZvciB0aGUgZ2l2ZW4gZWxlbWVudCBhbmQgY2FsbGJhY2tzLlxuICpcbiAqIEBwYXJhbSBlbCAtIFRoZSBlbGVtZW50IHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBob29rLlxuICogQHBhcmFtIGNhbGxiYWNrcyAtIFRoZSBsaXN0IG9mIGhvb2sgY2FsbGJhY2tzLCBzdWNoIGFzIG1vdW50ZWQsXG4gKiAgIHVwZGF0ZWQsIGRlc3Ryb3llZCwgZXRjLlxuICpcbiAqICpOb3RlKjogYGNyZWF0ZUhvb2tgIG11c3QgYmUgY2FsbGVkIGZyb20gdGhlIGBjb25uZWN0ZWRDYWxsYmFja2AgbGlmZWN5Y2xlXG4gKiB3aGljaCBpcyB0cmlnZ2VyZWQgYWZ0ZXIgdGhlIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gdGhlIERPTS4gSWYgeW91IHRyeVxuICogdG8gY2FsbCBgY3JlYXRlSG9va2AgZnJvbSB0aGUgY29uc3RydWN0b3IsIGFuIGVycm9yIHdpbGwgYmUgbG9nZ2VkLlxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogY2xhc3MgTXlDb21wb25lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7XG4gKiAgIGNvbm5lY3RlZENhbGxiYWNrKCl7XG4gKiAgICAgbGV0IG9uTGl2ZVZpZXdNb3VudGVkID0gKCkgPT4gdGhpcy5ob29rLnB1c2hFdmVudCguLi4pKVxuICogICAgIHRoaXMuaG9vayA9IGNyZWF0ZUhvb2sodGhpcywge21vdW50ZWQ6IG9uTGl2ZVZpZXdNb3VudGVkfSlcbiAqICAgfVxuICogfVxuICpcbiAqIEByZXR1cm5zIFJldHVybnMgdGhlIEhvb2sgaW5zdGFuY2UgZm9yIHRoZSBjdXN0b20gZWxlbWVudC5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlSG9vayhlbDogSFRNTEVsZW1lbnQsIGNhbGxiYWNrczogSG9vayk6IFZpZXdIb29rIHtcbiAgbGV0IGV4aXN0aW5nSG9vayA9IERPTS5nZXRDdXN0b21FbEhvb2soZWwpO1xuICBpZiAoZXhpc3RpbmdIb29rKSB7XG4gICAgcmV0dXJuIGV4aXN0aW5nSG9vaztcbiAgfVxuXG4gIGxldCBob29rID0gbmV3IFZpZXdIb29rKFZpZXcuY2xvc2VzdFZpZXcoZWwpLCBlbCwgY2FsbGJhY2tzKTtcbiAgRE9NLnB1dEN1c3RvbUVsSG9vayhlbCwgaG9vayk7XG4gIHJldHVybiBob29rO1xufVxuXG5leHBvcnQgeyBMaXZlU29ja2V0LCBpc1VzZWRJbnB1dCwgY3JlYXRlSG9vaywgVmlld0hvb2ssIEhvb2ssIEhvb2tzT3B0aW9ucyB9O1xuIiwgIi8vIHdyYXBzIHZhbHVlIGluIGNsb3N1cmUgb3IgcmV0dXJucyBjbG9zdXJlXG5leHBvcnQgbGV0IGNsb3N1cmUgPSAodmFsdWUpID0+IHtcbiAgaWYodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCIpe1xuICAgIHJldHVybiB2YWx1ZVxuICB9IGVsc2Uge1xuICAgIGxldCBjbG9zdXJlID0gZnVuY3Rpb24gKCl7IHJldHVybiB2YWx1ZSB9XG4gICAgcmV0dXJuIGNsb3N1cmVcbiAgfVxufVxuIiwgImV4cG9ydCBjb25zdCBnbG9iYWxTZWxmID0gdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogbnVsbFxuZXhwb3J0IGNvbnN0IHBoeFdpbmRvdyA9IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiBudWxsXG5leHBvcnQgY29uc3QgZ2xvYmFsID0gZ2xvYmFsU2VsZiB8fCBwaHhXaW5kb3cgfHwgZ2xvYmFsVGhpc1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfVlNOID0gXCIyLjAuMFwiXG5leHBvcnQgY29uc3QgU09DS0VUX1NUQVRFUyA9IHtjb25uZWN0aW5nOiAwLCBvcGVuOiAxLCBjbG9zaW5nOiAyLCBjbG9zZWQ6IDN9XG5leHBvcnQgY29uc3QgREVGQVVMVF9USU1FT1VUID0gMTAwMDBcbmV4cG9ydCBjb25zdCBXU19DTE9TRV9OT1JNQUwgPSAxMDAwXG5leHBvcnQgY29uc3QgQ0hBTk5FTF9TVEFURVMgPSB7XG4gIGNsb3NlZDogXCJjbG9zZWRcIixcbiAgZXJyb3JlZDogXCJlcnJvcmVkXCIsXG4gIGpvaW5lZDogXCJqb2luZWRcIixcbiAgam9pbmluZzogXCJqb2luaW5nXCIsXG4gIGxlYXZpbmc6IFwibGVhdmluZ1wiLFxufVxuZXhwb3J0IGNvbnN0IENIQU5ORUxfRVZFTlRTID0ge1xuICBjbG9zZTogXCJwaHhfY2xvc2VcIixcbiAgZXJyb3I6IFwicGh4X2Vycm9yXCIsXG4gIGpvaW46IFwicGh4X2pvaW5cIixcbiAgcmVwbHk6IFwicGh4X3JlcGx5XCIsXG4gIGxlYXZlOiBcInBoeF9sZWF2ZVwiXG59XG5cbmV4cG9ydCBjb25zdCBUUkFOU1BPUlRTID0ge1xuICBsb25ncG9sbDogXCJsb25ncG9sbFwiLFxuICB3ZWJzb2NrZXQ6IFwid2Vic29ja2V0XCJcbn1cbmV4cG9ydCBjb25zdCBYSFJfU1RBVEVTID0ge1xuICBjb21wbGV0ZTogNFxufVxuZXhwb3J0IGNvbnN0IEFVVEhfVE9LRU5fUFJFRklYID0gXCJiYXNlNjR1cmwuYmVhcmVyLnBoeC5cIlxuIiwgIi8qKlxuICogSW5pdGlhbGl6ZXMgdGhlIFB1c2hcbiAqIEBwYXJhbSB7Q2hhbm5lbH0gY2hhbm5lbCAtIFRoZSBDaGFubmVsXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnQgLSBUaGUgZXZlbnQsIGZvciBleGFtcGxlIGBcInBoeF9qb2luXCJgXG4gKiBAcGFyYW0ge09iamVjdH0gcGF5bG9hZCAtIFRoZSBwYXlsb2FkLCBmb3IgZXhhbXBsZSBge3VzZXJfaWQ6IDEyM31gXG4gKiBAcGFyYW0ge251bWJlcn0gdGltZW91dCAtIFRoZSBwdXNoIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFB1c2gge1xuICBjb25zdHJ1Y3RvcihjaGFubmVsLCBldmVudCwgcGF5bG9hZCwgdGltZW91dCl7XG4gICAgdGhpcy5jaGFubmVsID0gY2hhbm5lbFxuICAgIHRoaXMuZXZlbnQgPSBldmVudFxuICAgIHRoaXMucGF5bG9hZCA9IHBheWxvYWQgfHwgZnVuY3Rpb24gKCl7IHJldHVybiB7fSB9XG4gICAgdGhpcy5yZWNlaXZlZFJlc3AgPSBudWxsXG4gICAgdGhpcy50aW1lb3V0ID0gdGltZW91dFxuICAgIHRoaXMudGltZW91dFRpbWVyID0gbnVsbFxuICAgIHRoaXMucmVjSG9va3MgPSBbXVxuICAgIHRoaXMuc2VudCA9IGZhbHNlXG4gIH1cblxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXRcbiAgICovXG4gIHJlc2VuZCh0aW1lb3V0KXtcbiAgICB0aGlzLnRpbWVvdXQgPSB0aW1lb3V0XG4gICAgdGhpcy5yZXNldCgpXG4gICAgdGhpcy5zZW5kKClcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKi9cbiAgc2VuZCgpe1xuICAgIGlmKHRoaXMuaGFzUmVjZWl2ZWQoXCJ0aW1lb3V0XCIpKXsgcmV0dXJuIH1cbiAgICB0aGlzLnN0YXJ0VGltZW91dCgpXG4gICAgdGhpcy5zZW50ID0gdHJ1ZVxuICAgIHRoaXMuY2hhbm5lbC5zb2NrZXQucHVzaCh7XG4gICAgICB0b3BpYzogdGhpcy5jaGFubmVsLnRvcGljLFxuICAgICAgZXZlbnQ6IHRoaXMuZXZlbnQsXG4gICAgICBwYXlsb2FkOiB0aGlzLnBheWxvYWQoKSxcbiAgICAgIHJlZjogdGhpcy5yZWYsXG4gICAgICBqb2luX3JlZjogdGhpcy5jaGFubmVsLmpvaW5SZWYoKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHsqfSBzdGF0dXNcbiAgICogQHBhcmFtIHsqfSBjYWxsYmFja1xuICAgKi9cbiAgcmVjZWl2ZShzdGF0dXMsIGNhbGxiYWNrKXtcbiAgICBpZih0aGlzLmhhc1JlY2VpdmVkKHN0YXR1cykpe1xuICAgICAgY2FsbGJhY2sodGhpcy5yZWNlaXZlZFJlc3AucmVzcG9uc2UpXG4gICAgfVxuXG4gICAgdGhpcy5yZWNIb29rcy5wdXNoKHtzdGF0dXMsIGNhbGxiYWNrfSlcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICByZXNldCgpe1xuICAgIHRoaXMuY2FuY2VsUmVmRXZlbnQoKVxuICAgIHRoaXMucmVmID0gbnVsbFxuICAgIHRoaXMucmVmRXZlbnQgPSBudWxsXG4gICAgdGhpcy5yZWNlaXZlZFJlc3AgPSBudWxsXG4gICAgdGhpcy5zZW50ID0gZmFsc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgbWF0Y2hSZWNlaXZlKHtzdGF0dXMsIHJlc3BvbnNlLCBfcmVmfSl7XG4gICAgdGhpcy5yZWNIb29rcy5maWx0ZXIoaCA9PiBoLnN0YXR1cyA9PT0gc3RhdHVzKVxuICAgICAgLmZvckVhY2goaCA9PiBoLmNhbGxiYWNrKHJlc3BvbnNlKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgY2FuY2VsUmVmRXZlbnQoKXtcbiAgICBpZighdGhpcy5yZWZFdmVudCl7IHJldHVybiB9XG4gICAgdGhpcy5jaGFubmVsLm9mZih0aGlzLnJlZkV2ZW50KVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBjYW5jZWxUaW1lb3V0KCl7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZW91dFRpbWVyKVxuICAgIHRoaXMudGltZW91dFRpbWVyID0gbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBzdGFydFRpbWVvdXQoKXtcbiAgICBpZih0aGlzLnRpbWVvdXRUaW1lcil7IHRoaXMuY2FuY2VsVGltZW91dCgpIH1cbiAgICB0aGlzLnJlZiA9IHRoaXMuY2hhbm5lbC5zb2NrZXQubWFrZVJlZigpXG4gICAgdGhpcy5yZWZFdmVudCA9IHRoaXMuY2hhbm5lbC5yZXBseUV2ZW50TmFtZSh0aGlzLnJlZilcblxuICAgIHRoaXMuY2hhbm5lbC5vbih0aGlzLnJlZkV2ZW50LCBwYXlsb2FkID0+IHtcbiAgICAgIHRoaXMuY2FuY2VsUmVmRXZlbnQoKVxuICAgICAgdGhpcy5jYW5jZWxUaW1lb3V0KClcbiAgICAgIHRoaXMucmVjZWl2ZWRSZXNwID0gcGF5bG9hZFxuICAgICAgdGhpcy5tYXRjaFJlY2VpdmUocGF5bG9hZClcbiAgICB9KVxuXG4gICAgdGhpcy50aW1lb3V0VGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMudHJpZ2dlcihcInRpbWVvdXRcIiwge30pXG4gICAgfSwgdGhpcy50aW1lb3V0KVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBoYXNSZWNlaXZlZChzdGF0dXMpe1xuICAgIHJldHVybiB0aGlzLnJlY2VpdmVkUmVzcCAmJiB0aGlzLnJlY2VpdmVkUmVzcC5zdGF0dXMgPT09IHN0YXR1c1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICB0cmlnZ2VyKHN0YXR1cywgcmVzcG9uc2Upe1xuICAgIHRoaXMuY2hhbm5lbC50cmlnZ2VyKHRoaXMucmVmRXZlbnQsIHtzdGF0dXMsIHJlc3BvbnNlfSlcbiAgfVxufVxuIiwgIi8qKlxuICpcbiAqIENyZWF0ZXMgYSB0aW1lciB0aGF0IGFjY2VwdHMgYSBgdGltZXJDYWxjYCBmdW5jdGlvbiB0byBwZXJmb3JtXG4gKiBjYWxjdWxhdGVkIHRpbWVvdXQgcmV0cmllcywgc3VjaCBhcyBleHBvbmVudGlhbCBiYWNrb2ZmLlxuICpcbiAqIEBleGFtcGxlXG4gKiBsZXQgcmVjb25uZWN0VGltZXIgPSBuZXcgVGltZXIoKCkgPT4gdGhpcy5jb25uZWN0KCksIGZ1bmN0aW9uKHRyaWVzKXtcbiAqICAgcmV0dXJuIFsxMDAwLCA1MDAwLCAxMDAwMF1bdHJpZXMgLSAxXSB8fCAxMDAwMFxuICogfSlcbiAqIHJlY29ubmVjdFRpbWVyLnNjaGVkdWxlVGltZW91dCgpIC8vIGZpcmVzIGFmdGVyIDEwMDBcbiAqIHJlY29ubmVjdFRpbWVyLnNjaGVkdWxlVGltZW91dCgpIC8vIGZpcmVzIGFmdGVyIDUwMDBcbiAqIHJlY29ubmVjdFRpbWVyLnJlc2V0KClcbiAqIHJlY29ubmVjdFRpbWVyLnNjaGVkdWxlVGltZW91dCgpIC8vIGZpcmVzIGFmdGVyIDEwMDBcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICogQHBhcmFtIHtGdW5jdGlvbn0gdGltZXJDYWxjXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRpbWVyIHtcbiAgY29uc3RydWN0b3IoY2FsbGJhY2ssIHRpbWVyQ2FsYyl7XG4gICAgdGhpcy5jYWxsYmFjayA9IGNhbGxiYWNrXG4gICAgdGhpcy50aW1lckNhbGMgPSB0aW1lckNhbGNcbiAgICB0aGlzLnRpbWVyID0gbnVsbFxuICAgIHRoaXMudHJpZXMgPSAwXG4gIH1cblxuICByZXNldCgpe1xuICAgIHRoaXMudHJpZXMgPSAwXG4gICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpXG4gIH1cblxuICAvKipcbiAgICogQ2FuY2VscyBhbnkgcHJldmlvdXMgc2NoZWR1bGVUaW1lb3V0IGFuZCBzY2hlZHVsZXMgY2FsbGJhY2tcbiAgICovXG4gIHNjaGVkdWxlVGltZW91dCgpe1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVyKVxuXG4gICAgdGhpcy50aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy50cmllcyA9IHRoaXMudHJpZXMgKyAxXG4gICAgICB0aGlzLmNhbGxiYWNrKClcbiAgICB9LCB0aGlzLnRpbWVyQ2FsYyh0aGlzLnRyaWVzICsgMSkpXG4gIH1cbn1cbiIsICJpbXBvcnQge2Nsb3N1cmV9IGZyb20gXCIuL3V0aWxzXCJcbmltcG9ydCB7XG4gIENIQU5ORUxfRVZFTlRTLFxuICBDSEFOTkVMX1NUQVRFUyxcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCJcblxuaW1wb3J0IFB1c2ggZnJvbSBcIi4vcHVzaFwiXG5pbXBvcnQgVGltZXIgZnJvbSBcIi4vdGltZXJcIlxuXG4vKipcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdG9waWNcbiAqIEBwYXJhbSB7KE9iamVjdHxmdW5jdGlvbil9IHBhcmFtc1xuICogQHBhcmFtIHtTb2NrZXR9IHNvY2tldFxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDaGFubmVsIHtcbiAgY29uc3RydWN0b3IodG9waWMsIHBhcmFtcywgc29ja2V0KXtcbiAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMuY2xvc2VkXG4gICAgdGhpcy50b3BpYyA9IHRvcGljXG4gICAgdGhpcy5wYXJhbXMgPSBjbG9zdXJlKHBhcmFtcyB8fCB7fSlcbiAgICB0aGlzLnNvY2tldCA9IHNvY2tldFxuICAgIHRoaXMuYmluZGluZ3MgPSBbXVxuICAgIHRoaXMuYmluZGluZ1JlZiA9IDBcbiAgICB0aGlzLnRpbWVvdXQgPSB0aGlzLnNvY2tldC50aW1lb3V0XG4gICAgdGhpcy5qb2luZWRPbmNlID0gZmFsc2VcbiAgICB0aGlzLmpvaW5QdXNoID0gbmV3IFB1c2godGhpcywgQ0hBTk5FTF9FVkVOVFMuam9pbiwgdGhpcy5wYXJhbXMsIHRoaXMudGltZW91dClcbiAgICB0aGlzLnB1c2hCdWZmZXIgPSBbXVxuICAgIHRoaXMuc3RhdGVDaGFuZ2VSZWZzID0gW11cblxuICAgIHRoaXMucmVqb2luVGltZXIgPSBuZXcgVGltZXIoKCkgPT4ge1xuICAgICAgaWYodGhpcy5zb2NrZXQuaXNDb25uZWN0ZWQoKSl7IHRoaXMucmVqb2luKCkgfVxuICAgIH0sIHRoaXMuc29ja2V0LnJlam9pbkFmdGVyTXMpXG4gICAgdGhpcy5zdGF0ZUNoYW5nZVJlZnMucHVzaCh0aGlzLnNvY2tldC5vbkVycm9yKCgpID0+IHRoaXMucmVqb2luVGltZXIucmVzZXQoKSkpXG4gICAgdGhpcy5zdGF0ZUNoYW5nZVJlZnMucHVzaCh0aGlzLnNvY2tldC5vbk9wZW4oKCkgPT4ge1xuICAgICAgdGhpcy5yZWpvaW5UaW1lci5yZXNldCgpXG4gICAgICBpZih0aGlzLmlzRXJyb3JlZCgpKXsgdGhpcy5yZWpvaW4oKSB9XG4gICAgfSlcbiAgICApXG4gICAgdGhpcy5qb2luUHVzaC5yZWNlaXZlKFwib2tcIiwgKCkgPT4ge1xuICAgICAgdGhpcy5zdGF0ZSA9IENIQU5ORUxfU1RBVEVTLmpvaW5lZFxuICAgICAgdGhpcy5yZWpvaW5UaW1lci5yZXNldCgpXG4gICAgICB0aGlzLnB1c2hCdWZmZXIuZm9yRWFjaChwdXNoRXZlbnQgPT4gcHVzaEV2ZW50LnNlbmQoKSlcbiAgICAgIHRoaXMucHVzaEJ1ZmZlciA9IFtdXG4gICAgfSlcbiAgICB0aGlzLmpvaW5QdXNoLnJlY2VpdmUoXCJlcnJvclwiLCAoKSA9PiB7XG4gICAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMuZXJyb3JlZFxuICAgICAgaWYodGhpcy5zb2NrZXQuaXNDb25uZWN0ZWQoKSl7IHRoaXMucmVqb2luVGltZXIuc2NoZWR1bGVUaW1lb3V0KCkgfVxuICAgIH0pXG4gICAgdGhpcy5vbkNsb3NlKCgpID0+IHtcbiAgICAgIHRoaXMucmVqb2luVGltZXIucmVzZXQoKVxuICAgICAgaWYodGhpcy5zb2NrZXQuaGFzTG9nZ2VyKCkpIHRoaXMuc29ja2V0LmxvZyhcImNoYW5uZWxcIiwgYGNsb3NlICR7dGhpcy50b3BpY30gJHt0aGlzLmpvaW5SZWYoKX1gKVxuICAgICAgdGhpcy5zdGF0ZSA9IENIQU5ORUxfU1RBVEVTLmNsb3NlZFxuICAgICAgdGhpcy5zb2NrZXQucmVtb3ZlKHRoaXMpXG4gICAgfSlcbiAgICB0aGlzLm9uRXJyb3IocmVhc29uID0+IHtcbiAgICAgIGlmKHRoaXMuc29ja2V0Lmhhc0xvZ2dlcigpKSB0aGlzLnNvY2tldC5sb2coXCJjaGFubmVsXCIsIGBlcnJvciAke3RoaXMudG9waWN9YCwgcmVhc29uKVxuICAgICAgaWYodGhpcy5pc0pvaW5pbmcoKSl7IHRoaXMuam9pblB1c2gucmVzZXQoKSB9XG4gICAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMuZXJyb3JlZFxuICAgICAgaWYodGhpcy5zb2NrZXQuaXNDb25uZWN0ZWQoKSl7IHRoaXMucmVqb2luVGltZXIuc2NoZWR1bGVUaW1lb3V0KCkgfVxuICAgIH0pXG4gICAgdGhpcy5qb2luUHVzaC5yZWNlaXZlKFwidGltZW91dFwiLCAoKSA9PiB7XG4gICAgICBpZih0aGlzLnNvY2tldC5oYXNMb2dnZXIoKSkgdGhpcy5zb2NrZXQubG9nKFwiY2hhbm5lbFwiLCBgdGltZW91dCAke3RoaXMudG9waWN9ICgke3RoaXMuam9pblJlZigpfSlgLCB0aGlzLmpvaW5QdXNoLnRpbWVvdXQpXG4gICAgICBsZXQgbGVhdmVQdXNoID0gbmV3IFB1c2godGhpcywgQ0hBTk5FTF9FVkVOVFMubGVhdmUsIGNsb3N1cmUoe30pLCB0aGlzLnRpbWVvdXQpXG4gICAgICBsZWF2ZVB1c2guc2VuZCgpXG4gICAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMuZXJyb3JlZFxuICAgICAgdGhpcy5qb2luUHVzaC5yZXNldCgpXG4gICAgICBpZih0aGlzLnNvY2tldC5pc0Nvbm5lY3RlZCgpKXsgdGhpcy5yZWpvaW5UaW1lci5zY2hlZHVsZVRpbWVvdXQoKSB9XG4gICAgfSlcbiAgICB0aGlzLm9uKENIQU5ORUxfRVZFTlRTLnJlcGx5LCAocGF5bG9hZCwgcmVmKSA9PiB7XG4gICAgICB0aGlzLnRyaWdnZXIodGhpcy5yZXBseUV2ZW50TmFtZShyZWYpLCBwYXlsb2FkKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogSm9pbiB0aGUgY2hhbm5lbFxuICAgKiBAcGFyYW0ge2ludGVnZXJ9IHRpbWVvdXRcbiAgICogQHJldHVybnMge1B1c2h9XG4gICAqL1xuICBqb2luKHRpbWVvdXQgPSB0aGlzLnRpbWVvdXQpe1xuICAgIGlmKHRoaXMuam9pbmVkT25jZSl7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0cmllZCB0byBqb2luIG11bHRpcGxlIHRpbWVzLiAnam9pbicgY2FuIG9ubHkgYmUgY2FsbGVkIGEgc2luZ2xlIHRpbWUgcGVyIGNoYW5uZWwgaW5zdGFuY2VcIilcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50aW1lb3V0ID0gdGltZW91dFxuICAgICAgdGhpcy5qb2luZWRPbmNlID0gdHJ1ZVxuICAgICAgdGhpcy5yZWpvaW4oKVxuICAgICAgcmV0dXJuIHRoaXMuam9pblB1c2hcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSG9vayBpbnRvIGNoYW5uZWwgY2xvc2VcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIG9uQ2xvc2UoY2FsbGJhY2spe1xuICAgIHRoaXMub24oQ0hBTk5FTF9FVkVOVFMuY2xvc2UsIGNhbGxiYWNrKVxuICB9XG5cbiAgLyoqXG4gICAqIEhvb2sgaW50byBjaGFubmVsIGVycm9yc1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgb25FcnJvcihjYWxsYmFjayl7XG4gICAgcmV0dXJuIHRoaXMub24oQ0hBTk5FTF9FVkVOVFMuZXJyb3IsIHJlYXNvbiA9PiBjYWxsYmFjayhyZWFzb24pKVxuICB9XG5cbiAgLyoqXG4gICAqIFN1YnNjcmliZXMgb24gY2hhbm5lbCBldmVudHNcbiAgICpcbiAgICogU3Vic2NyaXB0aW9uIHJldHVybnMgYSByZWYgY291bnRlciwgd2hpY2ggY2FuIGJlIHVzZWQgbGF0ZXIgdG9cbiAgICogdW5zdWJzY3JpYmUgdGhlIGV4YWN0IGV2ZW50IGxpc3RlbmVyXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGNvbnN0IHJlZjEgPSBjaGFubmVsLm9uKFwiZXZlbnRcIiwgZG9fc3R1ZmYpXG4gICAqIGNvbnN0IHJlZjIgPSBjaGFubmVsLm9uKFwiZXZlbnRcIiwgZG9fb3RoZXJfc3R1ZmYpXG4gICAqIGNoYW5uZWwub2ZmKFwiZXZlbnRcIiwgcmVmMSlcbiAgICogLy8gU2luY2UgdW5zdWJzY3JpcHRpb24sIGRvX3N0dWZmIHdvbid0IGZpcmUsXG4gICAqIC8vIHdoaWxlIGRvX290aGVyX3N0dWZmIHdpbGwga2VlcCBmaXJpbmcgb24gdGhlIFwiZXZlbnRcIlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICogQHJldHVybnMge2ludGVnZXJ9IHJlZlxuICAgKi9cbiAgb24oZXZlbnQsIGNhbGxiYWNrKXtcbiAgICBsZXQgcmVmID0gdGhpcy5iaW5kaW5nUmVmKytcbiAgICB0aGlzLmJpbmRpbmdzLnB1c2goe2V2ZW50LCByZWYsIGNhbGxiYWNrfSlcbiAgICByZXR1cm4gcmVmXG4gIH1cblxuICAvKipcbiAgICogVW5zdWJzY3JpYmVzIG9mZiBvZiBjaGFubmVsIGV2ZW50c1xuICAgKlxuICAgKiBVc2UgdGhlIHJlZiByZXR1cm5lZCBmcm9tIGEgY2hhbm5lbC5vbigpIHRvIHVuc3Vic2NyaWJlIG9uZVxuICAgKiBoYW5kbGVyLCBvciBwYXNzIG5vdGhpbmcgZm9yIHRoZSByZWYgdG8gdW5zdWJzY3JpYmUgYWxsXG4gICAqIGhhbmRsZXJzIGZvciB0aGUgZ2l2ZW4gZXZlbnQuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIC8vIFVuc3Vic2NyaWJlIHRoZSBkb19zdHVmZiBoYW5kbGVyXG4gICAqIGNvbnN0IHJlZjEgPSBjaGFubmVsLm9uKFwiZXZlbnRcIiwgZG9fc3R1ZmYpXG4gICAqIGNoYW5uZWwub2ZmKFwiZXZlbnRcIiwgcmVmMSlcbiAgICpcbiAgICogLy8gVW5zdWJzY3JpYmUgYWxsIGhhbmRsZXJzIGZyb20gZXZlbnRcbiAgICogY2hhbm5lbC5vZmYoXCJldmVudFwiKVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcbiAgICogQHBhcmFtIHtpbnRlZ2VyfSByZWZcbiAgICovXG4gIG9mZihldmVudCwgcmVmKXtcbiAgICB0aGlzLmJpbmRpbmdzID0gdGhpcy5iaW5kaW5ncy5maWx0ZXIoKGJpbmQpID0+IHtcbiAgICAgIHJldHVybiAhKGJpbmQuZXZlbnQgPT09IGV2ZW50ICYmICh0eXBlb2YgcmVmID09PSBcInVuZGVmaW5lZFwiIHx8IHJlZiA9PT0gYmluZC5yZWYpKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGNhblB1c2goKXsgcmV0dXJuIHRoaXMuc29ja2V0LmlzQ29ubmVjdGVkKCkgJiYgdGhpcy5pc0pvaW5lZCgpIH1cblxuICAvKipcbiAgICogU2VuZHMgYSBtZXNzYWdlIGBldmVudGAgdG8gcGhvZW5peCB3aXRoIHRoZSBwYXlsb2FkIGBwYXlsb2FkYC5cbiAgICogUGhvZW5peCByZWNlaXZlcyB0aGlzIGluIHRoZSBgaGFuZGxlX2luKGV2ZW50LCBwYXlsb2FkLCBzb2NrZXQpYFxuICAgKiBmdW5jdGlvbi4gaWYgcGhvZW5peCByZXBsaWVzIG9yIGl0IHRpbWVzIG91dCAoZGVmYXVsdCAxMDAwMG1zKSxcbiAgICogdGhlbiBvcHRpb25hbGx5IHRoZSByZXBseSBjYW4gYmUgcmVjZWl2ZWQuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGNoYW5uZWwucHVzaChcImV2ZW50XCIpXG4gICAqICAgLnJlY2VpdmUoXCJva1wiLCBwYXlsb2FkID0+IGNvbnNvbGUubG9nKFwicGhvZW5peCByZXBsaWVkOlwiLCBwYXlsb2FkKSlcbiAgICogICAucmVjZWl2ZShcImVycm9yXCIsIGVyciA9PiBjb25zb2xlLmxvZyhcInBob2VuaXggZXJyb3JlZFwiLCBlcnIpKVxuICAgKiAgIC5yZWNlaXZlKFwidGltZW91dFwiLCAoKSA9PiBjb25zb2xlLmxvZyhcInRpbWVkIG91dCBwdXNoaW5nXCIpKVxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcbiAgICogQHBhcmFtIHtPYmplY3R9IHBheWxvYWRcbiAgICogQHBhcmFtIHtudW1iZXJ9IFt0aW1lb3V0XVxuICAgKiBAcmV0dXJucyB7UHVzaH1cbiAgICovXG4gIHB1c2goZXZlbnQsIHBheWxvYWQsIHRpbWVvdXQgPSB0aGlzLnRpbWVvdXQpe1xuICAgIHBheWxvYWQgPSBwYXlsb2FkIHx8IHt9XG4gICAgaWYoIXRoaXMuam9pbmVkT25jZSl7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHRyaWVkIHRvIHB1c2ggJyR7ZXZlbnR9JyB0byAnJHt0aGlzLnRvcGljfScgYmVmb3JlIGpvaW5pbmcuIFVzZSBjaGFubmVsLmpvaW4oKSBiZWZvcmUgcHVzaGluZyBldmVudHNgKVxuICAgIH1cbiAgICBsZXQgcHVzaEV2ZW50ID0gbmV3IFB1c2godGhpcywgZXZlbnQsIGZ1bmN0aW9uICgpeyByZXR1cm4gcGF5bG9hZCB9LCB0aW1lb3V0KVxuICAgIGlmKHRoaXMuY2FuUHVzaCgpKXtcbiAgICAgIHB1c2hFdmVudC5zZW5kKClcbiAgICB9IGVsc2Uge1xuICAgICAgcHVzaEV2ZW50LnN0YXJ0VGltZW91dCgpXG4gICAgICB0aGlzLnB1c2hCdWZmZXIucHVzaChwdXNoRXZlbnQpXG4gICAgfVxuXG4gICAgcmV0dXJuIHB1c2hFdmVudFxuICB9XG5cbiAgLyoqIExlYXZlcyB0aGUgY2hhbm5lbFxuICAgKlxuICAgKiBVbnN1YnNjcmliZXMgZnJvbSBzZXJ2ZXIgZXZlbnRzLCBhbmRcbiAgICogaW5zdHJ1Y3RzIGNoYW5uZWwgdG8gdGVybWluYXRlIG9uIHNlcnZlclxuICAgKlxuICAgKiBUcmlnZ2VycyBvbkNsb3NlKCkgaG9va3NcbiAgICpcbiAgICogVG8gcmVjZWl2ZSBsZWF2ZSBhY2tub3dsZWRnZW1lbnRzLCB1c2UgdGhlIGByZWNlaXZlYFxuICAgKiBob29rIHRvIGJpbmQgdG8gdGhlIHNlcnZlciBhY2ssIGllOlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBjaGFubmVsLmxlYXZlKCkucmVjZWl2ZShcIm9rXCIsICgpID0+IGFsZXJ0KFwibGVmdCFcIikgKVxuICAgKlxuICAgKiBAcGFyYW0ge2ludGVnZXJ9IHRpbWVvdXRcbiAgICogQHJldHVybnMge1B1c2h9XG4gICAqL1xuICBsZWF2ZSh0aW1lb3V0ID0gdGhpcy50aW1lb3V0KXtcbiAgICB0aGlzLnJlam9pblRpbWVyLnJlc2V0KClcbiAgICB0aGlzLmpvaW5QdXNoLmNhbmNlbFRpbWVvdXQoKVxuXG4gICAgdGhpcy5zdGF0ZSA9IENIQU5ORUxfU1RBVEVTLmxlYXZpbmdcbiAgICBsZXQgb25DbG9zZSA9ICgpID0+IHtcbiAgICAgIGlmKHRoaXMuc29ja2V0Lmhhc0xvZ2dlcigpKSB0aGlzLnNvY2tldC5sb2coXCJjaGFubmVsXCIsIGBsZWF2ZSAke3RoaXMudG9waWN9YClcbiAgICAgIHRoaXMudHJpZ2dlcihDSEFOTkVMX0VWRU5UUy5jbG9zZSwgXCJsZWF2ZVwiKVxuICAgIH1cbiAgICBsZXQgbGVhdmVQdXNoID0gbmV3IFB1c2godGhpcywgQ0hBTk5FTF9FVkVOVFMubGVhdmUsIGNsb3N1cmUoe30pLCB0aW1lb3V0KVxuICAgIGxlYXZlUHVzaC5yZWNlaXZlKFwib2tcIiwgKCkgPT4gb25DbG9zZSgpKVxuICAgICAgLnJlY2VpdmUoXCJ0aW1lb3V0XCIsICgpID0+IG9uQ2xvc2UoKSlcbiAgICBsZWF2ZVB1c2guc2VuZCgpXG4gICAgaWYoIXRoaXMuY2FuUHVzaCgpKXsgbGVhdmVQdXNoLnRyaWdnZXIoXCJva1wiLCB7fSkgfVxuXG4gICAgcmV0dXJuIGxlYXZlUHVzaFxuICB9XG5cbiAgLyoqXG4gICAqIE92ZXJyaWRhYmxlIG1lc3NhZ2UgaG9va1xuICAgKlxuICAgKiBSZWNlaXZlcyBhbGwgZXZlbnRzIGZvciBzcGVjaWFsaXplZCBtZXNzYWdlIGhhbmRsaW5nXG4gICAqIGJlZm9yZSBkaXNwYXRjaGluZyB0byB0aGUgY2hhbm5lbCBjYWxsYmFja3MuXG4gICAqXG4gICAqIE11c3QgcmV0dXJuIHRoZSBwYXlsb2FkLCBtb2RpZmllZCBvciB1bm1vZGlmaWVkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuICAgKiBAcGFyYW0ge09iamVjdH0gcGF5bG9hZFxuICAgKiBAcGFyYW0ge2ludGVnZXJ9IHJlZlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fVxuICAgKi9cbiAgb25NZXNzYWdlKF9ldmVudCwgcGF5bG9hZCwgX3JlZil7IHJldHVybiBwYXlsb2FkIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGlzTWVtYmVyKHRvcGljLCBldmVudCwgcGF5bG9hZCwgam9pblJlZil7XG4gICAgaWYodGhpcy50b3BpYyAhPT0gdG9waWMpeyByZXR1cm4gZmFsc2UgfVxuXG4gICAgaWYoam9pblJlZiAmJiBqb2luUmVmICE9PSB0aGlzLmpvaW5SZWYoKSl7XG4gICAgICBpZih0aGlzLnNvY2tldC5oYXNMb2dnZXIoKSkgdGhpcy5zb2NrZXQubG9nKFwiY2hhbm5lbFwiLCBcImRyb3BwaW5nIG91dGRhdGVkIG1lc3NhZ2VcIiwge3RvcGljLCBldmVudCwgcGF5bG9hZCwgam9pblJlZn0pXG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGpvaW5SZWYoKXsgcmV0dXJuIHRoaXMuam9pblB1c2gucmVmIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHJlam9pbih0aW1lb3V0ID0gdGhpcy50aW1lb3V0KXtcbiAgICBpZih0aGlzLmlzTGVhdmluZygpKXsgcmV0dXJuIH1cbiAgICB0aGlzLnNvY2tldC5sZWF2ZU9wZW5Ub3BpYyh0aGlzLnRvcGljKVxuICAgIHRoaXMuc3RhdGUgPSBDSEFOTkVMX1NUQVRFUy5qb2luaW5nXG4gICAgdGhpcy5qb2luUHVzaC5yZXNlbmQodGltZW91dClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgdHJpZ2dlcihldmVudCwgcGF5bG9hZCwgcmVmLCBqb2luUmVmKXtcbiAgICBsZXQgaGFuZGxlZFBheWxvYWQgPSB0aGlzLm9uTWVzc2FnZShldmVudCwgcGF5bG9hZCwgcmVmLCBqb2luUmVmKVxuICAgIGlmKHBheWxvYWQgJiYgIWhhbmRsZWRQYXlsb2FkKXsgdGhyb3cgbmV3IEVycm9yKFwiY2hhbm5lbCBvbk1lc3NhZ2UgY2FsbGJhY2tzIG11c3QgcmV0dXJuIHRoZSBwYXlsb2FkLCBtb2RpZmllZCBvciB1bm1vZGlmaWVkXCIpIH1cblxuICAgIGxldCBldmVudEJpbmRpbmdzID0gdGhpcy5iaW5kaW5ncy5maWx0ZXIoYmluZCA9PiBiaW5kLmV2ZW50ID09PSBldmVudClcblxuICAgIGZvcihsZXQgaSA9IDA7IGkgPCBldmVudEJpbmRpbmdzLmxlbmd0aDsgaSsrKXtcbiAgICAgIGxldCBiaW5kID0gZXZlbnRCaW5kaW5nc1tpXVxuICAgICAgYmluZC5jYWxsYmFjayhoYW5kbGVkUGF5bG9hZCwgcmVmLCBqb2luUmVmIHx8IHRoaXMuam9pblJlZigpKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcmVwbHlFdmVudE5hbWUocmVmKXsgcmV0dXJuIGBjaGFuX3JlcGx5XyR7cmVmfWAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgaXNDbG9zZWQoKXsgcmV0dXJuIHRoaXMuc3RhdGUgPT09IENIQU5ORUxfU1RBVEVTLmNsb3NlZCB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBpc0Vycm9yZWQoKXsgcmV0dXJuIHRoaXMuc3RhdGUgPT09IENIQU5ORUxfU1RBVEVTLmVycm9yZWQgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgaXNKb2luZWQoKXsgcmV0dXJuIHRoaXMuc3RhdGUgPT09IENIQU5ORUxfU1RBVEVTLmpvaW5lZCB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBpc0pvaW5pbmcoKXsgcmV0dXJuIHRoaXMuc3RhdGUgPT09IENIQU5ORUxfU1RBVEVTLmpvaW5pbmcgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgaXNMZWF2aW5nKCl7IHJldHVybiB0aGlzLnN0YXRlID09PSBDSEFOTkVMX1NUQVRFUy5sZWF2aW5nIH1cbn1cbiIsICJpbXBvcnQge1xuICBnbG9iYWwsXG4gIFhIUl9TVEFURVNcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCJcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQWpheCB7XG5cbiAgc3RhdGljIHJlcXVlc3QobWV0aG9kLCBlbmRQb2ludCwgaGVhZGVycywgYm9keSwgdGltZW91dCwgb250aW1lb3V0LCBjYWxsYmFjayl7XG4gICAgaWYoZ2xvYmFsLlhEb21haW5SZXF1ZXN0KXtcbiAgICAgIGxldCByZXEgPSBuZXcgZ2xvYmFsLlhEb21haW5SZXF1ZXN0KCkgLy8gSUU4LCBJRTlcbiAgICAgIHJldHVybiB0aGlzLnhkb21haW5SZXF1ZXN0KHJlcSwgbWV0aG9kLCBlbmRQb2ludCwgYm9keSwgdGltZW91dCwgb250aW1lb3V0LCBjYWxsYmFjaylcbiAgICB9IGVsc2UgaWYoZ2xvYmFsLlhNTEh0dHBSZXF1ZXN0KXtcbiAgICAgIGxldCByZXEgPSBuZXcgZ2xvYmFsLlhNTEh0dHBSZXF1ZXN0KCkgLy8gSUU3KywgRmlyZWZveCwgQ2hyb21lLCBPcGVyYSwgU2FmYXJpXG4gICAgICByZXR1cm4gdGhpcy54aHJSZXF1ZXN0KHJlcSwgbWV0aG9kLCBlbmRQb2ludCwgaGVhZGVycywgYm9keSwgdGltZW91dCwgb250aW1lb3V0LCBjYWxsYmFjaylcbiAgICB9IGVsc2UgaWYoZ2xvYmFsLmZldGNoICYmIGdsb2JhbC5BYm9ydENvbnRyb2xsZXIpe1xuICAgICAgLy8gRmV0Y2ggd2l0aCBBYm9ydENvbnRyb2xsZXIgZm9yIG1vZGVybiBicm93c2Vyc1xuICAgICAgcmV0dXJuIHRoaXMuZmV0Y2hSZXF1ZXN0KG1ldGhvZCwgZW5kUG9pbnQsIGhlYWRlcnMsIGJvZHksIHRpbWVvdXQsIG9udGltZW91dCwgY2FsbGJhY2spXG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIHN1aXRhYmxlIFhNTEh0dHBSZXF1ZXN0IGltcGxlbWVudGF0aW9uIGZvdW5kXCIpXG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGZldGNoUmVxdWVzdChtZXRob2QsIGVuZFBvaW50LCBoZWFkZXJzLCBib2R5LCB0aW1lb3V0LCBvbnRpbWVvdXQsIGNhbGxiYWNrKXtcbiAgICBsZXQgb3B0aW9ucyA9IHtcbiAgICAgIG1ldGhvZCxcbiAgICAgIGhlYWRlcnMsXG4gICAgICBib2R5LFxuICAgIH1cbiAgICBsZXQgY29udHJvbGxlciA9IG51bGxcbiAgICBpZih0aW1lb3V0KXtcbiAgICAgIGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKClcbiAgICAgIGNvbnN0IF90aW1lb3V0SWQgPSBzZXRUaW1lb3V0KCgpID0+IGNvbnRyb2xsZXIuYWJvcnQoKSwgdGltZW91dClcbiAgICAgIG9wdGlvbnMuc2lnbmFsID0gY29udHJvbGxlci5zaWduYWxcbiAgICB9XG4gICAgZ2xvYmFsLmZldGNoKGVuZFBvaW50LCBvcHRpb25zKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4gcmVzcG9uc2UudGV4dCgpKVxuICAgICAgLnRoZW4oZGF0YSA9PiB0aGlzLnBhcnNlSlNPTihkYXRhKSlcbiAgICAgIC50aGVuKGRhdGEgPT4gY2FsbGJhY2sgJiYgY2FsbGJhY2soZGF0YSkpXG4gICAgICAuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgaWYoZXJyLm5hbWUgPT09IFwiQWJvcnRFcnJvclwiICYmIG9udGltZW91dCl7XG4gICAgICAgICAgb250aW1lb3V0KClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjayhudWxsKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIHJldHVybiBjb250cm9sbGVyXG4gIH1cblxuICBzdGF0aWMgeGRvbWFpblJlcXVlc3QocmVxLCBtZXRob2QsIGVuZFBvaW50LCBib2R5LCB0aW1lb3V0LCBvbnRpbWVvdXQsIGNhbGxiYWNrKXtcbiAgICByZXEudGltZW91dCA9IHRpbWVvdXRcbiAgICByZXEub3BlbihtZXRob2QsIGVuZFBvaW50KVxuICAgIHJlcS5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICBsZXQgcmVzcG9uc2UgPSB0aGlzLnBhcnNlSlNPTihyZXEucmVzcG9uc2VUZXh0KVxuICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2socmVzcG9uc2UpXG4gICAgfVxuICAgIGlmKG9udGltZW91dCl7IHJlcS5vbnRpbWVvdXQgPSBvbnRpbWVvdXQgfVxuXG4gICAgLy8gV29yayBhcm91bmQgYnVnIGluIElFOSB0aGF0IHJlcXVpcmVzIGFuIGF0dGFjaGVkIG9ucHJvZ3Jlc3MgaGFuZGxlclxuICAgIHJlcS5vbnByb2dyZXNzID0gKCkgPT4geyB9XG5cbiAgICByZXEuc2VuZChib2R5KVxuICAgIHJldHVybiByZXFcbiAgfVxuXG4gIHN0YXRpYyB4aHJSZXF1ZXN0KHJlcSwgbWV0aG9kLCBlbmRQb2ludCwgaGVhZGVycywgYm9keSwgdGltZW91dCwgb250aW1lb3V0LCBjYWxsYmFjayl7XG4gICAgcmVxLm9wZW4obWV0aG9kLCBlbmRQb2ludCwgdHJ1ZSlcbiAgICByZXEudGltZW91dCA9IHRpbWVvdXRcbiAgICBmb3IobGV0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhoZWFkZXJzKSl7XG4gICAgICByZXEuc2V0UmVxdWVzdEhlYWRlcihrZXksIHZhbHVlKVxuICAgIH1cbiAgICByZXEub25lcnJvciA9ICgpID0+IGNhbGxiYWNrICYmIGNhbGxiYWNrKG51bGwpXG4gICAgcmVxLm9ucmVhZHlzdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgIGlmKHJlcS5yZWFkeVN0YXRlID09PSBYSFJfU1RBVEVTLmNvbXBsZXRlICYmIGNhbGxiYWNrKXtcbiAgICAgICAgbGV0IHJlc3BvbnNlID0gdGhpcy5wYXJzZUpTT04ocmVxLnJlc3BvbnNlVGV4dClcbiAgICAgICAgY2FsbGJhY2socmVzcG9uc2UpXG4gICAgICB9XG4gICAgfVxuICAgIGlmKG9udGltZW91dCl7IHJlcS5vbnRpbWVvdXQgPSBvbnRpbWVvdXQgfVxuXG4gICAgcmVxLnNlbmQoYm9keSlcbiAgICByZXR1cm4gcmVxXG4gIH1cblxuICBzdGF0aWMgcGFyc2VKU09OKHJlc3Ape1xuICAgIGlmKCFyZXNwIHx8IHJlc3AgPT09IFwiXCIpeyByZXR1cm4gbnVsbCB9XG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEpTT04ucGFyc2UocmVzcClcbiAgICB9IGNhdGNoIHtcbiAgICAgIGNvbnNvbGUgJiYgY29uc29sZS5sb2coXCJmYWlsZWQgdG8gcGFyc2UgSlNPTiByZXNwb25zZVwiLCByZXNwKVxuICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgc2VyaWFsaXplKG9iaiwgcGFyZW50S2V5KXtcbiAgICBsZXQgcXVlcnlTdHIgPSBbXVxuICAgIGZvcih2YXIga2V5IGluIG9iail7XG4gICAgICBpZighT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSl7IGNvbnRpbnVlIH1cbiAgICAgIGxldCBwYXJhbUtleSA9IHBhcmVudEtleSA/IGAke3BhcmVudEtleX1bJHtrZXl9XWAgOiBrZXlcbiAgICAgIGxldCBwYXJhbVZhbCA9IG9ialtrZXldXG4gICAgICBpZih0eXBlb2YgcGFyYW1WYWwgPT09IFwib2JqZWN0XCIpe1xuICAgICAgICBxdWVyeVN0ci5wdXNoKHRoaXMuc2VyaWFsaXplKHBhcmFtVmFsLCBwYXJhbUtleSkpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBxdWVyeVN0ci5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChwYXJhbUtleSkgKyBcIj1cIiArIGVuY29kZVVSSUNvbXBvbmVudChwYXJhbVZhbCkpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBxdWVyeVN0ci5qb2luKFwiJlwiKVxuICB9XG5cbiAgc3RhdGljIGFwcGVuZFBhcmFtcyh1cmwsIHBhcmFtcyl7XG4gICAgaWYoT2JqZWN0LmtleXMocGFyYW1zKS5sZW5ndGggPT09IDApeyByZXR1cm4gdXJsIH1cblxuICAgIGxldCBwcmVmaXggPSB1cmwubWF0Y2goL1xcPy8pID8gXCImXCIgOiBcIj9cIlxuICAgIHJldHVybiBgJHt1cmx9JHtwcmVmaXh9JHt0aGlzLnNlcmlhbGl6ZShwYXJhbXMpfWBcbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIFNPQ0tFVF9TVEFURVMsXG4gIFRSQU5TUE9SVFMsXG4gIEFVVEhfVE9LRU5fUFJFRklYXG59IGZyb20gXCIuL2NvbnN0YW50c1wiXG5cbmltcG9ydCBBamF4IGZyb20gXCIuL2FqYXhcIlxuXG5sZXQgYXJyYXlCdWZmZXJUb0Jhc2U2NCA9IChidWZmZXIpID0+IHtcbiAgbGV0IGJpbmFyeSA9IFwiXCJcbiAgbGV0IGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKVxuICBsZXQgbGVuID0gYnl0ZXMuYnl0ZUxlbmd0aFxuICBmb3IobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspeyBiaW5hcnkgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSkgfVxuICByZXR1cm4gYnRvYShiaW5hcnkpXG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExvbmdQb2xsIHtcblxuICBjb25zdHJ1Y3RvcihlbmRQb2ludCwgcHJvdG9jb2xzKXtcbiAgICAvLyB3ZSBvbmx5IHN1cHBvcnQgc3VicHJvdG9jb2xzIGZvciBhdXRoVG9rZW5cbiAgICAvLyBbXCJwaG9lbml4XCIsIFwiYmFzZTY0dXJsLmJlYXJlci5waHguQkFTRTY0X0VOQ09ERURfVE9LRU5cIl1cbiAgICBpZihwcm90b2NvbHMgJiYgcHJvdG9jb2xzLmxlbmd0aCA9PT0gMiAmJiBwcm90b2NvbHNbMV0uc3RhcnRzV2l0aChBVVRIX1RPS0VOX1BSRUZJWCkpe1xuICAgICAgdGhpcy5hdXRoVG9rZW4gPSBhdG9iKHByb3RvY29sc1sxXS5zbGljZShBVVRIX1RPS0VOX1BSRUZJWC5sZW5ndGgpKVxuICAgIH1cbiAgICB0aGlzLmVuZFBvaW50ID0gbnVsbFxuICAgIHRoaXMudG9rZW4gPSBudWxsXG4gICAgdGhpcy5za2lwSGVhcnRiZWF0ID0gdHJ1ZVxuICAgIHRoaXMucmVxcyA9IG5ldyBTZXQoKVxuICAgIHRoaXMuYXdhaXRpbmdCYXRjaEFjayA9IGZhbHNlXG4gICAgdGhpcy5jdXJyZW50QmF0Y2ggPSBudWxsXG4gICAgdGhpcy5jdXJyZW50QmF0Y2hUaW1lciA9IG51bGxcbiAgICB0aGlzLmJhdGNoQnVmZmVyID0gW11cbiAgICB0aGlzLm9ub3BlbiA9IGZ1bmN0aW9uICgpeyB9IC8vIG5vb3BcbiAgICB0aGlzLm9uZXJyb3IgPSBmdW5jdGlvbiAoKXsgfSAvLyBub29wXG4gICAgdGhpcy5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAoKXsgfSAvLyBub29wXG4gICAgdGhpcy5vbmNsb3NlID0gZnVuY3Rpb24gKCl7IH0gLy8gbm9vcFxuICAgIHRoaXMucG9sbEVuZHBvaW50ID0gdGhpcy5ub3JtYWxpemVFbmRwb2ludChlbmRQb2ludClcbiAgICB0aGlzLnJlYWR5U3RhdGUgPSBTT0NLRVRfU1RBVEVTLmNvbm5lY3RpbmdcbiAgICAvLyB3ZSBtdXN0IHdhaXQgZm9yIHRoZSBjYWxsZXIgdG8gZmluaXNoIHNldHRpbmcgdXAgb3VyIGNhbGxiYWNrcyBhbmQgdGltZW91dCBwcm9wZXJ0aWVzXG4gICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnBvbGwoKSwgMClcbiAgfVxuXG4gIG5vcm1hbGl6ZUVuZHBvaW50KGVuZFBvaW50KXtcbiAgICByZXR1cm4gKGVuZFBvaW50XG4gICAgICAucmVwbGFjZShcIndzOi8vXCIsIFwiaHR0cDovL1wiKVxuICAgICAgLnJlcGxhY2UoXCJ3c3M6Ly9cIiwgXCJodHRwczovL1wiKVxuICAgICAgLnJlcGxhY2UobmV3IFJlZ0V4cChcIiguKilcXC9cIiArIFRSQU5TUE9SVFMud2Vic29ja2V0KSwgXCIkMS9cIiArIFRSQU5TUE9SVFMubG9uZ3BvbGwpKVxuICB9XG5cbiAgZW5kcG9pbnRVUkwoKXtcbiAgICByZXR1cm4gQWpheC5hcHBlbmRQYXJhbXModGhpcy5wb2xsRW5kcG9pbnQsIHt0b2tlbjogdGhpcy50b2tlbn0pXG4gIH1cblxuICBjbG9zZUFuZFJldHJ5KGNvZGUsIHJlYXNvbiwgd2FzQ2xlYW4pe1xuICAgIHRoaXMuY2xvc2UoY29kZSwgcmVhc29uLCB3YXNDbGVhbilcbiAgICB0aGlzLnJlYWR5U3RhdGUgPSBTT0NLRVRfU1RBVEVTLmNvbm5lY3RpbmdcbiAgfVxuXG4gIG9udGltZW91dCgpe1xuICAgIHRoaXMub25lcnJvcihcInRpbWVvdXRcIilcbiAgICB0aGlzLmNsb3NlQW5kUmV0cnkoMTAwNSwgXCJ0aW1lb3V0XCIsIGZhbHNlKVxuICB9XG5cbiAgaXNBY3RpdmUoKXsgcmV0dXJuIHRoaXMucmVhZHlTdGF0ZSA9PT0gU09DS0VUX1NUQVRFUy5vcGVuIHx8IHRoaXMucmVhZHlTdGF0ZSA9PT0gU09DS0VUX1NUQVRFUy5jb25uZWN0aW5nIH1cblxuICBwb2xsKCl7XG4gICAgY29uc3QgaGVhZGVycyA9IHtcIkFjY2VwdFwiOiBcImFwcGxpY2F0aW9uL2pzb25cIn1cbiAgICBpZih0aGlzLmF1dGhUb2tlbil7XG4gICAgICBoZWFkZXJzW1wiWC1QaG9lbml4LUF1dGhUb2tlblwiXSA9IHRoaXMuYXV0aFRva2VuXG4gICAgfVxuICAgIHRoaXMuYWpheChcIkdFVFwiLCBoZWFkZXJzLCBudWxsLCAoKSA9PiB0aGlzLm9udGltZW91dCgpLCByZXNwID0+IHtcbiAgICAgIGlmKHJlc3Ape1xuICAgICAgICB2YXIge3N0YXR1cywgdG9rZW4sIG1lc3NhZ2VzfSA9IHJlc3BcbiAgICAgICAgdGhpcy50b2tlbiA9IHRva2VuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0dXMgPSAwXG4gICAgICB9XG5cbiAgICAgIHN3aXRjaChzdGF0dXMpe1xuICAgICAgICBjYXNlIDIwMDpcbiAgICAgICAgICBtZXNzYWdlcy5mb3JFYWNoKG1zZyA9PiB7XG4gICAgICAgICAgICAvLyBUYXNrcyBhcmUgd2hhdCB0aGluZ3MgbGlrZSBldmVudCBoYW5kbGVycywgc2V0VGltZW91dCBjYWxsYmFja3MsXG4gICAgICAgICAgICAvLyBwcm9taXNlIHJlc29sdmVzIGFuZCBtb3JlIGFyZSBydW4gd2l0aGluLlxuICAgICAgICAgICAgLy8gSW4gbW9kZXJuIGJyb3dzZXJzLCB0aGVyZSBhcmUgdHdvIGRpZmZlcmVudCBraW5kcyBvZiB0YXNrcyxcbiAgICAgICAgICAgIC8vIG1pY3JvdGFza3MgYW5kIG1hY3JvdGFza3MuXG4gICAgICAgICAgICAvLyBNaWNyb3Rhc2tzIGFyZSBtYWlubHkgdXNlZCBmb3IgUHJvbWlzZXMsIHdoaWxlIG1hY3JvdGFza3MgYXJlXG4gICAgICAgICAgICAvLyB1c2VkIGZvciBldmVyeXRoaW5nIGVsc2UuXG4gICAgICAgICAgICAvLyBNaWNyb3Rhc2tzIGFsd2F5cyBoYXZlIHByaW9yaXR5IG92ZXIgbWFjcm90YXNrcy4gSWYgdGhlIEpTIGVuZ2luZVxuICAgICAgICAgICAgLy8gaXMgbG9va2luZyBmb3IgYSB0YXNrIHRvIHJ1biwgaXQgd2lsbCBhbHdheXMgdHJ5IHRvIGVtcHR5IHRoZVxuICAgICAgICAgICAgLy8gbWljcm90YXNrIHF1ZXVlIGJlZm9yZSBhdHRlbXB0aW5nIHRvIHJ1biBhbnl0aGluZyBmcm9tIHRoZVxuICAgICAgICAgICAgLy8gbWFjcm90YXNrIHF1ZXVlLlxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIEZvciB0aGUgV2ViU29ja2V0IHRyYW5zcG9ydCwgbWVzc2FnZXMgYWx3YXlzIGFycml2ZSBpbiB0aGVpciBvd25cbiAgICAgICAgICAgIC8vIGV2ZW50LiBUaGlzIG1lYW5zIHRoYXQgaWYgYW55IHByb21pc2VzIGFyZSByZXNvbHZlZCBmcm9tIHdpdGhpbixcbiAgICAgICAgICAgIC8vIHRoZWlyIGNhbGxiYWNrcyB3aWxsIGFsd2F5cyBmaW5pc2ggZXhlY3V0aW9uIGJ5IHRoZSB0aW1lIHRoZVxuICAgICAgICAgICAgLy8gbmV4dCBtZXNzYWdlIGV2ZW50IGhhbmRsZXIgaXMgcnVuLlxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIEluIG9yZGVyIHRvIGVtdWxhdGUgdGhpcyBiZWhhdmlvdXIsIHdlIG5lZWQgdG8gbWFrZSBzdXJlIGVhY2hcbiAgICAgICAgICAgIC8vIG9ubWVzc2FnZSBoYW5kbGVyIGlzIHJ1biB3aXRoaW4gaXRzIG93biBtYWNyb3Rhc2suXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMub25tZXNzYWdlKHtkYXRhOiBtc2d9KSwgMClcbiAgICAgICAgICB9KVxuICAgICAgICAgIHRoaXMucG9sbCgpXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAyMDQ6XG4gICAgICAgICAgdGhpcy5wb2xsKClcbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDQxMDpcbiAgICAgICAgICB0aGlzLnJlYWR5U3RhdGUgPSBTT0NLRVRfU1RBVEVTLm9wZW5cbiAgICAgICAgICB0aGlzLm9ub3Blbih7fSlcbiAgICAgICAgICB0aGlzLnBvbGwoKVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgNDAzOlxuICAgICAgICAgIHRoaXMub25lcnJvcig0MDMpXG4gICAgICAgICAgdGhpcy5jbG9zZSgxMDA4LCBcImZvcmJpZGRlblwiLCBmYWxzZSlcbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDA6XG4gICAgICAgIGNhc2UgNTAwOlxuICAgICAgICAgIHRoaXMub25lcnJvcig1MDApXG4gICAgICAgICAgdGhpcy5jbG9zZUFuZFJldHJ5KDEwMTEsIFwiaW50ZXJuYWwgc2VydmVyIGVycm9yXCIsIDUwMClcbiAgICAgICAgICBicmVha1xuICAgICAgICBkZWZhdWx0OiB0aHJvdyBuZXcgRXJyb3IoYHVuaGFuZGxlZCBwb2xsIHN0YXR1cyAke3N0YXR1c31gKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICAvLyB3ZSBjb2xsZWN0IGFsbCBwdXNoZXMgd2l0aGluIHRoZSBjdXJyZW50IGV2ZW50IGxvb3AgYnlcbiAgLy8gc2V0VGltZW91dCAwLCB3aGljaCBvcHRpbWl6ZXMgYmFjay10by1iYWNrIHByb2NlZHVyYWxcbiAgLy8gcHVzaGVzIGFnYWluc3QgYW4gZW1wdHkgYnVmZmVyXG5cbiAgc2VuZChib2R5KXtcbiAgICBpZih0eXBlb2YoYm9keSkgIT09IFwic3RyaW5nXCIpeyBib2R5ID0gYXJyYXlCdWZmZXJUb0Jhc2U2NChib2R5KSB9XG4gICAgaWYodGhpcy5jdXJyZW50QmF0Y2gpe1xuICAgICAgdGhpcy5jdXJyZW50QmF0Y2gucHVzaChib2R5KVxuICAgIH0gZWxzZSBpZih0aGlzLmF3YWl0aW5nQmF0Y2hBY2spe1xuICAgICAgdGhpcy5iYXRjaEJ1ZmZlci5wdXNoKGJvZHkpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3VycmVudEJhdGNoID0gW2JvZHldXG4gICAgICB0aGlzLmN1cnJlbnRCYXRjaFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuYmF0Y2hTZW5kKHRoaXMuY3VycmVudEJhdGNoKVxuICAgICAgICB0aGlzLmN1cnJlbnRCYXRjaCA9IG51bGxcbiAgICAgIH0sIDApXG4gICAgfVxuICB9XG5cbiAgYmF0Y2hTZW5kKG1lc3NhZ2VzKXtcbiAgICB0aGlzLmF3YWl0aW5nQmF0Y2hBY2sgPSB0cnVlXG4gICAgdGhpcy5hamF4KFwiUE9TVFwiLCB7XCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi94LW5kanNvblwifSwgbWVzc2FnZXMuam9pbihcIlxcblwiKSwgKCkgPT4gdGhpcy5vbmVycm9yKFwidGltZW91dFwiKSwgcmVzcCA9PiB7XG4gICAgICB0aGlzLmF3YWl0aW5nQmF0Y2hBY2sgPSBmYWxzZVxuICAgICAgaWYoIXJlc3AgfHwgcmVzcC5zdGF0dXMgIT09IDIwMCl7XG4gICAgICAgIHRoaXMub25lcnJvcihyZXNwICYmIHJlc3Auc3RhdHVzKVxuICAgICAgICB0aGlzLmNsb3NlQW5kUmV0cnkoMTAxMSwgXCJpbnRlcm5hbCBzZXJ2ZXIgZXJyb3JcIiwgZmFsc2UpXG4gICAgICB9IGVsc2UgaWYodGhpcy5iYXRjaEJ1ZmZlci5sZW5ndGggPiAwKXtcbiAgICAgICAgdGhpcy5iYXRjaFNlbmQodGhpcy5iYXRjaEJ1ZmZlcilcbiAgICAgICAgdGhpcy5iYXRjaEJ1ZmZlciA9IFtdXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIGNsb3NlKGNvZGUsIHJlYXNvbiwgd2FzQ2xlYW4pe1xuICAgIGZvcihsZXQgcmVxIG9mIHRoaXMucmVxcyl7IHJlcS5hYm9ydCgpIH1cbiAgICB0aGlzLnJlYWR5U3RhdGUgPSBTT0NLRVRfU1RBVEVTLmNsb3NlZFxuICAgIGxldCBvcHRzID0gT2JqZWN0LmFzc2lnbih7Y29kZTogMTAwMCwgcmVhc29uOiB1bmRlZmluZWQsIHdhc0NsZWFuOiB0cnVlfSwge2NvZGUsIHJlYXNvbiwgd2FzQ2xlYW59KVxuICAgIHRoaXMuYmF0Y2hCdWZmZXIgPSBbXVxuICAgIGNsZWFyVGltZW91dCh0aGlzLmN1cnJlbnRCYXRjaFRpbWVyKVxuICAgIHRoaXMuY3VycmVudEJhdGNoVGltZXIgPSBudWxsXG4gICAgaWYodHlwZW9mKENsb3NlRXZlbnQpICE9PSBcInVuZGVmaW5lZFwiKXtcbiAgICAgIHRoaXMub25jbG9zZShuZXcgQ2xvc2VFdmVudChcImNsb3NlXCIsIG9wdHMpKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9uY2xvc2Uob3B0cylcbiAgICB9XG4gIH1cblxuICBhamF4KG1ldGhvZCwgaGVhZGVycywgYm9keSwgb25DYWxsZXJUaW1lb3V0LCBjYWxsYmFjayl7XG4gICAgbGV0IHJlcVxuICAgIGxldCBvbnRpbWVvdXQgPSAoKSA9PiB7XG4gICAgICB0aGlzLnJlcXMuZGVsZXRlKHJlcSlcbiAgICAgIG9uQ2FsbGVyVGltZW91dCgpXG4gICAgfVxuICAgIHJlcSA9IEFqYXgucmVxdWVzdChtZXRob2QsIHRoaXMuZW5kcG9pbnRVUkwoKSwgaGVhZGVycywgYm9keSwgdGhpcy50aW1lb3V0LCBvbnRpbWVvdXQsIHJlc3AgPT4ge1xuICAgICAgdGhpcy5yZXFzLmRlbGV0ZShyZXEpXG4gICAgICBpZih0aGlzLmlzQWN0aXZlKCkpeyBjYWxsYmFjayhyZXNwKSB9XG4gICAgfSlcbiAgICB0aGlzLnJlcXMuYWRkKHJlcSlcbiAgfVxufVxuIiwgIi8qKlxuICogSW5pdGlhbGl6ZXMgdGhlIFByZXNlbmNlXG4gKiBAcGFyYW0ge0NoYW5uZWx9IGNoYW5uZWwgLSBUaGUgQ2hhbm5lbFxuICogQHBhcmFtIHtPYmplY3R9IG9wdHMgLSBUaGUgb3B0aW9ucyxcbiAqICAgICAgICBmb3IgZXhhbXBsZSBge2V2ZW50czoge3N0YXRlOiBcInN0YXRlXCIsIGRpZmY6IFwiZGlmZlwifX1gXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFByZXNlbmNlIHtcblxuICBjb25zdHJ1Y3RvcihjaGFubmVsLCBvcHRzID0ge30pe1xuICAgIGxldCBldmVudHMgPSBvcHRzLmV2ZW50cyB8fCB7c3RhdGU6IFwicHJlc2VuY2Vfc3RhdGVcIiwgZGlmZjogXCJwcmVzZW5jZV9kaWZmXCJ9XG4gICAgdGhpcy5zdGF0ZSA9IHt9XG4gICAgdGhpcy5wZW5kaW5nRGlmZnMgPSBbXVxuICAgIHRoaXMuY2hhbm5lbCA9IGNoYW5uZWxcbiAgICB0aGlzLmpvaW5SZWYgPSBudWxsXG4gICAgdGhpcy5jYWxsZXIgPSB7XG4gICAgICBvbkpvaW46IGZ1bmN0aW9uICgpeyB9LFxuICAgICAgb25MZWF2ZTogZnVuY3Rpb24gKCl7IH0sXG4gICAgICBvblN5bmM6IGZ1bmN0aW9uICgpeyB9XG4gICAgfVxuXG4gICAgdGhpcy5jaGFubmVsLm9uKGV2ZW50cy5zdGF0ZSwgbmV3U3RhdGUgPT4ge1xuICAgICAgbGV0IHtvbkpvaW4sIG9uTGVhdmUsIG9uU3luY30gPSB0aGlzLmNhbGxlclxuXG4gICAgICB0aGlzLmpvaW5SZWYgPSB0aGlzLmNoYW5uZWwuam9pblJlZigpXG4gICAgICB0aGlzLnN0YXRlID0gUHJlc2VuY2Uuc3luY1N0YXRlKHRoaXMuc3RhdGUsIG5ld1N0YXRlLCBvbkpvaW4sIG9uTGVhdmUpXG5cbiAgICAgIHRoaXMucGVuZGluZ0RpZmZzLmZvckVhY2goZGlmZiA9PiB7XG4gICAgICAgIHRoaXMuc3RhdGUgPSBQcmVzZW5jZS5zeW5jRGlmZih0aGlzLnN0YXRlLCBkaWZmLCBvbkpvaW4sIG9uTGVhdmUpXG4gICAgICB9KVxuICAgICAgdGhpcy5wZW5kaW5nRGlmZnMgPSBbXVxuICAgICAgb25TeW5jKClcbiAgICB9KVxuXG4gICAgdGhpcy5jaGFubmVsLm9uKGV2ZW50cy5kaWZmLCBkaWZmID0+IHtcbiAgICAgIGxldCB7b25Kb2luLCBvbkxlYXZlLCBvblN5bmN9ID0gdGhpcy5jYWxsZXJcblxuICAgICAgaWYodGhpcy5pblBlbmRpbmdTeW5jU3RhdGUoKSl7XG4gICAgICAgIHRoaXMucGVuZGluZ0RpZmZzLnB1c2goZGlmZilcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc3RhdGUgPSBQcmVzZW5jZS5zeW5jRGlmZih0aGlzLnN0YXRlLCBkaWZmLCBvbkpvaW4sIG9uTGVhdmUpXG4gICAgICAgIG9uU3luYygpXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIG9uSm9pbihjYWxsYmFjayl7IHRoaXMuY2FsbGVyLm9uSm9pbiA9IGNhbGxiYWNrIH1cblxuICBvbkxlYXZlKGNhbGxiYWNrKXsgdGhpcy5jYWxsZXIub25MZWF2ZSA9IGNhbGxiYWNrIH1cblxuICBvblN5bmMoY2FsbGJhY2speyB0aGlzLmNhbGxlci5vblN5bmMgPSBjYWxsYmFjayB9XG5cbiAgbGlzdChieSl7IHJldHVybiBQcmVzZW5jZS5saXN0KHRoaXMuc3RhdGUsIGJ5KSB9XG5cbiAgaW5QZW5kaW5nU3luY1N0YXRlKCl7XG4gICAgcmV0dXJuICF0aGlzLmpvaW5SZWYgfHwgKHRoaXMuam9pblJlZiAhPT0gdGhpcy5jaGFubmVsLmpvaW5SZWYoKSlcbiAgfVxuXG4gIC8vIGxvd2VyLWxldmVsIHB1YmxpYyBzdGF0aWMgQVBJXG5cbiAgLyoqXG4gICAqIFVzZWQgdG8gc3luYyB0aGUgbGlzdCBvZiBwcmVzZW5jZXMgb24gdGhlIHNlcnZlclxuICAgKiB3aXRoIHRoZSBjbGllbnQncyBzdGF0ZS4gQW4gb3B0aW9uYWwgYG9uSm9pbmAgYW5kIGBvbkxlYXZlYCBjYWxsYmFjayBjYW5cbiAgICogYmUgcHJvdmlkZWQgdG8gcmVhY3QgdG8gY2hhbmdlcyBpbiB0aGUgY2xpZW50J3MgbG9jYWwgcHJlc2VuY2VzIGFjcm9zc1xuICAgKiBkaXNjb25uZWN0cyBhbmQgcmVjb25uZWN0cyB3aXRoIHRoZSBzZXJ2ZXIuXG4gICAqXG4gICAqIEByZXR1cm5zIHtQcmVzZW5jZX1cbiAgICovXG4gIHN0YXRpYyBzeW5jU3RhdGUoY3VycmVudFN0YXRlLCBuZXdTdGF0ZSwgb25Kb2luLCBvbkxlYXZlKXtcbiAgICBsZXQgc3RhdGUgPSB0aGlzLmNsb25lKGN1cnJlbnRTdGF0ZSlcbiAgICBsZXQgam9pbnMgPSB7fVxuICAgIGxldCBsZWF2ZXMgPSB7fVxuXG4gICAgdGhpcy5tYXAoc3RhdGUsIChrZXksIHByZXNlbmNlKSA9PiB7XG4gICAgICBpZighbmV3U3RhdGVba2V5XSl7XG4gICAgICAgIGxlYXZlc1trZXldID0gcHJlc2VuY2VcbiAgICAgIH1cbiAgICB9KVxuICAgIHRoaXMubWFwKG5ld1N0YXRlLCAoa2V5LCBuZXdQcmVzZW5jZSkgPT4ge1xuICAgICAgbGV0IGN1cnJlbnRQcmVzZW5jZSA9IHN0YXRlW2tleV1cbiAgICAgIGlmKGN1cnJlbnRQcmVzZW5jZSl7XG4gICAgICAgIGxldCBuZXdSZWZzID0gbmV3UHJlc2VuY2UubWV0YXMubWFwKG0gPT4gbS5waHhfcmVmKVxuICAgICAgICBsZXQgY3VyUmVmcyA9IGN1cnJlbnRQcmVzZW5jZS5tZXRhcy5tYXAobSA9PiBtLnBoeF9yZWYpXG4gICAgICAgIGxldCBqb2luZWRNZXRhcyA9IG5ld1ByZXNlbmNlLm1ldGFzLmZpbHRlcihtID0+IGN1clJlZnMuaW5kZXhPZihtLnBoeF9yZWYpIDwgMClcbiAgICAgICAgbGV0IGxlZnRNZXRhcyA9IGN1cnJlbnRQcmVzZW5jZS5tZXRhcy5maWx0ZXIobSA9PiBuZXdSZWZzLmluZGV4T2YobS5waHhfcmVmKSA8IDApXG4gICAgICAgIGlmKGpvaW5lZE1ldGFzLmxlbmd0aCA+IDApe1xuICAgICAgICAgIGpvaW5zW2tleV0gPSBuZXdQcmVzZW5jZVxuICAgICAgICAgIGpvaW5zW2tleV0ubWV0YXMgPSBqb2luZWRNZXRhc1xuICAgICAgICB9XG4gICAgICAgIGlmKGxlZnRNZXRhcy5sZW5ndGggPiAwKXtcbiAgICAgICAgICBsZWF2ZXNba2V5XSA9IHRoaXMuY2xvbmUoY3VycmVudFByZXNlbmNlKVxuICAgICAgICAgIGxlYXZlc1trZXldLm1ldGFzID0gbGVmdE1ldGFzXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGpvaW5zW2tleV0gPSBuZXdQcmVzZW5jZVxuICAgICAgfVxuICAgIH0pXG4gICAgcmV0dXJuIHRoaXMuc3luY0RpZmYoc3RhdGUsIHtqb2luczogam9pbnMsIGxlYXZlczogbGVhdmVzfSwgb25Kb2luLCBvbkxlYXZlKVxuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIFVzZWQgdG8gc3luYyBhIGRpZmYgb2YgcHJlc2VuY2Ugam9pbiBhbmQgbGVhdmVcbiAgICogZXZlbnRzIGZyb20gdGhlIHNlcnZlciwgYXMgdGhleSBoYXBwZW4uIExpa2UgYHN5bmNTdGF0ZWAsIGBzeW5jRGlmZmBcbiAgICogYWNjZXB0cyBvcHRpb25hbCBgb25Kb2luYCBhbmQgYG9uTGVhdmVgIGNhbGxiYWNrcyB0byByZWFjdCB0byBhIHVzZXJcbiAgICogam9pbmluZyBvciBsZWF2aW5nIGZyb20gYSBkZXZpY2UuXG4gICAqXG4gICAqIEByZXR1cm5zIHtQcmVzZW5jZX1cbiAgICovXG4gIHN0YXRpYyBzeW5jRGlmZihzdGF0ZSwgZGlmZiwgb25Kb2luLCBvbkxlYXZlKXtcbiAgICBsZXQge2pvaW5zLCBsZWF2ZXN9ID0gdGhpcy5jbG9uZShkaWZmKVxuICAgIGlmKCFvbkpvaW4peyBvbkpvaW4gPSBmdW5jdGlvbiAoKXsgfSB9XG4gICAgaWYoIW9uTGVhdmUpeyBvbkxlYXZlID0gZnVuY3Rpb24gKCl7IH0gfVxuXG4gICAgdGhpcy5tYXAoam9pbnMsIChrZXksIG5ld1ByZXNlbmNlKSA9PiB7XG4gICAgICBsZXQgY3VycmVudFByZXNlbmNlID0gc3RhdGVba2V5XVxuICAgICAgc3RhdGVba2V5XSA9IHRoaXMuY2xvbmUobmV3UHJlc2VuY2UpXG4gICAgICBpZihjdXJyZW50UHJlc2VuY2Upe1xuICAgICAgICBsZXQgam9pbmVkUmVmcyA9IHN0YXRlW2tleV0ubWV0YXMubWFwKG0gPT4gbS5waHhfcmVmKVxuICAgICAgICBsZXQgY3VyTWV0YXMgPSBjdXJyZW50UHJlc2VuY2UubWV0YXMuZmlsdGVyKG0gPT4gam9pbmVkUmVmcy5pbmRleE9mKG0ucGh4X3JlZikgPCAwKVxuICAgICAgICBzdGF0ZVtrZXldLm1ldGFzLnVuc2hpZnQoLi4uY3VyTWV0YXMpXG4gICAgICB9XG4gICAgICBvbkpvaW4oa2V5LCBjdXJyZW50UHJlc2VuY2UsIG5ld1ByZXNlbmNlKVxuICAgIH0pXG4gICAgdGhpcy5tYXAobGVhdmVzLCAoa2V5LCBsZWZ0UHJlc2VuY2UpID0+IHtcbiAgICAgIGxldCBjdXJyZW50UHJlc2VuY2UgPSBzdGF0ZVtrZXldXG4gICAgICBpZighY3VycmVudFByZXNlbmNlKXsgcmV0dXJuIH1cbiAgICAgIGxldCByZWZzVG9SZW1vdmUgPSBsZWZ0UHJlc2VuY2UubWV0YXMubWFwKG0gPT4gbS5waHhfcmVmKVxuICAgICAgY3VycmVudFByZXNlbmNlLm1ldGFzID0gY3VycmVudFByZXNlbmNlLm1ldGFzLmZpbHRlcihwID0+IHtcbiAgICAgICAgcmV0dXJuIHJlZnNUb1JlbW92ZS5pbmRleE9mKHAucGh4X3JlZikgPCAwXG4gICAgICB9KVxuICAgICAgb25MZWF2ZShrZXksIGN1cnJlbnRQcmVzZW5jZSwgbGVmdFByZXNlbmNlKVxuICAgICAgaWYoY3VycmVudFByZXNlbmNlLm1ldGFzLmxlbmd0aCA9PT0gMCl7XG4gICAgICAgIGRlbGV0ZSBzdGF0ZVtrZXldXG4gICAgICB9XG4gICAgfSlcbiAgICByZXR1cm4gc3RhdGVcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcmVzZW5jZXMsIHdpdGggc2VsZWN0ZWQgbWV0YWRhdGEuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwcmVzZW5jZXNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2hvb3NlclxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJlc2VuY2V9XG4gICAqL1xuICBzdGF0aWMgbGlzdChwcmVzZW5jZXMsIGNob29zZXIpe1xuICAgIGlmKCFjaG9vc2VyKXsgY2hvb3NlciA9IGZ1bmN0aW9uIChrZXksIHByZXMpeyByZXR1cm4gcHJlcyB9IH1cblxuICAgIHJldHVybiB0aGlzLm1hcChwcmVzZW5jZXMsIChrZXksIHByZXNlbmNlKSA9PiB7XG4gICAgICByZXR1cm4gY2hvb3NlcihrZXksIHByZXNlbmNlKVxuICAgIH0pXG4gIH1cblxuICAvLyBwcml2YXRlXG5cbiAgc3RhdGljIG1hcChvYmosIGZ1bmMpe1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopLm1hcChrZXkgPT4gZnVuYyhrZXksIG9ialtrZXldKSlcbiAgfVxuXG4gIHN0YXRpYyBjbG9uZShvYmopeyByZXR1cm4gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShvYmopKSB9XG59XG4iLCAiLyogVGhlIGRlZmF1bHQgc2VyaWFsaXplciBmb3IgZW5jb2RpbmcgYW5kIGRlY29kaW5nIG1lc3NhZ2VzICovXG5pbXBvcnQge1xuICBDSEFOTkVMX0VWRU5UU1xufSBmcm9tIFwiLi9jb25zdGFudHNcIlxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIEhFQURFUl9MRU5HVEg6IDEsXG4gIE1FVEFfTEVOR1RIOiA0LFxuICBLSU5EUzoge3B1c2g6IDAsIHJlcGx5OiAxLCBicm9hZGNhc3Q6IDJ9LFxuXG4gIGVuY29kZShtc2csIGNhbGxiYWNrKXtcbiAgICBpZihtc2cucGF5bG9hZC5jb25zdHJ1Y3RvciA9PT0gQXJyYXlCdWZmZXIpe1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKHRoaXMuYmluYXJ5RW5jb2RlKG1zZykpXG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBwYXlsb2FkID0gW21zZy5qb2luX3JlZiwgbXNnLnJlZiwgbXNnLnRvcGljLCBtc2cuZXZlbnQsIG1zZy5wYXlsb2FkXVxuICAgICAgcmV0dXJuIGNhbGxiYWNrKEpTT04uc3RyaW5naWZ5KHBheWxvYWQpKVxuICAgIH1cbiAgfSxcblxuICBkZWNvZGUocmF3UGF5bG9hZCwgY2FsbGJhY2spe1xuICAgIGlmKHJhd1BheWxvYWQuY29uc3RydWN0b3IgPT09IEFycmF5QnVmZmVyKXtcbiAgICAgIHJldHVybiBjYWxsYmFjayh0aGlzLmJpbmFyeURlY29kZShyYXdQYXlsb2FkKSlcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IFtqb2luX3JlZiwgcmVmLCB0b3BpYywgZXZlbnQsIHBheWxvYWRdID0gSlNPTi5wYXJzZShyYXdQYXlsb2FkKVxuICAgICAgcmV0dXJuIGNhbGxiYWNrKHtqb2luX3JlZiwgcmVmLCB0b3BpYywgZXZlbnQsIHBheWxvYWR9KVxuICAgIH1cbiAgfSxcblxuICAvLyBwcml2YXRlXG5cbiAgYmluYXJ5RW5jb2RlKG1lc3NhZ2Upe1xuICAgIGxldCB7am9pbl9yZWYsIHJlZiwgZXZlbnQsIHRvcGljLCBwYXlsb2FkfSA9IG1lc3NhZ2VcbiAgICBsZXQgbWV0YUxlbmd0aCA9IHRoaXMuTUVUQV9MRU5HVEggKyBqb2luX3JlZi5sZW5ndGggKyByZWYubGVuZ3RoICsgdG9waWMubGVuZ3RoICsgZXZlbnQubGVuZ3RoXG4gICAgbGV0IGhlYWRlciA9IG5ldyBBcnJheUJ1ZmZlcih0aGlzLkhFQURFUl9MRU5HVEggKyBtZXRhTGVuZ3RoKVxuICAgIGxldCB2aWV3ID0gbmV3IERhdGFWaWV3KGhlYWRlcilcbiAgICBsZXQgb2Zmc2V0ID0gMFxuXG4gICAgdmlldy5zZXRVaW50OChvZmZzZXQrKywgdGhpcy5LSU5EUy5wdXNoKSAvLyBraW5kXG4gICAgdmlldy5zZXRVaW50OChvZmZzZXQrKywgam9pbl9yZWYubGVuZ3RoKVxuICAgIHZpZXcuc2V0VWludDgob2Zmc2V0KyssIHJlZi5sZW5ndGgpXG4gICAgdmlldy5zZXRVaW50OChvZmZzZXQrKywgdG9waWMubGVuZ3RoKVxuICAgIHZpZXcuc2V0VWludDgob2Zmc2V0KyssIGV2ZW50Lmxlbmd0aClcbiAgICBBcnJheS5mcm9tKGpvaW5fcmVmLCBjaGFyID0+IHZpZXcuc2V0VWludDgob2Zmc2V0KyssIGNoYXIuY2hhckNvZGVBdCgwKSkpXG4gICAgQXJyYXkuZnJvbShyZWYsIGNoYXIgPT4gdmlldy5zZXRVaW50OChvZmZzZXQrKywgY2hhci5jaGFyQ29kZUF0KDApKSlcbiAgICBBcnJheS5mcm9tKHRvcGljLCBjaGFyID0+IHZpZXcuc2V0VWludDgob2Zmc2V0KyssIGNoYXIuY2hhckNvZGVBdCgwKSkpXG4gICAgQXJyYXkuZnJvbShldmVudCwgY2hhciA9PiB2aWV3LnNldFVpbnQ4KG9mZnNldCsrLCBjaGFyLmNoYXJDb2RlQXQoMCkpKVxuXG4gICAgdmFyIGNvbWJpbmVkID0gbmV3IFVpbnQ4QXJyYXkoaGVhZGVyLmJ5dGVMZW5ndGggKyBwYXlsb2FkLmJ5dGVMZW5ndGgpXG4gICAgY29tYmluZWQuc2V0KG5ldyBVaW50OEFycmF5KGhlYWRlciksIDApXG4gICAgY29tYmluZWQuc2V0KG5ldyBVaW50OEFycmF5KHBheWxvYWQpLCBoZWFkZXIuYnl0ZUxlbmd0aClcblxuICAgIHJldHVybiBjb21iaW5lZC5idWZmZXJcbiAgfSxcblxuICBiaW5hcnlEZWNvZGUoYnVmZmVyKXtcbiAgICBsZXQgdmlldyA9IG5ldyBEYXRhVmlldyhidWZmZXIpXG4gICAgbGV0IGtpbmQgPSB2aWV3LmdldFVpbnQ4KDApXG4gICAgbGV0IGRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoKVxuICAgIHN3aXRjaChraW5kKXtcbiAgICAgIGNhc2UgdGhpcy5LSU5EUy5wdXNoOiByZXR1cm4gdGhpcy5kZWNvZGVQdXNoKGJ1ZmZlciwgdmlldywgZGVjb2RlcilcbiAgICAgIGNhc2UgdGhpcy5LSU5EUy5yZXBseTogcmV0dXJuIHRoaXMuZGVjb2RlUmVwbHkoYnVmZmVyLCB2aWV3LCBkZWNvZGVyKVxuICAgICAgY2FzZSB0aGlzLktJTkRTLmJyb2FkY2FzdDogcmV0dXJuIHRoaXMuZGVjb2RlQnJvYWRjYXN0KGJ1ZmZlciwgdmlldywgZGVjb2RlcilcbiAgICB9XG4gIH0sXG5cbiAgZGVjb2RlUHVzaChidWZmZXIsIHZpZXcsIGRlY29kZXIpe1xuICAgIGxldCBqb2luUmVmU2l6ZSA9IHZpZXcuZ2V0VWludDgoMSlcbiAgICBsZXQgdG9waWNTaXplID0gdmlldy5nZXRVaW50OCgyKVxuICAgIGxldCBldmVudFNpemUgPSB2aWV3LmdldFVpbnQ4KDMpXG4gICAgbGV0IG9mZnNldCA9IHRoaXMuSEVBREVSX0xFTkdUSCArIHRoaXMuTUVUQV9MRU5HVEggLSAxIC8vIHB1c2hlcyBoYXZlIG5vIHJlZlxuICAgIGxldCBqb2luUmVmID0gZGVjb2Rlci5kZWNvZGUoYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgam9pblJlZlNpemUpKVxuICAgIG9mZnNldCA9IG9mZnNldCArIGpvaW5SZWZTaXplXG4gICAgbGV0IHRvcGljID0gZGVjb2Rlci5kZWNvZGUoYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgdG9waWNTaXplKSlcbiAgICBvZmZzZXQgPSBvZmZzZXQgKyB0b3BpY1NpemVcbiAgICBsZXQgZXZlbnQgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBldmVudFNpemUpKVxuICAgIG9mZnNldCA9IG9mZnNldCArIGV2ZW50U2l6ZVxuICAgIGxldCBkYXRhID0gYnVmZmVyLnNsaWNlKG9mZnNldCwgYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgcmV0dXJuIHtqb2luX3JlZjogam9pblJlZiwgcmVmOiBudWxsLCB0b3BpYzogdG9waWMsIGV2ZW50OiBldmVudCwgcGF5bG9hZDogZGF0YX1cbiAgfSxcblxuICBkZWNvZGVSZXBseShidWZmZXIsIHZpZXcsIGRlY29kZXIpe1xuICAgIGxldCBqb2luUmVmU2l6ZSA9IHZpZXcuZ2V0VWludDgoMSlcbiAgICBsZXQgcmVmU2l6ZSA9IHZpZXcuZ2V0VWludDgoMilcbiAgICBsZXQgdG9waWNTaXplID0gdmlldy5nZXRVaW50OCgzKVxuICAgIGxldCBldmVudFNpemUgPSB2aWV3LmdldFVpbnQ4KDQpXG4gICAgbGV0IG9mZnNldCA9IHRoaXMuSEVBREVSX0xFTkdUSCArIHRoaXMuTUVUQV9MRU5HVEhcbiAgICBsZXQgam9pblJlZiA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIGpvaW5SZWZTaXplKSlcbiAgICBvZmZzZXQgPSBvZmZzZXQgKyBqb2luUmVmU2l6ZVxuICAgIGxldCByZWYgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyByZWZTaXplKSlcbiAgICBvZmZzZXQgPSBvZmZzZXQgKyByZWZTaXplXG4gICAgbGV0IHRvcGljID0gZGVjb2Rlci5kZWNvZGUoYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgdG9waWNTaXplKSlcbiAgICBvZmZzZXQgPSBvZmZzZXQgKyB0b3BpY1NpemVcbiAgICBsZXQgZXZlbnQgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBldmVudFNpemUpKVxuICAgIG9mZnNldCA9IG9mZnNldCArIGV2ZW50U2l6ZVxuICAgIGxldCBkYXRhID0gYnVmZmVyLnNsaWNlKG9mZnNldCwgYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgbGV0IHBheWxvYWQgPSB7c3RhdHVzOiBldmVudCwgcmVzcG9uc2U6IGRhdGF9XG4gICAgcmV0dXJuIHtqb2luX3JlZjogam9pblJlZiwgcmVmOiByZWYsIHRvcGljOiB0b3BpYywgZXZlbnQ6IENIQU5ORUxfRVZFTlRTLnJlcGx5LCBwYXlsb2FkOiBwYXlsb2FkfVxuICB9LFxuXG4gIGRlY29kZUJyb2FkY2FzdChidWZmZXIsIHZpZXcsIGRlY29kZXIpe1xuICAgIGxldCB0b3BpY1NpemUgPSB2aWV3LmdldFVpbnQ4KDEpXG4gICAgbGV0IGV2ZW50U2l6ZSA9IHZpZXcuZ2V0VWludDgoMilcbiAgICBsZXQgb2Zmc2V0ID0gdGhpcy5IRUFERVJfTEVOR1RIICsgMlxuICAgIGxldCB0b3BpYyA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIHRvcGljU2l6ZSkpXG4gICAgb2Zmc2V0ID0gb2Zmc2V0ICsgdG9waWNTaXplXG4gICAgbGV0IGV2ZW50ID0gZGVjb2Rlci5kZWNvZGUoYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgZXZlbnRTaXplKSlcbiAgICBvZmZzZXQgPSBvZmZzZXQgKyBldmVudFNpemVcbiAgICBsZXQgZGF0YSA9IGJ1ZmZlci5zbGljZShvZmZzZXQsIGJ1ZmZlci5ieXRlTGVuZ3RoKVxuXG4gICAgcmV0dXJuIHtqb2luX3JlZjogbnVsbCwgcmVmOiBudWxsLCB0b3BpYzogdG9waWMsIGV2ZW50OiBldmVudCwgcGF5bG9hZDogZGF0YX1cbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIGdsb2JhbCxcbiAgcGh4V2luZG93LFxuICBDSEFOTkVMX0VWRU5UUyxcbiAgREVGQVVMVF9USU1FT1VULFxuICBERUZBVUxUX1ZTTixcbiAgU09DS0VUX1NUQVRFUyxcbiAgVFJBTlNQT1JUUyxcbiAgV1NfQ0xPU0VfTk9STUFMLFxuICBBVVRIX1RPS0VOX1BSRUZJWFxufSBmcm9tIFwiLi9jb25zdGFudHNcIlxuXG5pbXBvcnQge1xuICBjbG9zdXJlXG59IGZyb20gXCIuL3V0aWxzXCJcblxuaW1wb3J0IEFqYXggZnJvbSBcIi4vYWpheFwiXG5pbXBvcnQgQ2hhbm5lbCBmcm9tIFwiLi9jaGFubmVsXCJcbmltcG9ydCBMb25nUG9sbCBmcm9tIFwiLi9sb25ncG9sbFwiXG5pbXBvcnQgU2VyaWFsaXplciBmcm9tIFwiLi9zZXJpYWxpemVyXCJcbmltcG9ydCBUaW1lciBmcm9tIFwiLi90aW1lclwiXG5cbi8qKiBJbml0aWFsaXplcyB0aGUgU29ja2V0ICpcbiAqXG4gKiBGb3IgSUU4IHN1cHBvcnQgdXNlIGFuIEVTNS1zaGltIChodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW0pXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGVuZFBvaW50IC0gVGhlIHN0cmluZyBXZWJTb2NrZXQgZW5kcG9pbnQsIGllLCBgXCJ3czovL2V4YW1wbGUuY29tL3NvY2tldFwiYCxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgXCJ3c3M6Ly9leGFtcGxlLmNvbVwiYFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBcIi9zb2NrZXRcImAgKGluaGVyaXRlZCBob3N0ICYgcHJvdG9jb2wpXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdHNdIC0gT3B0aW9uYWwgY29uZmlndXJhdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdHMudHJhbnNwb3J0XSAtIFRoZSBXZWJzb2NrZXQgVHJhbnNwb3J0LCBmb3IgZXhhbXBsZSBXZWJTb2NrZXQgb3IgUGhvZW5peC5Mb25nUG9sbC5cbiAqXG4gKiBEZWZhdWx0cyB0byBXZWJTb2NrZXQgd2l0aCBhdXRvbWF0aWMgTG9uZ1BvbGwgZmFsbGJhY2sgaWYgV2ViU29ja2V0IGlzIG5vdCBkZWZpbmVkLlxuICogVG8gZmFsbGJhY2sgdG8gTG9uZ1BvbGwgd2hlbiBXZWJTb2NrZXQgYXR0ZW1wdHMgZmFpbCwgdXNlIGBsb25nUG9sbEZhbGxiYWNrTXM6IDI1MDBgLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy5sb25nUG9sbEZhbGxiYWNrTXNdIC0gVGhlIG1pbGxpc2Vjb25kIHRpbWUgdG8gYXR0ZW1wdCB0aGUgcHJpbWFyeSB0cmFuc3BvcnRcbiAqIGJlZm9yZSBmYWxsaW5nIGJhY2sgdG8gdGhlIExvbmdQb2xsIHRyYW5zcG9ydC4gRGlzYWJsZWQgYnkgZGVmYXVsdC5cbiAqXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLmRlYnVnXSAtIFdoZW4gdHJ1ZSwgZW5hYmxlcyBkZWJ1ZyBsb2dnaW5nLiBEZWZhdWx0IGZhbHNlLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRzLmVuY29kZV0gLSBUaGUgZnVuY3Rpb24gdG8gZW5jb2RlIG91dGdvaW5nIG1lc3NhZ2VzLlxuICpcbiAqIERlZmF1bHRzIHRvIEpTT04gZW5jb2Rlci5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0cy5kZWNvZGVdIC0gVGhlIGZ1bmN0aW9uIHRvIGRlY29kZSBpbmNvbWluZyBtZXNzYWdlcy5cbiAqXG4gKiBEZWZhdWx0cyB0byBKU09OOlxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIChwYXlsb2FkLCBjYWxsYmFjaykgPT4gY2FsbGJhY2soSlNPTi5wYXJzZShwYXlsb2FkKSlcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy50aW1lb3V0XSAtIFRoZSBkZWZhdWx0IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIHRvIHRyaWdnZXIgcHVzaCB0aW1lb3V0cy5cbiAqXG4gKiBEZWZhdWx0cyBgREVGQVVMVF9USU1FT1VUYFxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmhlYXJ0YmVhdEludGVydmFsTXNdIC0gVGhlIG1pbGxpc2VjIGludGVydmFsIHRvIHNlbmQgYSBoZWFydGJlYXQgbWVzc2FnZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdHMucmVjb25uZWN0QWZ0ZXJNc10gLSBUaGUgb3B0aW9uYWwgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZVxuICogc29ja2V0IHJlY29ubmVjdCBpbnRlcnZhbCwgaW4gbWlsbGlzZWNvbmRzLlxuICpcbiAqIERlZmF1bHRzIHRvIHN0ZXBwZWQgYmFja29mZiBvZjpcbiAqXG4gKiBgYGBqYXZhc2NyaXB0XG4gKiBmdW5jdGlvbih0cmllcyl7XG4gKiAgIHJldHVybiBbMTAsIDUwLCAxMDAsIDE1MCwgMjAwLCAyNTAsIDUwMCwgMTAwMCwgMjAwMF1bdHJpZXMgLSAxXSB8fCA1MDAwXG4gKiB9XG4gKiBgYGBgXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdHMucmVqb2luQWZ0ZXJNc10gLSBUaGUgb3B0aW9uYWwgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSBtaWxsaXNlY1xuICogcmVqb2luIGludGVydmFsIGZvciBpbmRpdmlkdWFsIGNoYW5uZWxzLlxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIGZ1bmN0aW9uKHRyaWVzKXtcbiAqICAgcmV0dXJuIFsxMDAwLCAyMDAwLCA1MDAwXVt0cmllcyAtIDFdIHx8IDEwMDAwXG4gKiB9XG4gKiBgYGBgXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdHMubG9nZ2VyXSAtIFRoZSBvcHRpb25hbCBmdW5jdGlvbiBmb3Igc3BlY2lhbGl6ZWQgbG9nZ2luZywgaWU6XG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogZnVuY3Rpb24oa2luZCwgbXNnLCBkYXRhKSB7XG4gKiAgIGNvbnNvbGUubG9nKGAke2tpbmR9OiAke21zZ31gLCBkYXRhKVxuICogfVxuICogYGBgXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmxvbmdwb2xsZXJUaW1lb3V0XSAtIFRoZSBtYXhpbXVtIHRpbWVvdXQgb2YgYSBsb25nIHBvbGwgQUpBWCByZXF1ZXN0LlxuICpcbiAqIERlZmF1bHRzIHRvIDIwcyAoZG91YmxlIHRoZSBzZXJ2ZXIgbG9uZyBwb2xsIHRpbWVyKS5cbiAqXG4gKiBAcGFyYW0geyhPYmplY3R8ZnVuY3Rpb24pfSBbb3B0cy5wYXJhbXNdIC0gVGhlIG9wdGlvbmFsIHBhcmFtcyB0byBwYXNzIHdoZW4gY29ubmVjdGluZ1xuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmF1dGhUb2tlbl0gLSB0aGUgb3B0aW9uYWwgYXV0aGVudGljYXRpb24gdG9rZW4gdG8gYmUgZXhwb3NlZCBvbiB0aGUgc2VydmVyXG4gKiB1bmRlciB0aGUgYDphdXRoX3Rva2VuYCBjb25uZWN0X2luZm8ga2V5LlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmJpbmFyeVR5cGVdIC0gVGhlIGJpbmFyeSB0eXBlIHRvIHVzZSBmb3IgYmluYXJ5IFdlYlNvY2tldCBmcmFtZXMuXG4gKlxuICogRGVmYXVsdHMgdG8gXCJhcnJheWJ1ZmZlclwiXG4gKlxuICogQHBhcmFtIHt2c259IFtvcHRzLnZzbl0gLSBUaGUgc2VyaWFsaXplcidzIHByb3RvY29sIHZlcnNpb24gdG8gc2VuZCBvbiBjb25uZWN0LlxuICpcbiAqIERlZmF1bHRzIHRvIERFRkFVTFRfVlNOLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0cy5zZXNzaW9uU3RvcmFnZV0gLSBBbiBvcHRpb25hbCBTdG9yYWdlIGNvbXBhdGlibGUgb2JqZWN0XG4gKiBQaG9lbml4IHVzZXMgc2Vzc2lvblN0b3JhZ2UgZm9yIGxvbmdwb2xsIGZhbGxiYWNrIGhpc3RvcnkuIE92ZXJyaWRpbmcgdGhlIHN0b3JlIGlzXG4gKiB1c2VmdWwgd2hlbiBQaG9lbml4IHdvbid0IGhhdmUgYWNjZXNzIHRvIGBzZXNzaW9uU3RvcmFnZWAuIEZvciBleGFtcGxlLCBUaGlzIGNvdWxkXG4gKiBoYXBwZW4gaWYgYSBzaXRlIGxvYWRzIGEgY3Jvc3MtZG9tYWluIGNoYW5uZWwgaW4gYW4gaWZyYW1lLiBFeGFtcGxlIHVzYWdlOlxuICpcbiAqICAgICBjbGFzcyBJbk1lbW9yeVN0b3JhZ2Uge1xuICogICAgICAgY29uc3RydWN0b3IoKSB7IHRoaXMuc3RvcmFnZSA9IHt9IH1cbiAqICAgICAgIGdldEl0ZW0oa2V5TmFtZSkgeyByZXR1cm4gdGhpcy5zdG9yYWdlW2tleU5hbWVdIHx8IG51bGwgfVxuICogICAgICAgcmVtb3ZlSXRlbShrZXlOYW1lKSB7IGRlbGV0ZSB0aGlzLnN0b3JhZ2Vba2V5TmFtZV0gfVxuICogICAgICAgc2V0SXRlbShrZXlOYW1lLCBrZXlWYWx1ZSkgeyB0aGlzLnN0b3JhZ2Vba2V5TmFtZV0gPSBrZXlWYWx1ZSB9XG4gKiAgICAgfVxuICpcbiovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTb2NrZXQge1xuICBjb25zdHJ1Y3RvcihlbmRQb2ludCwgb3B0cyA9IHt9KXtcbiAgICB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzID0ge29wZW46IFtdLCBjbG9zZTogW10sIGVycm9yOiBbXSwgbWVzc2FnZTogW119XG4gICAgdGhpcy5jaGFubmVscyA9IFtdXG4gICAgdGhpcy5zZW5kQnVmZmVyID0gW11cbiAgICB0aGlzLnJlZiA9IDBcbiAgICB0aGlzLnRpbWVvdXQgPSBvcHRzLnRpbWVvdXQgfHwgREVGQVVMVF9USU1FT1VUXG4gICAgdGhpcy50cmFuc3BvcnQgPSBvcHRzLnRyYW5zcG9ydCB8fCBnbG9iYWwuV2ViU29ja2V0IHx8IExvbmdQb2xsXG4gICAgdGhpcy5wcmltYXJ5UGFzc2VkSGVhbHRoQ2hlY2sgPSBmYWxzZVxuICAgIHRoaXMubG9uZ1BvbGxGYWxsYmFja01zID0gb3B0cy5sb25nUG9sbEZhbGxiYWNrTXNcbiAgICB0aGlzLmZhbGxiYWNrVGltZXIgPSBudWxsXG4gICAgdGhpcy5zZXNzaW9uU3RvcmUgPSBvcHRzLnNlc3Npb25TdG9yYWdlIHx8IChnbG9iYWwgJiYgZ2xvYmFsLnNlc3Npb25TdG9yYWdlKVxuICAgIHRoaXMuZXN0YWJsaXNoZWRDb25uZWN0aW9ucyA9IDBcbiAgICB0aGlzLmRlZmF1bHRFbmNvZGVyID0gU2VyaWFsaXplci5lbmNvZGUuYmluZChTZXJpYWxpemVyKVxuICAgIHRoaXMuZGVmYXVsdERlY29kZXIgPSBTZXJpYWxpemVyLmRlY29kZS5iaW5kKFNlcmlhbGl6ZXIpXG4gICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gZmFsc2VcbiAgICB0aGlzLmRpc2Nvbm5lY3RpbmcgPSBmYWxzZVxuICAgIHRoaXMuYmluYXJ5VHlwZSA9IG9wdHMuYmluYXJ5VHlwZSB8fCBcImFycmF5YnVmZmVyXCJcbiAgICB0aGlzLmNvbm5lY3RDbG9jayA9IDFcbiAgICBpZih0aGlzLnRyYW5zcG9ydCAhPT0gTG9uZ1BvbGwpe1xuICAgICAgdGhpcy5lbmNvZGUgPSBvcHRzLmVuY29kZSB8fCB0aGlzLmRlZmF1bHRFbmNvZGVyXG4gICAgICB0aGlzLmRlY29kZSA9IG9wdHMuZGVjb2RlIHx8IHRoaXMuZGVmYXVsdERlY29kZXJcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5lbmNvZGUgPSB0aGlzLmRlZmF1bHRFbmNvZGVyXG4gICAgICB0aGlzLmRlY29kZSA9IHRoaXMuZGVmYXVsdERlY29kZXJcbiAgICB9XG4gICAgbGV0IGF3YWl0aW5nQ29ubmVjdGlvbk9uUGFnZVNob3cgPSBudWxsXG4gICAgaWYocGh4V2luZG93ICYmIHBoeFdpbmRvdy5hZGRFdmVudExpc3RlbmVyKXtcbiAgICAgIHBoeFdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicGFnZWhpZGVcIiwgX2UgPT4ge1xuICAgICAgICBpZih0aGlzLmNvbm4pe1xuICAgICAgICAgIHRoaXMuZGlzY29ubmVjdCgpXG4gICAgICAgICAgYXdhaXRpbmdDb25uZWN0aW9uT25QYWdlU2hvdyA9IHRoaXMuY29ubmVjdENsb2NrXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICBwaHhXaW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInBhZ2VzaG93XCIsIF9lID0+IHtcbiAgICAgICAgaWYoYXdhaXRpbmdDb25uZWN0aW9uT25QYWdlU2hvdyA9PT0gdGhpcy5jb25uZWN0Q2xvY2spe1xuICAgICAgICAgIGF3YWl0aW5nQ29ubmVjdGlvbk9uUGFnZVNob3cgPSBudWxsXG4gICAgICAgICAgdGhpcy5jb25uZWN0KClcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9XG4gICAgdGhpcy5oZWFydGJlYXRJbnRlcnZhbE1zID0gb3B0cy5oZWFydGJlYXRJbnRlcnZhbE1zIHx8IDMwMDAwXG4gICAgdGhpcy5yZWpvaW5BZnRlck1zID0gKHRyaWVzKSA9PiB7XG4gICAgICBpZihvcHRzLnJlam9pbkFmdGVyTXMpe1xuICAgICAgICByZXR1cm4gb3B0cy5yZWpvaW5BZnRlck1zKHRyaWVzKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFsxMDAwLCAyMDAwLCA1MDAwXVt0cmllcyAtIDFdIHx8IDEwMDAwXG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMucmVjb25uZWN0QWZ0ZXJNcyA9ICh0cmllcykgPT4ge1xuICAgICAgaWYob3B0cy5yZWNvbm5lY3RBZnRlck1zKXtcbiAgICAgICAgcmV0dXJuIG9wdHMucmVjb25uZWN0QWZ0ZXJNcyh0cmllcylcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBbMTAsIDUwLCAxMDAsIDE1MCwgMjAwLCAyNTAsIDUwMCwgMTAwMCwgMjAwMF1bdHJpZXMgLSAxXSB8fCA1MDAwXG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMubG9nZ2VyID0gb3B0cy5sb2dnZXIgfHwgbnVsbFxuICAgIGlmKCF0aGlzLmxvZ2dlciAmJiBvcHRzLmRlYnVnKXtcbiAgICAgIHRoaXMubG9nZ2VyID0gKGtpbmQsIG1zZywgZGF0YSkgPT4geyBjb25zb2xlLmxvZyhgJHtraW5kfTogJHttc2d9YCwgZGF0YSkgfVxuICAgIH1cbiAgICB0aGlzLmxvbmdwb2xsZXJUaW1lb3V0ID0gb3B0cy5sb25ncG9sbGVyVGltZW91dCB8fCAyMDAwMFxuICAgIHRoaXMucGFyYW1zID0gY2xvc3VyZShvcHRzLnBhcmFtcyB8fCB7fSlcbiAgICB0aGlzLmVuZFBvaW50ID0gYCR7ZW5kUG9pbnR9LyR7VFJBTlNQT1JUUy53ZWJzb2NrZXR9YFxuICAgIHRoaXMudnNuID0gb3B0cy52c24gfHwgREVGQVVMVF9WU05cbiAgICB0aGlzLmhlYXJ0YmVhdFRpbWVvdXRUaW1lciA9IG51bGxcbiAgICB0aGlzLmhlYXJ0YmVhdFRpbWVyID0gbnVsbFxuICAgIHRoaXMucGVuZGluZ0hlYXJ0YmVhdFJlZiA9IG51bGxcbiAgICB0aGlzLnJlY29ubmVjdFRpbWVyID0gbmV3IFRpbWVyKCgpID0+IHtcbiAgICAgIHRoaXMudGVhcmRvd24oKCkgPT4gdGhpcy5jb25uZWN0KCkpXG4gICAgfSwgdGhpcy5yZWNvbm5lY3RBZnRlck1zKVxuICAgIHRoaXMuYXV0aFRva2VuID0gb3B0cy5hdXRoVG9rZW5cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBMb25nUG9sbCB0cmFuc3BvcnQgcmVmZXJlbmNlXG4gICAqL1xuICBnZXRMb25nUG9sbFRyYW5zcG9ydCgpeyByZXR1cm4gTG9uZ1BvbGwgfVxuXG4gIC8qKlxuICAgKiBEaXNjb25uZWN0cyBhbmQgcmVwbGFjZXMgdGhlIGFjdGl2ZSB0cmFuc3BvcnRcbiAgICpcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gbmV3VHJhbnNwb3J0IC0gVGhlIG5ldyB0cmFuc3BvcnQgY2xhc3MgdG8gaW5zdGFudGlhdGVcbiAgICpcbiAgICovXG4gIHJlcGxhY2VUcmFuc3BvcnQobmV3VHJhbnNwb3J0KXtcbiAgICB0aGlzLmNvbm5lY3RDbG9jaysrXG4gICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gdHJ1ZVxuICAgIGNsZWFyVGltZW91dCh0aGlzLmZhbGxiYWNrVGltZXIpXG4gICAgdGhpcy5yZWNvbm5lY3RUaW1lci5yZXNldCgpXG4gICAgaWYodGhpcy5jb25uKXtcbiAgICAgIHRoaXMuY29ubi5jbG9zZSgpXG4gICAgICB0aGlzLmNvbm4gPSBudWxsXG4gICAgfVxuICAgIHRoaXMudHJhbnNwb3J0ID0gbmV3VHJhbnNwb3J0XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgc29ja2V0IHByb3RvY29sXG4gICAqXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAqL1xuICBwcm90b2NvbCgpeyByZXR1cm4gbG9jYXRpb24ucHJvdG9jb2wubWF0Y2goL15odHRwcy8pID8gXCJ3c3NcIiA6IFwid3NcIiB9XG5cbiAgLyoqXG4gICAqIFRoZSBmdWxseSBxdWFsaWZpZWQgc29ja2V0IHVybFxuICAgKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgKi9cbiAgZW5kUG9pbnRVUkwoKXtcbiAgICBsZXQgdXJpID0gQWpheC5hcHBlbmRQYXJhbXMoXG4gICAgICBBamF4LmFwcGVuZFBhcmFtcyh0aGlzLmVuZFBvaW50LCB0aGlzLnBhcmFtcygpKSwge3ZzbjogdGhpcy52c259KVxuICAgIGlmKHVyaS5jaGFyQXQoMCkgIT09IFwiL1wiKXsgcmV0dXJuIHVyaSB9XG4gICAgaWYodXJpLmNoYXJBdCgxKSA9PT0gXCIvXCIpeyByZXR1cm4gYCR7dGhpcy5wcm90b2NvbCgpfToke3VyaX1gIH1cblxuICAgIHJldHVybiBgJHt0aGlzLnByb3RvY29sKCl9Oi8vJHtsb2NhdGlvbi5ob3N0fSR7dXJpfWBcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNjb25uZWN0cyB0aGUgc29ja2V0XG4gICAqXG4gICAqIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvQ2xvc2VFdmVudCNTdGF0dXNfY29kZXMgZm9yIHZhbGlkIHN0YXR1cyBjb2Rlcy5cbiAgICpcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgLSBPcHRpb25hbCBjYWxsYmFjayB3aGljaCBpcyBjYWxsZWQgYWZ0ZXIgc29ja2V0IGlzIGRpc2Nvbm5lY3RlZC5cbiAgICogQHBhcmFtIHtpbnRlZ2VyfSBjb2RlIC0gQSBzdGF0dXMgY29kZSBmb3IgZGlzY29ubmVjdGlvbiAoT3B0aW9uYWwpLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmVhc29uIC0gQSB0ZXh0dWFsIGRlc2NyaXB0aW9uIG9mIHRoZSByZWFzb24gdG8gZGlzY29ubmVjdC4gKE9wdGlvbmFsKVxuICAgKi9cbiAgZGlzY29ubmVjdChjYWxsYmFjaywgY29kZSwgcmVhc29uKXtcbiAgICB0aGlzLmNvbm5lY3RDbG9jaysrXG4gICAgdGhpcy5kaXNjb25uZWN0aW5nID0gdHJ1ZVxuICAgIHRoaXMuY2xvc2VXYXNDbGVhbiA9IHRydWVcbiAgICBjbGVhclRpbWVvdXQodGhpcy5mYWxsYmFja1RpbWVyKVxuICAgIHRoaXMucmVjb25uZWN0VGltZXIucmVzZXQoKVxuICAgIHRoaXMudGVhcmRvd24oKCkgPT4ge1xuICAgICAgdGhpcy5kaXNjb25uZWN0aW5nID0gZmFsc2VcbiAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKClcbiAgICB9LCBjb2RlLCByZWFzb24pXG4gIH1cblxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbXMgdG8gc2VuZCB3aGVuIGNvbm5lY3RpbmcsIGZvciBleGFtcGxlIGB7dXNlcl9pZDogdXNlclRva2VufWBcbiAgICpcbiAgICogUGFzc2luZyBwYXJhbXMgdG8gY29ubmVjdCBpcyBkZXByZWNhdGVkOyBwYXNzIHRoZW0gaW4gdGhlIFNvY2tldCBjb25zdHJ1Y3RvciBpbnN0ZWFkOlxuICAgKiBgbmV3IFNvY2tldChcIi9zb2NrZXRcIiwge3BhcmFtczoge3VzZXJfaWQ6IHVzZXJUb2tlbn19KWAuXG4gICAqL1xuICBjb25uZWN0KHBhcmFtcyl7XG4gICAgaWYocGFyYW1zKXtcbiAgICAgIGNvbnNvbGUgJiYgY29uc29sZS5sb2coXCJwYXNzaW5nIHBhcmFtcyB0byBjb25uZWN0IGlzIGRlcHJlY2F0ZWQuIEluc3RlYWQgcGFzcyA6cGFyYW1zIHRvIHRoZSBTb2NrZXQgY29uc3RydWN0b3JcIilcbiAgICAgIHRoaXMucGFyYW1zID0gY2xvc3VyZShwYXJhbXMpXG4gICAgfVxuICAgIGlmKHRoaXMuY29ubiAmJiAhdGhpcy5kaXNjb25uZWN0aW5nKXsgcmV0dXJuIH1cbiAgICBpZih0aGlzLmxvbmdQb2xsRmFsbGJhY2tNcyAmJiB0aGlzLnRyYW5zcG9ydCAhPT0gTG9uZ1BvbGwpe1xuICAgICAgdGhpcy5jb25uZWN0V2l0aEZhbGxiYWNrKExvbmdQb2xsLCB0aGlzLmxvbmdQb2xsRmFsbGJhY2tNcylcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50cmFuc3BvcnRDb25uZWN0KClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTG9ncyB0aGUgbWVzc2FnZS4gT3ZlcnJpZGUgYHRoaXMubG9nZ2VyYCBmb3Igc3BlY2lhbGl6ZWQgbG9nZ2luZy4gbm9vcHMgYnkgZGVmYXVsdFxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2luZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gbXNnXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhXG4gICAqL1xuICBsb2coa2luZCwgbXNnLCBkYXRhKXsgdGhpcy5sb2dnZXIgJiYgdGhpcy5sb2dnZXIoa2luZCwgbXNnLCBkYXRhKSB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiBhIGxvZ2dlciBoYXMgYmVlbiBzZXQgb24gdGhpcyBzb2NrZXQuXG4gICAqL1xuICBoYXNMb2dnZXIoKXsgcmV0dXJuIHRoaXMubG9nZ2VyICE9PSBudWxsIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGNhbGxiYWNrcyBmb3IgY29ubmVjdGlvbiBvcGVuIGV2ZW50c1xuICAgKlxuICAgKiBAZXhhbXBsZSBzb2NrZXQub25PcGVuKGZ1bmN0aW9uKCl7IGNvbnNvbGUuaW5mbyhcInRoZSBzb2NrZXQgd2FzIG9wZW5lZFwiKSB9KVxuICAgKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgb25PcGVuKGNhbGxiYWNrKXtcbiAgICBsZXQgcmVmID0gdGhpcy5tYWtlUmVmKClcbiAgICB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzLm9wZW4ucHVzaChbcmVmLCBjYWxsYmFja10pXG4gICAgcmV0dXJuIHJlZlxuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyBjYWxsYmFja3MgZm9yIGNvbm5lY3Rpb24gY2xvc2UgZXZlbnRzXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBvbkNsb3NlKGNhbGxiYWNrKXtcbiAgICBsZXQgcmVmID0gdGhpcy5tYWtlUmVmKClcbiAgICB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzLmNsb3NlLnB1c2goW3JlZiwgY2FsbGJhY2tdKVxuICAgIHJldHVybiByZWZcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgY2FsbGJhY2tzIGZvciBjb25uZWN0aW9uIGVycm9yIGV2ZW50c1xuICAgKlxuICAgKiBAZXhhbXBsZSBzb2NrZXQub25FcnJvcihmdW5jdGlvbihlcnJvcil7IGFsZXJ0KFwiQW4gZXJyb3Igb2NjdXJyZWRcIikgfSlcbiAgICpcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIG9uRXJyb3IoY2FsbGJhY2spe1xuICAgIGxldCByZWYgPSB0aGlzLm1ha2VSZWYoKVxuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3MuZXJyb3IucHVzaChbcmVmLCBjYWxsYmFja10pXG4gICAgcmV0dXJuIHJlZlxuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyBjYWxsYmFja3MgZm9yIGNvbm5lY3Rpb24gbWVzc2FnZSBldmVudHNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIG9uTWVzc2FnZShjYWxsYmFjayl7XG4gICAgbGV0IHJlZiA9IHRoaXMubWFrZVJlZigpXG4gICAgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcy5tZXNzYWdlLnB1c2goW3JlZiwgY2FsbGJhY2tdKVxuICAgIHJldHVybiByZWZcbiAgfVxuXG4gIC8qKlxuICAgKiBQaW5ncyB0aGUgc2VydmVyIGFuZCBpbnZva2VzIHRoZSBjYWxsYmFjayB3aXRoIHRoZSBSVFQgaW4gbWlsbGlzZWNvbmRzXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgcGluZyB3YXMgcHVzaGVkIG9yIGZhbHNlIGlmIHVuYWJsZSB0byBiZSBwdXNoZWQuXG4gICAqL1xuICBwaW5nKGNhbGxiYWNrKXtcbiAgICBpZighdGhpcy5pc0Nvbm5lY3RlZCgpKXsgcmV0dXJuIGZhbHNlIH1cbiAgICBsZXQgcmVmID0gdGhpcy5tYWtlUmVmKClcbiAgICBsZXQgc3RhcnRUaW1lID0gRGF0ZS5ub3coKVxuICAgIHRoaXMucHVzaCh7dG9waWM6IFwicGhvZW5peFwiLCBldmVudDogXCJoZWFydGJlYXRcIiwgcGF5bG9hZDoge30sIHJlZjogcmVmfSlcbiAgICBsZXQgb25Nc2dSZWYgPSB0aGlzLm9uTWVzc2FnZShtc2cgPT4ge1xuICAgICAgaWYobXNnLnJlZiA9PT0gcmVmKXtcbiAgICAgICAgdGhpcy5vZmYoW29uTXNnUmVmXSlcbiAgICAgICAgY2FsbGJhY2soRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSlcbiAgICAgIH1cbiAgICB9KVxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cbiAgdHJhbnNwb3J0Q29ubmVjdCgpe1xuICAgIHRoaXMuY29ubmVjdENsb2NrKytcbiAgICB0aGlzLmNsb3NlV2FzQ2xlYW4gPSBmYWxzZVxuICAgIGxldCBwcm90b2NvbHMgPSB1bmRlZmluZWRcbiAgICAvLyBTZWMtV2ViU29ja2V0LVByb3RvY29sIGJhc2VkIHRva2VuXG4gICAgLy8gKGxvbmdwb2xsIHVzZXMgQXV0aG9yaXphdGlvbiBoZWFkZXIgaW5zdGVhZClcbiAgICBpZih0aGlzLmF1dGhUb2tlbil7XG4gICAgICBwcm90b2NvbHMgPSBbXCJwaG9lbml4XCIsIGAke0FVVEhfVE9LRU5fUFJFRklYfSR7YnRvYSh0aGlzLmF1dGhUb2tlbikucmVwbGFjZSgvPS9nLCBcIlwiKX1gXVxuICAgIH1cbiAgICB0aGlzLmNvbm4gPSBuZXcgdGhpcy50cmFuc3BvcnQodGhpcy5lbmRQb2ludFVSTCgpLCBwcm90b2NvbHMpXG4gICAgdGhpcy5jb25uLmJpbmFyeVR5cGUgPSB0aGlzLmJpbmFyeVR5cGVcbiAgICB0aGlzLmNvbm4udGltZW91dCA9IHRoaXMubG9uZ3BvbGxlclRpbWVvdXRcbiAgICB0aGlzLmNvbm4ub25vcGVuID0gKCkgPT4gdGhpcy5vbkNvbm5PcGVuKClcbiAgICB0aGlzLmNvbm4ub25lcnJvciA9IGVycm9yID0+IHRoaXMub25Db25uRXJyb3IoZXJyb3IpXG4gICAgdGhpcy5jb25uLm9ubWVzc2FnZSA9IGV2ZW50ID0+IHRoaXMub25Db25uTWVzc2FnZShldmVudClcbiAgICB0aGlzLmNvbm4ub25jbG9zZSA9IGV2ZW50ID0+IHRoaXMub25Db25uQ2xvc2UoZXZlbnQpXG4gIH1cblxuICBnZXRTZXNzaW9uKGtleSl7IHJldHVybiB0aGlzLnNlc3Npb25TdG9yZSAmJiB0aGlzLnNlc3Npb25TdG9yZS5nZXRJdGVtKGtleSkgfVxuXG4gIHN0b3JlU2Vzc2lvbihrZXksIHZhbCl7IHRoaXMuc2Vzc2lvblN0b3JlICYmIHRoaXMuc2Vzc2lvblN0b3JlLnNldEl0ZW0oa2V5LCB2YWwpIH1cblxuICBjb25uZWN0V2l0aEZhbGxiYWNrKGZhbGxiYWNrVHJhbnNwb3J0LCBmYWxsYmFja1RocmVzaG9sZCA9IDI1MDApe1xuICAgIGNsZWFyVGltZW91dCh0aGlzLmZhbGxiYWNrVGltZXIpXG4gICAgbGV0IGVzdGFibGlzaGVkID0gZmFsc2VcbiAgICBsZXQgcHJpbWFyeVRyYW5zcG9ydCA9IHRydWVcbiAgICBsZXQgb3BlblJlZiwgZXJyb3JSZWZcbiAgICBsZXQgZmFsbGJhY2sgPSAocmVhc29uKSA9PiB7XG4gICAgICB0aGlzLmxvZyhcInRyYW5zcG9ydFwiLCBgZmFsbGluZyBiYWNrIHRvICR7ZmFsbGJhY2tUcmFuc3BvcnQubmFtZX0uLi5gLCByZWFzb24pXG4gICAgICB0aGlzLm9mZihbb3BlblJlZiwgZXJyb3JSZWZdKVxuICAgICAgcHJpbWFyeVRyYW5zcG9ydCA9IGZhbHNlXG4gICAgICB0aGlzLnJlcGxhY2VUcmFuc3BvcnQoZmFsbGJhY2tUcmFuc3BvcnQpXG4gICAgICB0aGlzLnRyYW5zcG9ydENvbm5lY3QoKVxuICAgIH1cbiAgICBpZih0aGlzLmdldFNlc3Npb24oYHBoeDpmYWxsYmFjazoke2ZhbGxiYWNrVHJhbnNwb3J0Lm5hbWV9YCkpeyByZXR1cm4gZmFsbGJhY2soXCJtZW1vcml6ZWRcIikgfVxuXG4gICAgdGhpcy5mYWxsYmFja1RpbWVyID0gc2V0VGltZW91dChmYWxsYmFjaywgZmFsbGJhY2tUaHJlc2hvbGQpXG5cbiAgICBlcnJvclJlZiA9IHRoaXMub25FcnJvcihyZWFzb24gPT4ge1xuICAgICAgdGhpcy5sb2coXCJ0cmFuc3BvcnRcIiwgXCJlcnJvclwiLCByZWFzb24pXG4gICAgICBpZihwcmltYXJ5VHJhbnNwb3J0ICYmICFlc3RhYmxpc2hlZCl7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLmZhbGxiYWNrVGltZXIpXG4gICAgICAgIGZhbGxiYWNrKHJlYXNvbilcbiAgICAgIH1cbiAgICB9KVxuICAgIHRoaXMub25PcGVuKCgpID0+IHtcbiAgICAgIGVzdGFibGlzaGVkID0gdHJ1ZVxuICAgICAgaWYoIXByaW1hcnlUcmFuc3BvcnQpe1xuICAgICAgICAvLyBvbmx5IG1lbW9yaXplIExQIGlmIHdlIG5ldmVyIGNvbm5lY3RlZCB0byBwcmltYXJ5XG4gICAgICAgIGlmKCF0aGlzLnByaW1hcnlQYXNzZWRIZWFsdGhDaGVjayl7IHRoaXMuc3RvcmVTZXNzaW9uKGBwaHg6ZmFsbGJhY2s6JHtmYWxsYmFja1RyYW5zcG9ydC5uYW1lfWAsIFwidHJ1ZVwiKSB9XG4gICAgICAgIHJldHVybiB0aGlzLmxvZyhcInRyYW5zcG9ydFwiLCBgZXN0YWJsaXNoZWQgJHtmYWxsYmFja1RyYW5zcG9ydC5uYW1lfSBmYWxsYmFja2ApXG4gICAgICB9XG4gICAgICAvLyBpZiB3ZSd2ZSBlc3RhYmxpc2hlZCBwcmltYXJ5LCBnaXZlIHRoZSBmYWxsYmFjayBhIG5ldyBwZXJpb2QgdG8gYXR0ZW1wdCBwaW5nXG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5mYWxsYmFja1RpbWVyKVxuICAgICAgdGhpcy5mYWxsYmFja1RpbWVyID0gc2V0VGltZW91dChmYWxsYmFjaywgZmFsbGJhY2tUaHJlc2hvbGQpXG4gICAgICB0aGlzLnBpbmcocnR0ID0+IHtcbiAgICAgICAgdGhpcy5sb2coXCJ0cmFuc3BvcnRcIiwgXCJjb25uZWN0ZWQgdG8gcHJpbWFyeSBhZnRlclwiLCBydHQpXG4gICAgICAgIHRoaXMucHJpbWFyeVBhc3NlZEhlYWx0aENoZWNrID0gdHJ1ZVxuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5mYWxsYmFja1RpbWVyKVxuICAgICAgfSlcbiAgICB9KVxuICAgIHRoaXMudHJhbnNwb3J0Q29ubmVjdCgpXG4gIH1cblxuICBjbGVhckhlYXJ0YmVhdHMoKXtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5oZWFydGJlYXRUaW1lcilcbiAgICBjbGVhclRpbWVvdXQodGhpcy5oZWFydGJlYXRUaW1lb3V0VGltZXIpXG4gIH1cblxuICBvbkNvbm5PcGVuKCl7XG4gICAgaWYodGhpcy5oYXNMb2dnZXIoKSkgdGhpcy5sb2coXCJ0cmFuc3BvcnRcIiwgYCR7dGhpcy50cmFuc3BvcnQubmFtZX0gY29ubmVjdGVkIHRvICR7dGhpcy5lbmRQb2ludFVSTCgpfWApXG4gICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gZmFsc2VcbiAgICB0aGlzLmRpc2Nvbm5lY3RpbmcgPSBmYWxzZVxuICAgIHRoaXMuZXN0YWJsaXNoZWRDb25uZWN0aW9ucysrXG4gICAgdGhpcy5mbHVzaFNlbmRCdWZmZXIoKVxuICAgIHRoaXMucmVjb25uZWN0VGltZXIucmVzZXQoKVxuICAgIHRoaXMucmVzZXRIZWFydGJlYXQoKVxuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3Mub3Blbi5mb3JFYWNoKChbLCBjYWxsYmFja10pID0+IGNhbGxiYWNrKCkpXG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cbiAgaGVhcnRiZWF0VGltZW91dCgpe1xuICAgIGlmKHRoaXMucGVuZGluZ0hlYXJ0YmVhdFJlZil7XG4gICAgICB0aGlzLnBlbmRpbmdIZWFydGJlYXRSZWYgPSBudWxsXG4gICAgICBpZih0aGlzLmhhc0xvZ2dlcigpKXsgdGhpcy5sb2coXCJ0cmFuc3BvcnRcIiwgXCJoZWFydGJlYXQgdGltZW91dC4gQXR0ZW1wdGluZyB0byByZS1lc3RhYmxpc2ggY29ubmVjdGlvblwiKSB9XG4gICAgICB0aGlzLnRyaWdnZXJDaGFuRXJyb3IoKVxuICAgICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gZmFsc2VcbiAgICAgIHRoaXMudGVhcmRvd24oKCkgPT4gdGhpcy5yZWNvbm5lY3RUaW1lci5zY2hlZHVsZVRpbWVvdXQoKSwgV1NfQ0xPU0VfTk9STUFMLCBcImhlYXJ0YmVhdCB0aW1lb3V0XCIpXG4gICAgfVxuICB9XG5cbiAgcmVzZXRIZWFydGJlYXQoKXtcbiAgICBpZih0aGlzLmNvbm4gJiYgdGhpcy5jb25uLnNraXBIZWFydGJlYXQpeyByZXR1cm4gfVxuICAgIHRoaXMucGVuZGluZ0hlYXJ0YmVhdFJlZiA9IG51bGxcbiAgICB0aGlzLmNsZWFySGVhcnRiZWF0cygpXG4gICAgdGhpcy5oZWFydGJlYXRUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zZW5kSGVhcnRiZWF0KCksIHRoaXMuaGVhcnRiZWF0SW50ZXJ2YWxNcylcbiAgfVxuXG4gIHRlYXJkb3duKGNhbGxiYWNrLCBjb2RlLCByZWFzb24pe1xuICAgIGlmKCF0aGlzLmNvbm4pe1xuICAgICAgcmV0dXJuIGNhbGxiYWNrICYmIGNhbGxiYWNrKClcbiAgICB9XG4gICAgbGV0IGNvbm5lY3RDbG9jayA9IHRoaXMuY29ubmVjdENsb2NrXG5cbiAgICB0aGlzLndhaXRGb3JCdWZmZXJEb25lKCgpID0+IHtcbiAgICAgIGlmKGNvbm5lY3RDbG9jayAhPT0gdGhpcy5jb25uZWN0Q2xvY2speyByZXR1cm4gfVxuICAgICAgaWYodGhpcy5jb25uKXtcbiAgICAgICAgaWYoY29kZSl7IHRoaXMuY29ubi5jbG9zZShjb2RlLCByZWFzb24gfHwgXCJcIikgfSBlbHNlIHsgdGhpcy5jb25uLmNsb3NlKCkgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLndhaXRGb3JTb2NrZXRDbG9zZWQoKCkgPT4ge1xuICAgICAgICBpZihjb25uZWN0Q2xvY2sgIT09IHRoaXMuY29ubmVjdENsb2NrKXsgcmV0dXJuIH1cbiAgICAgICAgaWYodGhpcy5jb25uKXtcbiAgICAgICAgICB0aGlzLmNvbm4ub25vcGVuID0gZnVuY3Rpb24gKCl7IH0gLy8gbm9vcFxuICAgICAgICAgIHRoaXMuY29ubi5vbmVycm9yID0gZnVuY3Rpb24gKCl7IH0gLy8gbm9vcFxuICAgICAgICAgIHRoaXMuY29ubi5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAoKXsgfSAvLyBub29wXG4gICAgICAgICAgdGhpcy5jb25uLm9uY2xvc2UgPSBmdW5jdGlvbiAoKXsgfSAvLyBub29wXG4gICAgICAgICAgdGhpcy5jb25uID0gbnVsbFxuICAgICAgICB9XG5cbiAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgd2FpdEZvckJ1ZmZlckRvbmUoY2FsbGJhY2ssIHRyaWVzID0gMSl7XG4gICAgaWYodHJpZXMgPT09IDUgfHwgIXRoaXMuY29ubiB8fCAhdGhpcy5jb25uLmJ1ZmZlcmVkQW1vdW50KXtcbiAgICAgIGNhbGxiYWNrKClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy53YWl0Rm9yQnVmZmVyRG9uZShjYWxsYmFjaywgdHJpZXMgKyAxKVxuICAgIH0sIDE1MCAqIHRyaWVzKVxuICB9XG5cbiAgd2FpdEZvclNvY2tldENsb3NlZChjYWxsYmFjaywgdHJpZXMgPSAxKXtcbiAgICBpZih0cmllcyA9PT0gNSB8fCAhdGhpcy5jb25uIHx8IHRoaXMuY29ubi5yZWFkeVN0YXRlID09PSBTT0NLRVRfU1RBVEVTLmNsb3NlZCl7XG4gICAgICBjYWxsYmFjaygpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMud2FpdEZvclNvY2tldENsb3NlZChjYWxsYmFjaywgdHJpZXMgKyAxKVxuICAgIH0sIDE1MCAqIHRyaWVzKVxuICB9XG5cbiAgb25Db25uQ2xvc2UoZXZlbnQpe1xuICAgIGxldCBjbG9zZUNvZGUgPSBldmVudCAmJiBldmVudC5jb2RlXG4gICAgaWYodGhpcy5oYXNMb2dnZXIoKSkgdGhpcy5sb2coXCJ0cmFuc3BvcnRcIiwgXCJjbG9zZVwiLCBldmVudClcbiAgICB0aGlzLnRyaWdnZXJDaGFuRXJyb3IoKVxuICAgIHRoaXMuY2xlYXJIZWFydGJlYXRzKClcbiAgICBpZighdGhpcy5jbG9zZVdhc0NsZWFuICYmIGNsb3NlQ29kZSAhPT0gMTAwMCl7XG4gICAgICB0aGlzLnJlY29ubmVjdFRpbWVyLnNjaGVkdWxlVGltZW91dCgpXG4gICAgfVxuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3MuY2xvc2UuZm9yRWFjaCgoWywgY2FsbGJhY2tdKSA9PiBjYWxsYmFjayhldmVudCkpXG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIG9uQ29ubkVycm9yKGVycm9yKXtcbiAgICBpZih0aGlzLmhhc0xvZ2dlcigpKSB0aGlzLmxvZyhcInRyYW5zcG9ydFwiLCBlcnJvcilcbiAgICBsZXQgdHJhbnNwb3J0QmVmb3JlID0gdGhpcy50cmFuc3BvcnRcbiAgICBsZXQgZXN0YWJsaXNoZWRCZWZvcmUgPSB0aGlzLmVzdGFibGlzaGVkQ29ubmVjdGlvbnNcbiAgICB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzLmVycm9yLmZvckVhY2goKFssIGNhbGxiYWNrXSkgPT4ge1xuICAgICAgY2FsbGJhY2soZXJyb3IsIHRyYW5zcG9ydEJlZm9yZSwgZXN0YWJsaXNoZWRCZWZvcmUpXG4gICAgfSlcbiAgICBpZih0cmFuc3BvcnRCZWZvcmUgPT09IHRoaXMudHJhbnNwb3J0IHx8IGVzdGFibGlzaGVkQmVmb3JlID4gMCl7XG4gICAgICB0aGlzLnRyaWdnZXJDaGFuRXJyb3IoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgdHJpZ2dlckNoYW5FcnJvcigpe1xuICAgIHRoaXMuY2hhbm5lbHMuZm9yRWFjaChjaGFubmVsID0+IHtcbiAgICAgIGlmKCEoY2hhbm5lbC5pc0Vycm9yZWQoKSB8fCBjaGFubmVsLmlzTGVhdmluZygpIHx8IGNoYW5uZWwuaXNDbG9zZWQoKSkpe1xuICAgICAgICBjaGFubmVsLnRyaWdnZXIoQ0hBTk5FTF9FVkVOVFMuZXJyb3IpXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgKi9cbiAgY29ubmVjdGlvblN0YXRlKCl7XG4gICAgc3dpdGNoKHRoaXMuY29ubiAmJiB0aGlzLmNvbm4ucmVhZHlTdGF0ZSl7XG4gICAgICBjYXNlIFNPQ0tFVF9TVEFURVMuY29ubmVjdGluZzogcmV0dXJuIFwiY29ubmVjdGluZ1wiXG4gICAgICBjYXNlIFNPQ0tFVF9TVEFURVMub3BlbjogcmV0dXJuIFwib3BlblwiXG4gICAgICBjYXNlIFNPQ0tFVF9TVEFURVMuY2xvc2luZzogcmV0dXJuIFwiY2xvc2luZ1wiXG4gICAgICBkZWZhdWx0OiByZXR1cm4gXCJjbG9zZWRcIlxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICovXG4gIGlzQ29ubmVjdGVkKCl7IHJldHVybiB0aGlzLmNvbm5lY3Rpb25TdGF0ZSgpID09PSBcIm9wZW5cIiB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqXG4gICAqIEBwYXJhbSB7Q2hhbm5lbH1cbiAgICovXG4gIHJlbW92ZShjaGFubmVsKXtcbiAgICB0aGlzLm9mZihjaGFubmVsLnN0YXRlQ2hhbmdlUmVmcylcbiAgICB0aGlzLmNoYW5uZWxzID0gdGhpcy5jaGFubmVscy5maWx0ZXIoYyA9PiBjICE9PSBjaGFubmVsKVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYG9uT3BlbmAsIGBvbkNsb3NlYCwgYG9uRXJyb3IsYCBhbmQgYG9uTWVzc2FnZWAgcmVnaXN0cmF0aW9ucy5cbiAgICpcbiAgICogQHBhcmFtIHtyZWZzfSAtIGxpc3Qgb2YgcmVmcyByZXR1cm5lZCBieSBjYWxscyB0b1xuICAgKiAgICAgICAgICAgICAgICAgYG9uT3BlbmAsIGBvbkNsb3NlYCwgYG9uRXJyb3IsYCBhbmQgYG9uTWVzc2FnZWBcbiAgICovXG4gIG9mZihyZWZzKXtcbiAgICBmb3IobGV0IGtleSBpbiB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzKXtcbiAgICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3Nba2V5XSA9IHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3Nba2V5XS5maWx0ZXIoKFtyZWZdKSA9PiB7XG4gICAgICAgIHJldHVybiByZWZzLmluZGV4T2YocmVmKSA9PT0gLTFcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYXRlcyBhIG5ldyBjaGFubmVsIGZvciB0aGUgZ2l2ZW4gdG9waWNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRvcGljXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjaGFuUGFyYW1zIC0gUGFyYW1ldGVycyBmb3IgdGhlIGNoYW5uZWxcbiAgICogQHJldHVybnMge0NoYW5uZWx9XG4gICAqL1xuICBjaGFubmVsKHRvcGljLCBjaGFuUGFyYW1zID0ge30pe1xuICAgIGxldCBjaGFuID0gbmV3IENoYW5uZWwodG9waWMsIGNoYW5QYXJhbXMsIHRoaXMpXG4gICAgdGhpcy5jaGFubmVscy5wdXNoKGNoYW4pXG4gICAgcmV0dXJuIGNoYW5cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YVxuICAgKi9cbiAgcHVzaChkYXRhKXtcbiAgICBpZih0aGlzLmhhc0xvZ2dlcigpKXtcbiAgICAgIGxldCB7dG9waWMsIGV2ZW50LCBwYXlsb2FkLCByZWYsIGpvaW5fcmVmfSA9IGRhdGFcbiAgICAgIHRoaXMubG9nKFwicHVzaFwiLCBgJHt0b3BpY30gJHtldmVudH0gKCR7am9pbl9yZWZ9LCAke3JlZn0pYCwgcGF5bG9hZClcbiAgICB9XG5cbiAgICBpZih0aGlzLmlzQ29ubmVjdGVkKCkpe1xuICAgICAgdGhpcy5lbmNvZGUoZGF0YSwgcmVzdWx0ID0+IHRoaXMuY29ubi5zZW5kKHJlc3VsdCkpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2VuZEJ1ZmZlci5wdXNoKCgpID0+IHRoaXMuZW5jb2RlKGRhdGEsIHJlc3VsdCA9PiB0aGlzLmNvbm4uc2VuZChyZXN1bHQpKSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBuZXh0IG1lc3NhZ2UgcmVmLCBhY2NvdW50aW5nIGZvciBvdmVyZmxvd3NcbiAgICogQHJldHVybnMge3N0cmluZ31cbiAgICovXG4gIG1ha2VSZWYoKXtcbiAgICBsZXQgbmV3UmVmID0gdGhpcy5yZWYgKyAxXG4gICAgaWYobmV3UmVmID09PSB0aGlzLnJlZil7IHRoaXMucmVmID0gMCB9IGVsc2UgeyB0aGlzLnJlZiA9IG5ld1JlZiB9XG5cbiAgICByZXR1cm4gdGhpcy5yZWYudG9TdHJpbmcoKVxuICB9XG5cbiAgc2VuZEhlYXJ0YmVhdCgpe1xuICAgIGlmKHRoaXMucGVuZGluZ0hlYXJ0YmVhdFJlZiAmJiAhdGhpcy5pc0Nvbm5lY3RlZCgpKXsgcmV0dXJuIH1cbiAgICB0aGlzLnBlbmRpbmdIZWFydGJlYXRSZWYgPSB0aGlzLm1ha2VSZWYoKVxuICAgIHRoaXMucHVzaCh7dG9waWM6IFwicGhvZW5peFwiLCBldmVudDogXCJoZWFydGJlYXRcIiwgcGF5bG9hZDoge30sIHJlZjogdGhpcy5wZW5kaW5nSGVhcnRiZWF0UmVmfSlcbiAgICB0aGlzLmhlYXJ0YmVhdFRpbWVvdXRUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4gdGhpcy5oZWFydGJlYXRUaW1lb3V0KCksIHRoaXMuaGVhcnRiZWF0SW50ZXJ2YWxNcylcbiAgfVxuXG4gIGZsdXNoU2VuZEJ1ZmZlcigpe1xuICAgIGlmKHRoaXMuaXNDb25uZWN0ZWQoKSAmJiB0aGlzLnNlbmRCdWZmZXIubGVuZ3RoID4gMCl7XG4gICAgICB0aGlzLnNlbmRCdWZmZXIuZm9yRWFjaChjYWxsYmFjayA9PiBjYWxsYmFjaygpKVxuICAgICAgdGhpcy5zZW5kQnVmZmVyID0gW11cbiAgICB9XG4gIH1cblxuICBvbkNvbm5NZXNzYWdlKHJhd01lc3NhZ2Upe1xuICAgIHRoaXMuZGVjb2RlKHJhd01lc3NhZ2UuZGF0YSwgbXNnID0+IHtcbiAgICAgIGxldCB7dG9waWMsIGV2ZW50LCBwYXlsb2FkLCByZWYsIGpvaW5fcmVmfSA9IG1zZ1xuICAgICAgaWYocmVmICYmIHJlZiA9PT0gdGhpcy5wZW5kaW5nSGVhcnRiZWF0UmVmKXtcbiAgICAgICAgdGhpcy5jbGVhckhlYXJ0YmVhdHMoKVxuICAgICAgICB0aGlzLnBlbmRpbmdIZWFydGJlYXRSZWYgPSBudWxsXG4gICAgICAgIHRoaXMuaGVhcnRiZWF0VGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHRoaXMuc2VuZEhlYXJ0YmVhdCgpLCB0aGlzLmhlYXJ0YmVhdEludGVydmFsTXMpXG4gICAgICB9XG5cbiAgICAgIGlmKHRoaXMuaGFzTG9nZ2VyKCkpIHRoaXMubG9nKFwicmVjZWl2ZVwiLCBgJHtwYXlsb2FkLnN0YXR1cyB8fCBcIlwifSAke3RvcGljfSAke2V2ZW50fSAke3JlZiAmJiBcIihcIiArIHJlZiArIFwiKVwiIHx8IFwiXCJ9YCwgcGF5bG9hZClcblxuICAgICAgZm9yKGxldCBpID0gMDsgaSA8IHRoaXMuY2hhbm5lbHMubGVuZ3RoOyBpKyspe1xuICAgICAgICBjb25zdCBjaGFubmVsID0gdGhpcy5jaGFubmVsc1tpXVxuICAgICAgICBpZighY2hhbm5lbC5pc01lbWJlcih0b3BpYywgZXZlbnQsIHBheWxvYWQsIGpvaW5fcmVmKSl7IGNvbnRpbnVlIH1cbiAgICAgICAgY2hhbm5lbC50cmlnZ2VyKGV2ZW50LCBwYXlsb2FkLCByZWYsIGpvaW5fcmVmKVxuICAgICAgfVxuXG4gICAgICBmb3IobGV0IGkgPSAwOyBpIDwgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcy5tZXNzYWdlLmxlbmd0aDsgaSsrKXtcbiAgICAgICAgbGV0IFssIGNhbGxiYWNrXSA9IHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3MubWVzc2FnZVtpXVxuICAgICAgICBjYWxsYmFjayhtc2cpXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIGxlYXZlT3BlblRvcGljKHRvcGljKXtcbiAgICBsZXQgZHVwQ2hhbm5lbCA9IHRoaXMuY2hhbm5lbHMuZmluZChjID0+IGMudG9waWMgPT09IHRvcGljICYmIChjLmlzSm9pbmVkKCkgfHwgYy5pc0pvaW5pbmcoKSkpXG4gICAgaWYoZHVwQ2hhbm5lbCl7XG4gICAgICBpZih0aGlzLmhhc0xvZ2dlcigpKSB0aGlzLmxvZyhcInRyYW5zcG9ydFwiLCBgbGVhdmluZyBkdXBsaWNhdGUgdG9waWMgXCIke3RvcGljfVwiYClcbiAgICAgIGR1cENoYW5uZWwubGVhdmUoKVxuICAgIH1cbiAgfVxufVxuIiwgImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGluaXQoKSB7XG4gIGNvbnN0IGNhbnZhc0VsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNnaG9zdFwiKTtcblxuICBpZiAoIWNhbnZhc0VsKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImJvZHlcIikuY2xhc3NMaXN0LmFkZChcInNwb29reVwiKTtcblxuICBjb25zdCBtb3VzZVRocmVzaG9sZCA9IDAuMTtcbiAgY29uc3QgZGV2aWNlUGl4ZWxSYXRpbyA9IE1hdGgubWluKHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvLCAyKTtcblxuICBjb25zdCBtb3VzZSA9IHtcbiAgICB4OiAwLjMgKiB3aW5kb3cuaW5uZXJXaWR0aCxcbiAgICB5OiAwLjMgKiB3aW5kb3cuaW5uZXJIZWlnaHQsXG4gICAgdFg6IDAuMjUgKiB3aW5kb3cuaW5uZXJXaWR0aCxcbiAgICB0WTogMC40NSAqIHdpbmRvdy5pbm5lckhlaWdodCxcbiAgICBtb3Zpbmc6IGZhbHNlLFxuICAgIGNvbnRyb2xzUGFkZGluZzogMCxcbiAgfTtcblxuICBjb25zdCBwYXJhbXMgPSB7XG4gICAgc2l6ZTogMC4wNyxcbiAgICB0YWlsOiB7XG4gICAgICBkb3RzTnVtYmVyOiAyNSxcbiAgICAgIHNwcmluZzogMS40LFxuICAgICAgZnJpY3Rpb246IDAuMyxcbiAgICAgIG1heEdyYXZpdHk6IDUwLFxuICAgICAgZ3Jhdml0eTogMzUsXG4gICAgfSxcbiAgICBzbWlsZTogMSxcbiAgICBtYWluQ29sb3I6IFswLjk4LCAwLjk2LCAwLjk2XSxcbiAgICBib3JkZXJDb2xvcjogWzAuMiwgMC41LCAwLjddLFxuICAgIGlzRmxhdENvbG9yOiBmYWxzZSxcbiAgfTtcblxuICBjb25zdCB0ZXh0dXJlRWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xuICBjb25zdCB0ZXh0dXJlQ3R4ID0gdGV4dHVyZUVsLmdldENvbnRleHQoXCIyZFwiKTtcbiAgY29uc3QgcG9pbnRlclRyYWlsID0gbmV3IEFycmF5KHBhcmFtcy50YWlsLmRvdHNOdW1iZXIpO1xuICBsZXQgZG90U2l6ZSA9IChpKSA9PlxuICAgIHBhcmFtcy5zaXplICpcbiAgICB3aW5kb3cuaW5uZXJIZWlnaHQgKlxuICAgICgxIC0gMC4yICogTWF0aC5wb3coKDMgKiBpKSAvIHBhcmFtcy50YWlsLmRvdHNOdW1iZXIgLSAxLCAyKSk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcGFyYW1zLnRhaWwuZG90c051bWJlcjsgaSsrKSB7XG4gICAgcG9pbnRlclRyYWlsW2ldID0ge1xuICAgICAgeDogbW91c2UueCxcbiAgICAgIHk6IG1vdXNlLnksXG4gICAgICB2eDogMCxcbiAgICAgIHZ5OiAwLFxuICAgICAgb3BhY2l0eTogMC4wNCArIDAuMyAqIE1hdGgucG93KDEgLSBpIC8gcGFyYW1zLnRhaWwuZG90c051bWJlciwgNCksXG4gICAgICBib3JkZXJlZDogMC42ICogTWF0aC5wb3coMSAtIGkgLyBwb2ludGVyVHJhaWwubGVuZ3RoLCAxKSxcbiAgICAgIHI6IGRvdFNpemUoaSksXG4gICAgfTtcbiAgfVxuXG4gIGxldCB1bmlmb3JtcztcbiAgY29uc3QgZ2wgPSBpbml0U2hhZGVyKCk7XG5cbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJyZXNpemVcIiwgcmVzaXplQ2FudmFzKTtcbiAgcmVzaXplQ2FudmFzKCk7XG4gIHJlbmRlcigpO1xuXG4gIC8vIEFycmdoXG4gIHNldEludGVydmFsKHJlc2l6ZUNhbnZhcywgNTAwKTtcblxuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlbW92ZVwiLCAoZSkgPT4ge1xuICAgIHVwZGF0ZU1vdXNlUG9zaXRpb24oZS5wYWdlWCwgZS5wYWdlWSk7XG4gIH0pO1xuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNobW92ZVwiLCAoZSkgPT4ge1xuICAgIHVwZGF0ZU1vdXNlUG9zaXRpb24oZS50YXJnZXRUb3VjaGVzWzBdLnBhZ2VYLCBlLnRhcmdldFRvdWNoZXNbMF0ucGFnZVkpO1xuICB9KTtcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZSkgPT4ge1xuICAgIHVwZGF0ZU1vdXNlUG9zaXRpb24oZS5wYWdlWCwgZS5wYWdlWSk7XG4gIH0pO1xuXG4gIGxldCBtb3ZpbmdUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4gKG1vdXNlLm1vdmluZyA9IGZhbHNlKSwgMzAwKTtcblxuICBmdW5jdGlvbiB1cGRhdGVNb3VzZVBvc2l0aW9uKGVYLCBlWSkge1xuICAgIG1vdXNlLm1vdmluZyA9IHRydWU7XG4gICAgaWYgKG1vdXNlLmNvbnRyb2xzUGFkZGluZyA8IDApIHtcbiAgICAgIG1vdXNlLm1vdmluZyA9IGZhbHNlO1xuICAgIH1cbiAgICBjbGVhclRpbWVvdXQobW92aW5nVGltZXIpO1xuICAgIG1vdmluZ1RpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBtb3VzZS5tb3ZpbmcgPSBmYWxzZTtcbiAgICB9LCAzMDApO1xuXG4gICAgbW91c2UudFggPSBlWDtcblxuICAgIGNvbnN0IHNpemUgPSBwYXJhbXMuc2l6ZSAqIHdpbmRvdy5pbm5lckhlaWdodDtcbiAgICBlWSAtPSAwLjYgKiBzaXplO1xuICAgIG1vdXNlLnRZID0gZVkgPiBzaXplID8gZVkgOiBzaXplO1xuICAgIG1vdXNlLnRZIC09IG1vdXNlLmNvbnRyb2xzUGFkZGluZztcbiAgfVxuXG4gIGZ1bmN0aW9uIGluaXRTaGFkZXIoKSB7XG4gICAgY29uc3QgdnNTb3VyY2UgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInZlcnRTaGFkZXJcIikuaW5uZXJIVE1MO1xuICAgIGNvbnN0IGZzU291cmNlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJmcmFnU2hhZGVyXCIpLmlubmVySFRNTDtcblxuICAgIGNvbnN0IGdsID1cbiAgICAgIGNhbnZhc0VsLmdldENvbnRleHQoXCJ3ZWJnbFwiKSB8fCBjYW52YXNFbC5nZXRDb250ZXh0KFwiZXhwZXJpbWVudGFsLXdlYmdsXCIpO1xuXG4gICAgaWYgKCFnbCkge1xuICAgICAgYWxlcnQoXCJXZWJHTCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHlvdXIgYnJvd3Nlci5cIik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlU2hhZGVyKGdsLCBzb3VyY2VDb2RlLCB0eXBlKSB7XG4gICAgICBjb25zdCBzaGFkZXIgPSBnbC5jcmVhdGVTaGFkZXIodHlwZSk7XG4gICAgICBnbC5zaGFkZXJTb3VyY2Uoc2hhZGVyLCBzb3VyY2VDb2RlKTtcbiAgICAgIGdsLmNvbXBpbGVTaGFkZXIoc2hhZGVyKTtcblxuICAgICAgaWYgKCFnbC5nZXRTaGFkZXJQYXJhbWV0ZXIoc2hhZGVyLCBnbC5DT01QSUxFX1NUQVRVUykpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICBcIkFuIGVycm9yIG9jY3VycmVkIGNvbXBpbGluZyB0aGUgc2hhZGVyczogXCIgK1xuICAgICAgICAgIGdsLmdldFNoYWRlckluZm9Mb2coc2hhZGVyKSxcbiAgICAgICAgKTtcbiAgICAgICAgZ2wuZGVsZXRlU2hhZGVyKHNoYWRlcik7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gc2hhZGVyO1xuICAgIH1cblxuICAgIGNvbnN0IHZlcnRleFNoYWRlciA9IGNyZWF0ZVNoYWRlcihnbCwgdnNTb3VyY2UsIGdsLlZFUlRFWF9TSEFERVIpO1xuICAgIGNvbnN0IGZyYWdtZW50U2hhZGVyID0gY3JlYXRlU2hhZGVyKGdsLCBmc1NvdXJjZSwgZ2wuRlJBR01FTlRfU0hBREVSKTtcblxuICAgIGZ1bmN0aW9uIGNyZWF0ZVNoYWRlclByb2dyYW0oZ2wsIHZlcnRleFNoYWRlciwgZnJhZ21lbnRTaGFkZXIpIHtcbiAgICAgIGNvbnN0IHByb2dyYW0gPSBnbC5jcmVhdGVQcm9ncmFtKCk7XG4gICAgICBnbC5hdHRhY2hTaGFkZXIocHJvZ3JhbSwgdmVydGV4U2hhZGVyKTtcbiAgICAgIGdsLmF0dGFjaFNoYWRlcihwcm9ncmFtLCBmcmFnbWVudFNoYWRlcik7XG4gICAgICBnbC5saW5rUHJvZ3JhbShwcm9ncmFtKTtcblxuICAgICAgaWYgKCFnbC5nZXRQcm9ncmFtUGFyYW1ldGVyKHByb2dyYW0sIGdsLkxJTktfU1RBVFVTKSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgIFwiVW5hYmxlIHRvIGluaXRpYWxpemUgdGhlIHNoYWRlciBwcm9ncmFtOiBcIiArXG4gICAgICAgICAgZ2wuZ2V0UHJvZ3JhbUluZm9Mb2cocHJvZ3JhbSksXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcHJvZ3JhbTtcbiAgICB9XG5cbiAgICBjb25zdCBzaGFkZXJQcm9ncmFtID0gY3JlYXRlU2hhZGVyUHJvZ3JhbShnbCwgdmVydGV4U2hhZGVyLCBmcmFnbWVudFNoYWRlcik7XG4gICAgdW5pZm9ybXMgPSBnZXRVbmlmb3JtcyhzaGFkZXJQcm9ncmFtKTtcblxuICAgIGZ1bmN0aW9uIGdldFVuaWZvcm1zKHByb2dyYW0pIHtcbiAgICAgIGxldCB1bmlmb3JtcyA9IFtdO1xuICAgICAgbGV0IHVuaWZvcm1Db3VudCA9IGdsLmdldFByb2dyYW1QYXJhbWV0ZXIocHJvZ3JhbSwgZ2wuQUNUSVZFX1VOSUZPUk1TKTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdW5pZm9ybUNvdW50OyBpKyspIHtcbiAgICAgICAgbGV0IHVuaWZvcm1OYW1lID0gZ2wuZ2V0QWN0aXZlVW5pZm9ybShwcm9ncmFtLCBpKS5uYW1lO1xuICAgICAgICB1bmlmb3Jtc1t1bmlmb3JtTmFtZV0gPSBnbC5nZXRVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbSwgdW5pZm9ybU5hbWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHVuaWZvcm1zO1xuICAgIH1cblxuICAgIGNvbnN0IHZlcnRpY2VzID0gbmV3IEZsb2F0MzJBcnJheShbLTEsIC0xLCAxLCAtMSwgLTEsIDEsIDEsIDFdKTtcblxuICAgIGNvbnN0IHZlcnRleEJ1ZmZlciA9IGdsLmNyZWF0ZUJ1ZmZlcigpO1xuICAgIGdsLmJpbmRCdWZmZXIoZ2wuQVJSQVlfQlVGRkVSLCB2ZXJ0ZXhCdWZmZXIpO1xuICAgIGdsLmJ1ZmZlckRhdGEoZ2wuQVJSQVlfQlVGRkVSLCB2ZXJ0aWNlcywgZ2wuU1RBVElDX0RSQVcpO1xuXG4gICAgZ2wudXNlUHJvZ3JhbShzaGFkZXJQcm9ncmFtKTtcblxuICAgIGNvbnN0IHBvc2l0aW9uTG9jYXRpb24gPSBnbC5nZXRBdHRyaWJMb2NhdGlvbihzaGFkZXJQcm9ncmFtLCBcImFfcG9zaXRpb25cIik7XG4gICAgZ2wuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkocG9zaXRpb25Mb2NhdGlvbik7XG5cbiAgICBnbC5iaW5kQnVmZmVyKGdsLkFSUkFZX0JVRkZFUiwgdmVydGV4QnVmZmVyKTtcbiAgICBnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKHBvc2l0aW9uTG9jYXRpb24sIDIsIGdsLkZMT0FULCBmYWxzZSwgMCwgMCk7XG5cbiAgICBjb25zdCBjYW52YXNUZXh0dXJlID0gZ2wuY3JlYXRlVGV4dHVyZSgpO1xuICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIGNhbnZhc1RleHR1cmUpO1xuICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9NSU5fRklMVEVSLCBnbC5MSU5FQVIpO1xuICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9NQUdfRklMVEVSLCBnbC5MSU5FQVIpO1xuICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9XUkFQX1MsIGdsLkNMQU1QX1RPX0VER0UpO1xuICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9XUkFQX1QsIGdsLkNMQU1QX1RPX0VER0UpO1xuICAgIGdsLnRleEltYWdlMkQoXG4gICAgICBnbC5URVhUVVJFXzJELFxuICAgICAgMCxcbiAgICAgIGdsLlJHQkEsXG4gICAgICBnbC5SR0JBLFxuICAgICAgZ2wuVU5TSUdORURfQllURSxcbiAgICAgIHRleHR1cmVFbCxcbiAgICApO1xuICAgIGdsLnVuaWZvcm0xaSh1bmlmb3Jtcy51X3RleHR1cmUsIDApO1xuXG4gICAgZ2wudW5pZm9ybTFmKHVuaWZvcm1zLnVfc2l6ZSwgcGFyYW1zLnNpemUpO1xuICAgIGdsLnVuaWZvcm0zZihcbiAgICAgIHVuaWZvcm1zLnVfbWFpbl9jb2xvcixcbiAgICAgIHBhcmFtcy5tYWluQ29sb3JbMF0sXG4gICAgICBwYXJhbXMubWFpbkNvbG9yWzFdLFxuICAgICAgcGFyYW1zLm1haW5Db2xvclsyXSxcbiAgICApO1xuICAgIGdsLnVuaWZvcm0zZihcbiAgICAgIHVuaWZvcm1zLnVfYm9yZGVyX2NvbG9yLFxuICAgICAgcGFyYW1zLmJvcmRlckNvbG9yWzBdLFxuICAgICAgcGFyYW1zLmJvcmRlckNvbG9yWzFdLFxuICAgICAgcGFyYW1zLmJvcmRlckNvbG9yWzJdLFxuICAgICk7XG5cbiAgICByZXR1cm4gZ2w7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVUZXh0dXJlKCkge1xuICAgIHRleHR1cmVDdHguZmlsbFN0eWxlID0gXCJibGFja1wiO1xuICAgIHRleHR1cmVDdHguZmlsbFJlY3QoMCwgMCwgdGV4dHVyZUVsLndpZHRoLCB0ZXh0dXJlRWwuaGVpZ2h0KTtcblxuICAgIHBvaW50ZXJUcmFpbC5mb3JFYWNoKChwLCBwSWR4KSA9PiB7XG4gICAgICBpZiAocElkeCA9PT0gMCkge1xuICAgICAgICBwLnggPSBtb3VzZS54O1xuICAgICAgICBwLnkgPSBtb3VzZS55O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcC52eCArPSAocG9pbnRlclRyYWlsW3BJZHggLSAxXS54IC0gcC54KSAqIHBhcmFtcy50YWlsLnNwcmluZztcbiAgICAgICAgcC52eCAqPSBwYXJhbXMudGFpbC5mcmljdGlvbjtcblxuICAgICAgICBwLnZ5ICs9IChwb2ludGVyVHJhaWxbcElkeCAtIDFdLnkgLSBwLnkpICogcGFyYW1zLnRhaWwuc3ByaW5nO1xuICAgICAgICBwLnZ5ICo9IHBhcmFtcy50YWlsLmZyaWN0aW9uO1xuICAgICAgICBwLnZ5ICs9IHBhcmFtcy50YWlsLmdyYXZpdHk7XG5cbiAgICAgICAgcC54ICs9IHAudng7XG4gICAgICAgIHAueSArPSBwLnZ5O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBncmQgPSB0ZXh0dXJlQ3R4LmNyZWF0ZVJhZGlhbEdyYWRpZW50KFxuICAgICAgICBwLngsXG4gICAgICAgIHAueSxcbiAgICAgICAgcC5yICogcC5ib3JkZXJlZCxcbiAgICAgICAgcC54LFxuICAgICAgICBwLnksXG4gICAgICAgIHAucixcbiAgICAgICk7XG4gICAgICBncmQuYWRkQ29sb3JTdG9wKDAsIFwicmdiYSgyNTUsIDI1NSwgMjU1LCBcIiArIHAub3BhY2l0eSArIFwiKVwiKTtcbiAgICAgIGdyZC5hZGRDb2xvclN0b3AoMSwgXCJyZ2JhKDI1NSwgMjU1LCAyNTUsIDApXCIpO1xuXG4gICAgICB0ZXh0dXJlQ3R4LmJlZ2luUGF0aCgpO1xuICAgICAgdGV4dHVyZUN0eC5maWxsU3R5bGUgPSBncmQ7XG4gICAgICB0ZXh0dXJlQ3R4LmFyYyhwLngsIHAueSwgcC5yLCAwLCBNYXRoLlBJICogMik7XG4gICAgICB0ZXh0dXJlQ3R4LmZpbGwoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICBjb25zdCBjdXJyZW50VGltZSA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgIGdsLnVuaWZvcm0xZih1bmlmb3Jtcy51X3RpbWUsIGN1cnJlbnRUaW1lKTtcblxuICAgIGdsLmNsZWFyQ29sb3IoMC4wLCAwLjAsIDAuMCwgMS4wKTtcbiAgICBnbC5jbGVhcihnbC5DT0xPUl9CVUZGRVJfQklUKTtcbiAgICBnbC5kcmF3QXJyYXlzKGdsLlRSSUFOR0xFX1NUUklQLCAwLCA0KTtcblxuICAgIGlmIChtb3VzZS5tb3ZpbmcpIHtcbiAgICAgIHBhcmFtcy5zbWlsZSAtPSAwLjA1O1xuICAgICAgcGFyYW1zLnNtaWxlID0gTWF0aC5tYXgocGFyYW1zLnNtaWxlLCAtMC4xKTtcbiAgICAgIHBhcmFtcy50YWlsLmdyYXZpdHkgLT0gMTAgKiBwYXJhbXMuc2l6ZTtcbiAgICAgIHBhcmFtcy50YWlsLmdyYXZpdHkgPSBNYXRoLm1heChwYXJhbXMudGFpbC5ncmF2aXR5LCAwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcGFyYW1zLnNtaWxlICs9IDAuMDE7XG4gICAgICBwYXJhbXMuc21pbGUgPSBNYXRoLm1pbihwYXJhbXMuc21pbGUsIDEpO1xuICAgICAgaWYgKHBhcmFtcy50YWlsLmdyYXZpdHkgPiAzMCAqIHBhcmFtcy5zaXplKSB7XG4gICAgICAgIHBhcmFtcy50YWlsLmdyYXZpdHkgPVxuICAgICAgICAgICgzMCArIDkgKiAoMSArIE1hdGguc2luKDAuMDAyICogY3VycmVudFRpbWUpKSkgKiBwYXJhbXMuc2l6ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhcmFtcy50YWlsLmdyYXZpdHkgKz0gcGFyYW1zLnNpemU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbW91c2UueCArPSAobW91c2UudFggLSBtb3VzZS54KSAqIG1vdXNlVGhyZXNob2xkO1xuICAgIG1vdXNlLnkgKz0gKG1vdXNlLnRZIC0gbW91c2UueSkgKiBtb3VzZVRocmVzaG9sZDtcblxuICAgIGdsLnVuaWZvcm0xZih1bmlmb3Jtcy51X3NtaWxlLCBwYXJhbXMuc21pbGUpO1xuICAgIGdsLnVuaWZvcm0yZihcbiAgICAgIHVuaWZvcm1zLnVfcG9pbnRlcixcbiAgICAgIG1vdXNlLnggLyB3aW5kb3cuaW5uZXJXaWR0aCxcbiAgICAgIDEgLSBtb3VzZS55IC8gd2luZG93LmlubmVySGVpZ2h0LFxuICAgICk7XG4gICAgZ2wudW5pZm9ybTJmKFxuICAgICAgdW5pZm9ybXMudV90YXJnZXRfcG9pbnRlcixcbiAgICAgIG1vdXNlLnRYIC8gd2luZG93LmlubmVyV2lkdGgsXG4gICAgICAxIC0gbW91c2UudFkgLyB3aW5kb3cuaW5uZXJIZWlnaHQsXG4gICAgKTtcblxuICAgIHVwZGF0ZVRleHR1cmUoKTtcblxuICAgIGdsLnRleEltYWdlMkQoXG4gICAgICBnbC5URVhUVVJFXzJELFxuICAgICAgMCxcbiAgICAgIGdsLlJHQkEsXG4gICAgICBnbC5SR0JBLFxuICAgICAgZ2wuVU5TSUdORURfQllURSxcbiAgICAgIHRleHR1cmVFbCxcbiAgICApO1xuICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZShyZW5kZXIpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzaXplQ2FudmFzKCkge1xuICAgIGNhbnZhc0VsLndpZHRoID0gd2luZG93LmlubmVyV2lkdGggKiBkZXZpY2VQaXhlbFJhdGlvO1xuICAgIGNhbnZhc0VsLmhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodCAqIGRldmljZVBpeGVsUmF0aW87XG4gICAgdGV4dHVyZUVsLndpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XG4gICAgdGV4dHVyZUVsLmhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodDtcbiAgICBnbC52aWV3cG9ydCgwLCAwLCBjYW52YXNFbC53aWR0aCwgY2FudmFzRWwuaGVpZ2h0KTtcbiAgICBnbC51bmlmb3JtMWYodW5pZm9ybXMudV9yYXRpbywgY2FudmFzRWwud2lkdGggLyBjYW52YXNFbC5oZWlnaHQpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFyYW1zLnRhaWwuZG90c051bWJlcjsgaSsrKSB7XG4gICAgICBwb2ludGVyVHJhaWxbaV0uciA9IGRvdFNpemUoaSk7XG4gICAgfVxuICB9XG59XG4iLCAiLy8gY2FudmFzLWNvbmZldHRpIHYxLjYuMCBidWlsdCBvbiAyMDIyLTEwLTI0VDIxOjI2OjQxLjYxOVpcbnZhciBtb2R1bGUgPSB7fTtcblxuLy8gc291cmNlIGNvbnRlbnRcbihmdW5jdGlvbiBtYWluKGdsb2JhbCwgbW9kdWxlLCBpc1dvcmtlciwgd29ya2VyU2l6ZSkge1xuICB2YXIgY2FuVXNlV29ya2VyID0gISEoXG4gICAgZ2xvYmFsLldvcmtlciAmJlxuICAgIGdsb2JhbC5CbG9iICYmXG4gICAgZ2xvYmFsLlByb21pc2UgJiZcbiAgICBnbG9iYWwuT2Zmc2NyZWVuQ2FudmFzICYmXG4gICAgZ2xvYmFsLk9mZnNjcmVlbkNhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCAmJlxuICAgIGdsb2JhbC5IVE1MQ2FudmFzRWxlbWVudCAmJlxuICAgIGdsb2JhbC5IVE1MQ2FudmFzRWxlbWVudC5wcm90b3R5cGUudHJhbnNmZXJDb250cm9sVG9PZmZzY3JlZW4gJiZcbiAgICBnbG9iYWwuVVJMICYmXG4gICAgZ2xvYmFsLlVSTC5jcmVhdGVPYmplY3RVUkwpO1xuXG4gIGZ1bmN0aW9uIG5vb3AoKSB7fVxuXG4gIC8vIGNyZWF0ZSBhIHByb21pc2UgaWYgaXQgZXhpc3RzLCBvdGhlcndpc2UsIGp1c3RcbiAgLy8gY2FsbCB0aGUgZnVuY3Rpb24gZGlyZWN0bHlcbiAgZnVuY3Rpb24gcHJvbWlzZShmdW5jKSB7XG4gICAgdmFyIE1vZHVsZVByb21pc2UgPSBtb2R1bGUuZXhwb3J0cy5Qcm9taXNlO1xuICAgIHZhciBQcm9tID0gTW9kdWxlUHJvbWlzZSAhPT0gdm9pZCAwID8gTW9kdWxlUHJvbWlzZSA6IGdsb2JhbC5Qcm9taXNlO1xuXG4gICAgaWYgKHR5cGVvZiBQcm9tID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gbmV3IFByb20oZnVuYyk7XG4gICAgfVxuXG4gICAgZnVuYyhub29wLCBub29wKTtcblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdmFyIHJhZiA9IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIFRJTUUgPSBNYXRoLmZsb29yKDEwMDAgLyA2MCk7XG4gICAgdmFyIGZyYW1lLCBjYW5jZWw7XG4gICAgdmFyIGZyYW1lcyA9IHt9O1xuICAgIHZhciBsYXN0RnJhbWVUaW1lID0gMDtcblxuICAgIGlmICh0eXBlb2YgcmVxdWVzdEFuaW1hdGlvbkZyYW1lID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBjYW5jZWxBbmltYXRpb25GcmFtZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZnJhbWUgPSBmdW5jdGlvbiAoY2IpIHtcbiAgICAgICAgdmFyIGlkID0gTWF0aC5yYW5kb20oKTtcblxuICAgICAgICBmcmFtZXNbaWRdID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZ1bmN0aW9uIG9uRnJhbWUodGltZSkge1xuICAgICAgICAgIGlmIChsYXN0RnJhbWVUaW1lID09PSB0aW1lIHx8IGxhc3RGcmFtZVRpbWUgKyBUSU1FIC0gMSA8IHRpbWUpIHtcbiAgICAgICAgICAgIGxhc3RGcmFtZVRpbWUgPSB0aW1lO1xuICAgICAgICAgICAgZGVsZXRlIGZyYW1lc1tpZF07XG5cbiAgICAgICAgICAgIGNiKCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZyYW1lc1tpZF0gPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUob25GcmFtZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gaWQ7XG4gICAgICB9O1xuICAgICAgY2FuY2VsID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICAgIGlmIChmcmFtZXNbaWRdKSB7XG4gICAgICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUoZnJhbWVzW2lkXSk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGZyYW1lID0gZnVuY3Rpb24gKGNiKSB7XG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGNiLCBUSU1FKTtcbiAgICAgIH07XG4gICAgICBjYW5jZWwgPSBmdW5jdGlvbiAodGltZXIpIHtcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiB7IGZyYW1lOiBmcmFtZSwgY2FuY2VsOiBjYW5jZWwgfTtcbiAgfSgpKTtcblxuICB2YXIgZ2V0V29ya2VyID0gKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgd29ya2VyO1xuICAgIHZhciBwcm9tO1xuICAgIHZhciByZXNvbHZlcyA9IHt9O1xuXG4gICAgZnVuY3Rpb24gZGVjb3JhdGUod29ya2VyKSB7XG4gICAgICBmdW5jdGlvbiBleGVjdXRlKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgICAgIHdvcmtlci5wb3N0TWVzc2FnZSh7IG9wdGlvbnM6IG9wdGlvbnMgfHwge30sIGNhbGxiYWNrOiBjYWxsYmFjayB9KTtcbiAgICAgIH1cbiAgICAgIHdvcmtlci5pbml0ID0gZnVuY3Rpb24gaW5pdFdvcmtlcihjYW52YXMpIHtcbiAgICAgICAgdmFyIG9mZnNjcmVlbiA9IGNhbnZhcy50cmFuc2ZlckNvbnRyb2xUb09mZnNjcmVlbigpO1xuICAgICAgICB3b3JrZXIucG9zdE1lc3NhZ2UoeyBjYW52YXM6IG9mZnNjcmVlbiB9LCBbb2Zmc2NyZWVuXSk7XG4gICAgICB9O1xuXG4gICAgICB3b3JrZXIuZmlyZSA9IGZ1bmN0aW9uIGZpcmVXb3JrZXIob3B0aW9ucywgc2l6ZSwgZG9uZSkge1xuICAgICAgICBpZiAocHJvbSkge1xuICAgICAgICAgIGV4ZWN1dGUob3B0aW9ucywgbnVsbCk7XG4gICAgICAgICAgcmV0dXJuIHByb207XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgaWQgPSBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyKTtcblxuICAgICAgICBwcm9tID0gcHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICAgIGZ1bmN0aW9uIHdvcmtlckRvbmUobXNnKSB7XG4gICAgICAgICAgICBpZiAobXNnLmRhdGEuY2FsbGJhY2sgIT09IGlkKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZGVsZXRlIHJlc29sdmVzW2lkXTtcbiAgICAgICAgICAgIHdvcmtlci5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgd29ya2VyRG9uZSk7XG5cbiAgICAgICAgICAgIHByb20gPSBudWxsO1xuICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHdvcmtlci5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgd29ya2VyRG9uZSk7XG4gICAgICAgICAgZXhlY3V0ZShvcHRpb25zLCBpZCk7XG5cbiAgICAgICAgICByZXNvbHZlc1tpZF0gPSB3b3JrZXJEb25lLmJpbmQobnVsbCwgeyBkYXRhOiB7IGNhbGxiYWNrOiBpZCB9fSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBwcm9tO1xuICAgICAgfTtcblxuICAgICAgd29ya2VyLnJlc2V0ID0gZnVuY3Rpb24gcmVzZXRXb3JrZXIoKSB7XG4gICAgICAgIHdvcmtlci5wb3N0TWVzc2FnZSh7IHJlc2V0OiB0cnVlIH0pO1xuXG4gICAgICAgIGZvciAodmFyIGlkIGluIHJlc29sdmVzKSB7XG4gICAgICAgICAgcmVzb2x2ZXNbaWRdKCk7XG4gICAgICAgICAgZGVsZXRlIHJlc29sdmVzW2lkXTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKHdvcmtlcikge1xuICAgICAgICByZXR1cm4gd29ya2VyO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWlzV29ya2VyICYmIGNhblVzZVdvcmtlcikge1xuICAgICAgICB2YXIgY29kZSA9IFtcbiAgICAgICAgICAndmFyIENPTkZFVFRJLCBTSVpFID0ge30sIG1vZHVsZSA9IHt9OycsXG4gICAgICAgICAgJygnICsgbWFpbi50b1N0cmluZygpICsgJykodGhpcywgbW9kdWxlLCB0cnVlLCBTSVpFKTsnLFxuICAgICAgICAgICdvbm1lc3NhZ2UgPSBmdW5jdGlvbihtc2cpIHsnLFxuICAgICAgICAgICcgIGlmIChtc2cuZGF0YS5vcHRpb25zKSB7JyxcbiAgICAgICAgICAnICAgIENPTkZFVFRJKG1zZy5kYXRhLm9wdGlvbnMpLnRoZW4oZnVuY3Rpb24gKCkgeycsXG4gICAgICAgICAgJyAgICAgIGlmIChtc2cuZGF0YS5jYWxsYmFjaykgeycsXG4gICAgICAgICAgJyAgICAgICAgcG9zdE1lc3NhZ2UoeyBjYWxsYmFjazogbXNnLmRhdGEuY2FsbGJhY2sgfSk7JyxcbiAgICAgICAgICAnICAgICAgfScsXG4gICAgICAgICAgJyAgICB9KTsnLFxuICAgICAgICAgICcgIH0gZWxzZSBpZiAobXNnLmRhdGEucmVzZXQpIHsnLFxuICAgICAgICAgICcgICAgQ09ORkVUVEkgJiYgQ09ORkVUVEkucmVzZXQoKTsnLFxuICAgICAgICAgICcgIH0gZWxzZSBpZiAobXNnLmRhdGEucmVzaXplKSB7JyxcbiAgICAgICAgICAnICAgIFNJWkUud2lkdGggPSBtc2cuZGF0YS5yZXNpemUud2lkdGg7JyxcbiAgICAgICAgICAnICAgIFNJWkUuaGVpZ2h0ID0gbXNnLmRhdGEucmVzaXplLmhlaWdodDsnLFxuICAgICAgICAgICcgIH0gZWxzZSBpZiAobXNnLmRhdGEuY2FudmFzKSB7JyxcbiAgICAgICAgICAnICAgIFNJWkUud2lkdGggPSBtc2cuZGF0YS5jYW52YXMud2lkdGg7JyxcbiAgICAgICAgICAnICAgIFNJWkUuaGVpZ2h0ID0gbXNnLmRhdGEuY2FudmFzLmhlaWdodDsnLFxuICAgICAgICAgICcgICAgQ09ORkVUVEkgPSBtb2R1bGUuZXhwb3J0cy5jcmVhdGUobXNnLmRhdGEuY2FudmFzKTsnLFxuICAgICAgICAgICcgIH0nLFxuICAgICAgICAgICd9JyxcbiAgICAgICAgXS5qb2luKCdcXG4nKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB3b3JrZXIgPSBuZXcgV29ya2VyKFVSTC5jcmVhdGVPYmplY3RVUkwobmV3IEJsb2IoW2NvZGVdKSkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICB0eXBlb2YgY29uc29sZSAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBjb25zb2xlLndhcm4gPT09ICdmdW5jdGlvbicgPyBjb25zb2xlLndhcm4oJ1x1RDgzQ1x1REY4QSBDb3VsZCBub3QgbG9hZCB3b3JrZXInLCBlKSA6IG51bGw7XG5cbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGRlY29yYXRlKHdvcmtlcik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB3b3JrZXI7XG4gICAgfTtcbiAgfSkoKTtcblxuICB2YXIgZGVmYXVsdHMgPSB7XG4gICAgcGFydGljbGVDb3VudDogNTAsXG4gICAgYW5nbGU6IDkwLFxuICAgIHNwcmVhZDogNDUsXG4gICAgc3RhcnRWZWxvY2l0eTogNDUsXG4gICAgZGVjYXk6IDAuOSxcbiAgICBncmF2aXR5OiAxLFxuICAgIGRyaWZ0OiAwLFxuICAgIHRpY2tzOiAyMDAsXG4gICAgeDogMC41LFxuICAgIHk6IDAuNSxcbiAgICBzaGFwZXM6IFsnc3F1YXJlJywgJ2NpcmNsZSddLFxuICAgIHpJbmRleDogMTAwLFxuICAgIGNvbG9yczogW1xuICAgICAgJyMyNmNjZmYnLFxuICAgICAgJyNhMjVhZmQnLFxuICAgICAgJyNmZjVlN2UnLFxuICAgICAgJyM4OGZmNWEnLFxuICAgICAgJyNmY2ZmNDInLFxuICAgICAgJyNmZmE2MmQnLFxuICAgICAgJyNmZjM2ZmYnXG4gICAgXSxcbiAgICAvLyBwcm9iYWJseSBzaG91bGQgYmUgdHJ1ZSwgYnV0IGJhY2stY29tcGF0XG4gICAgZGlzYWJsZUZvclJlZHVjZWRNb3Rpb246IGZhbHNlLFxuICAgIHNjYWxhcjogMVxuICB9O1xuXG4gIGZ1bmN0aW9uIGNvbnZlcnQodmFsLCB0cmFuc2Zvcm0pIHtcbiAgICByZXR1cm4gdHJhbnNmb3JtID8gdHJhbnNmb3JtKHZhbCkgOiB2YWw7XG4gIH1cblxuICBmdW5jdGlvbiBpc09rKHZhbCkge1xuICAgIHJldHVybiAhKHZhbCA9PT0gbnVsbCB8fCB2YWwgPT09IHVuZGVmaW5lZCk7XG4gIH1cblxuICBmdW5jdGlvbiBwcm9wKG9wdGlvbnMsIG5hbWUsIHRyYW5zZm9ybSkge1xuICAgIHJldHVybiBjb252ZXJ0KFxuICAgICAgb3B0aW9ucyAmJiBpc09rKG9wdGlvbnNbbmFtZV0pID8gb3B0aW9uc1tuYW1lXSA6IGRlZmF1bHRzW25hbWVdLFxuICAgICAgdHJhbnNmb3JtXG4gICAgKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9ubHlQb3NpdGl2ZUludChudW1iZXIpe1xuICAgIHJldHVybiBudW1iZXIgPCAwID8gMCA6IE1hdGguZmxvb3IobnVtYmVyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJhbmRvbUludChtaW4sIG1heCkge1xuICAgIC8vIFttaW4sIG1heClcbiAgICByZXR1cm4gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogKG1heCAtIG1pbikpICsgbWluO1xuICB9XG5cbiAgZnVuY3Rpb24gdG9EZWNpbWFsKHN0cikge1xuICAgIHJldHVybiBwYXJzZUludChzdHIsIDE2KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNvbG9yc1RvUmdiKGNvbG9ycykge1xuICAgIHJldHVybiBjb2xvcnMubWFwKGhleFRvUmdiKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhleFRvUmdiKHN0cikge1xuICAgIHZhciB2YWwgPSBTdHJpbmcoc3RyKS5yZXBsYWNlKC9bXjAtOWEtZl0vZ2ksICcnKTtcblxuICAgIGlmICh2YWwubGVuZ3RoIDwgNikge1xuICAgICAgICB2YWwgPSB2YWxbMF0rdmFsWzBdK3ZhbFsxXSt2YWxbMV0rdmFsWzJdK3ZhbFsyXTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcjogdG9EZWNpbWFsKHZhbC5zdWJzdHJpbmcoMCwyKSksXG4gICAgICBnOiB0b0RlY2ltYWwodmFsLnN1YnN0cmluZygyLDQpKSxcbiAgICAgIGI6IHRvRGVjaW1hbCh2YWwuc3Vic3RyaW5nKDQsNikpXG4gICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldE9yaWdpbihvcHRpb25zKSB7XG4gICAgdmFyIG9yaWdpbiA9IHByb3Aob3B0aW9ucywgJ29yaWdpbicsIE9iamVjdCk7XG4gICAgb3JpZ2luLnggPSBwcm9wKG9yaWdpbiwgJ3gnLCBOdW1iZXIpO1xuICAgIG9yaWdpbi55ID0gcHJvcChvcmlnaW4sICd5JywgTnVtYmVyKTtcblxuICAgIHJldHVybiBvcmlnaW47XG4gIH1cblxuICBmdW5jdGlvbiBzZXRDYW52YXNXaW5kb3dTaXplKGNhbnZhcykge1xuICAgIGNhbnZhcy53aWR0aCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aDtcbiAgICBjYW52YXMuaGVpZ2h0ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNldENhbnZhc1JlY3RTaXplKGNhbnZhcykge1xuICAgIHZhciByZWN0ID0gY2FudmFzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNhbnZhcy53aWR0aCA9IHJlY3Qud2lkdGg7XG4gICAgY2FudmFzLmhlaWdodCA9IHJlY3QuaGVpZ2h0O1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0Q2FudmFzKHpJbmRleCkge1xuICAgIHZhciBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcblxuICAgIGNhbnZhcy5zdHlsZS5wb3NpdGlvbiA9ICdmaXhlZCc7XG4gICAgY2FudmFzLnN0eWxlLnRvcCA9ICcwcHgnO1xuICAgIGNhbnZhcy5zdHlsZS5sZWZ0ID0gJzBweCc7XG4gICAgY2FudmFzLnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnbm9uZSc7XG4gICAgY2FudmFzLnN0eWxlLnpJbmRleCA9IHpJbmRleDtcblxuICAgIHJldHVybiBjYW52YXM7XG4gIH1cblxuICBmdW5jdGlvbiBlbGxpcHNlKGNvbnRleHQsIHgsIHksIHJhZGl1c1gsIHJhZGl1c1ksIHJvdGF0aW9uLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSwgYW50aUNsb2Nrd2lzZSkge1xuICAgIGNvbnRleHQuc2F2ZSgpO1xuICAgIGNvbnRleHQudHJhbnNsYXRlKHgsIHkpO1xuICAgIGNvbnRleHQucm90YXRlKHJvdGF0aW9uKTtcbiAgICBjb250ZXh0LnNjYWxlKHJhZGl1c1gsIHJhZGl1c1kpO1xuICAgIGNvbnRleHQuYXJjKDAsIDAsIDEsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlLCBhbnRpQ2xvY2t3aXNlKTtcbiAgICBjb250ZXh0LnJlc3RvcmUoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJhbmRvbVBoeXNpY3Mob3B0cykge1xuICAgIHZhciByYWRBbmdsZSA9IG9wdHMuYW5nbGUgKiAoTWF0aC5QSSAvIDE4MCk7XG4gICAgdmFyIHJhZFNwcmVhZCA9IG9wdHMuc3ByZWFkICogKE1hdGguUEkgLyAxODApO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IG9wdHMueCxcbiAgICAgIHk6IG9wdHMueSxcbiAgICAgIHdvYmJsZTogTWF0aC5yYW5kb20oKSAqIDEwLFxuICAgICAgd29iYmxlU3BlZWQ6IE1hdGgubWluKDAuMTEsIE1hdGgucmFuZG9tKCkgKiAwLjEgKyAwLjA1KSxcbiAgICAgIHZlbG9jaXR5OiAob3B0cy5zdGFydFZlbG9jaXR5ICogMC41KSArIChNYXRoLnJhbmRvbSgpICogb3B0cy5zdGFydFZlbG9jaXR5KSxcbiAgICAgIGFuZ2xlMkQ6IC1yYWRBbmdsZSArICgoMC41ICogcmFkU3ByZWFkKSAtIChNYXRoLnJhbmRvbSgpICogcmFkU3ByZWFkKSksXG4gICAgICB0aWx0QW5nbGU6IChNYXRoLnJhbmRvbSgpICogKDAuNzUgLSAwLjI1KSArIDAuMjUpICogTWF0aC5QSSxcbiAgICAgIGNvbG9yOiBvcHRzLmNvbG9yLFxuICAgICAgc2hhcGU6IG9wdHMuc2hhcGUsXG4gICAgICB0aWNrOiAwLFxuICAgICAgdG90YWxUaWNrczogb3B0cy50aWNrcyxcbiAgICAgIGRlY2F5OiBvcHRzLmRlY2F5LFxuICAgICAgZHJpZnQ6IG9wdHMuZHJpZnQsXG4gICAgICByYW5kb206IE1hdGgucmFuZG9tKCkgKyAyLFxuICAgICAgdGlsdFNpbjogMCxcbiAgICAgIHRpbHRDb3M6IDAsXG4gICAgICB3b2JibGVYOiAwLFxuICAgICAgd29iYmxlWTogMCxcbiAgICAgIGdyYXZpdHk6IG9wdHMuZ3Jhdml0eSAqIDMsXG4gICAgICBvdmFsU2NhbGFyOiAwLjYsXG4gICAgICBzY2FsYXI6IG9wdHMuc2NhbGFyXG4gICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZUZldHRpKGNvbnRleHQsIGZldHRpKSB7XG4gICAgZmV0dGkueCArPSBNYXRoLmNvcyhmZXR0aS5hbmdsZTJEKSAqIGZldHRpLnZlbG9jaXR5ICsgZmV0dGkuZHJpZnQ7XG4gICAgZmV0dGkueSArPSBNYXRoLnNpbihmZXR0aS5hbmdsZTJEKSAqIGZldHRpLnZlbG9jaXR5ICsgZmV0dGkuZ3Jhdml0eTtcbiAgICBmZXR0aS53b2JibGUgKz0gZmV0dGkud29iYmxlU3BlZWQ7XG4gICAgZmV0dGkudmVsb2NpdHkgKj0gZmV0dGkuZGVjYXk7XG4gICAgZmV0dGkudGlsdEFuZ2xlICs9IDAuMTtcbiAgICBmZXR0aS50aWx0U2luID0gTWF0aC5zaW4oZmV0dGkudGlsdEFuZ2xlKTtcbiAgICBmZXR0aS50aWx0Q29zID0gTWF0aC5jb3MoZmV0dGkudGlsdEFuZ2xlKTtcbiAgICBmZXR0aS5yYW5kb20gPSBNYXRoLnJhbmRvbSgpICsgMjtcbiAgICBmZXR0aS53b2JibGVYID0gZmV0dGkueCArICgoMTAgKiBmZXR0aS5zY2FsYXIpICogTWF0aC5jb3MoZmV0dGkud29iYmxlKSk7XG4gICAgZmV0dGkud29iYmxlWSA9IGZldHRpLnkgKyAoKDEwICogZmV0dGkuc2NhbGFyKSAqIE1hdGguc2luKGZldHRpLndvYmJsZSkpO1xuXG4gICAgdmFyIHByb2dyZXNzID0gKGZldHRpLnRpY2srKykgLyBmZXR0aS50b3RhbFRpY2tzO1xuXG4gICAgdmFyIHgxID0gZmV0dGkueCArIChmZXR0aS5yYW5kb20gKiBmZXR0aS50aWx0Q29zKTtcbiAgICB2YXIgeTEgPSBmZXR0aS55ICsgKGZldHRpLnJhbmRvbSAqIGZldHRpLnRpbHRTaW4pO1xuICAgIHZhciB4MiA9IGZldHRpLndvYmJsZVggKyAoZmV0dGkucmFuZG9tICogZmV0dGkudGlsdENvcyk7XG4gICAgdmFyIHkyID0gZmV0dGkud29iYmxlWSArIChmZXR0aS5yYW5kb20gKiBmZXR0aS50aWx0U2luKTtcblxuICAgIGNvbnRleHQuZmlsbFN0eWxlID0gJ3JnYmEoJyArIGZldHRpLmNvbG9yLnIgKyAnLCAnICsgZmV0dGkuY29sb3IuZyArICcsICcgKyBmZXR0aS5jb2xvci5iICsgJywgJyArICgxIC0gcHJvZ3Jlc3MpICsgJyknO1xuICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XG5cbiAgICBpZiAoZmV0dGkuc2hhcGUgPT09ICdjaXJjbGUnKSB7XG4gICAgICBjb250ZXh0LmVsbGlwc2UgP1xuICAgICAgICBjb250ZXh0LmVsbGlwc2UoZmV0dGkueCwgZmV0dGkueSwgTWF0aC5hYnMoeDIgLSB4MSkgKiBmZXR0aS5vdmFsU2NhbGFyLCBNYXRoLmFicyh5MiAtIHkxKSAqIGZldHRpLm92YWxTY2FsYXIsIE1hdGguUEkgLyAxMCAqIGZldHRpLndvYmJsZSwgMCwgMiAqIE1hdGguUEkpIDpcbiAgICAgICAgZWxsaXBzZShjb250ZXh0LCBmZXR0aS54LCBmZXR0aS55LCBNYXRoLmFicyh4MiAtIHgxKSAqIGZldHRpLm92YWxTY2FsYXIsIE1hdGguYWJzKHkyIC0geTEpICogZmV0dGkub3ZhbFNjYWxhciwgTWF0aC5QSSAvIDEwICogZmV0dGkud29iYmxlLCAwLCAyICogTWF0aC5QSSk7XG4gICAgfSBlbHNlIGlmIChmZXR0aS5zaGFwZSA9PT0gJ3N0YXInKSB7XG4gICAgICB2YXIgcm90ID0gTWF0aC5QSSAvIDIgKiAzO1xuICAgICAgdmFyIGlubmVyUmFkaXVzID0gNCAqIGZldHRpLnNjYWxhcjtcbiAgICAgIHZhciBvdXRlclJhZGl1cyA9IDggKiBmZXR0aS5zY2FsYXI7XG4gICAgICB2YXIgeCA9IGZldHRpLng7XG4gICAgICB2YXIgeSA9IGZldHRpLnk7XG4gICAgICB2YXIgc3Bpa2VzID0gNTtcbiAgICAgIHZhciBzdGVwID0gTWF0aC5QSSAvIHNwaWtlcztcblxuICAgICAgd2hpbGUgKHNwaWtlcy0tKSB7XG4gICAgICAgIHggPSBmZXR0aS54ICsgTWF0aC5jb3Mocm90KSAqIG91dGVyUmFkaXVzO1xuICAgICAgICB5ID0gZmV0dGkueSArIE1hdGguc2luKHJvdCkgKiBvdXRlclJhZGl1cztcbiAgICAgICAgY29udGV4dC5saW5lVG8oeCwgeSk7XG4gICAgICAgIHJvdCArPSBzdGVwO1xuXG4gICAgICAgIHggPSBmZXR0aS54ICsgTWF0aC5jb3Mocm90KSAqIGlubmVyUmFkaXVzO1xuICAgICAgICB5ID0gZmV0dGkueSArIE1hdGguc2luKHJvdCkgKiBpbm5lclJhZGl1cztcbiAgICAgICAgY29udGV4dC5saW5lVG8oeCwgeSk7XG4gICAgICAgIHJvdCArPSBzdGVwO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZXh0Lm1vdmVUbyhNYXRoLmZsb29yKGZldHRpLngpLCBNYXRoLmZsb29yKGZldHRpLnkpKTtcbiAgICAgIGNvbnRleHQubGluZVRvKE1hdGguZmxvb3IoZmV0dGkud29iYmxlWCksIE1hdGguZmxvb3IoeTEpKTtcbiAgICAgIGNvbnRleHQubGluZVRvKE1hdGguZmxvb3IoeDIpLCBNYXRoLmZsb29yKHkyKSk7XG4gICAgICBjb250ZXh0LmxpbmVUbyhNYXRoLmZsb29yKHgxKSwgTWF0aC5mbG9vcihmZXR0aS53b2JibGVZKSk7XG4gICAgfVxuXG4gICAgY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICBjb250ZXh0LmZpbGwoKTtcblxuICAgIHJldHVybiBmZXR0aS50aWNrIDwgZmV0dGkudG90YWxUaWNrcztcbiAgfVxuXG4gIGZ1bmN0aW9uIGFuaW1hdGUoY2FudmFzLCBmZXR0aXMsIHJlc2l6ZXIsIHNpemUsIGRvbmUpIHtcbiAgICB2YXIgYW5pbWF0aW5nRmV0dGlzID0gZmV0dGlzLnNsaWNlKCk7XG4gICAgdmFyIGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICB2YXIgYW5pbWF0aW9uRnJhbWU7XG4gICAgdmFyIGRlc3Ryb3k7XG5cbiAgICB2YXIgcHJvbSA9IHByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgIGZ1bmN0aW9uIG9uRG9uZSgpIHtcbiAgICAgICAgYW5pbWF0aW9uRnJhbWUgPSBkZXN0cm95ID0gbnVsbDtcblxuICAgICAgICBjb250ZXh0LmNsZWFyUmVjdCgwLCAwLCBzaXplLndpZHRoLCBzaXplLmhlaWdodCk7XG5cbiAgICAgICAgZG9uZSgpO1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIHVwZGF0ZSgpIHtcbiAgICAgICAgaWYgKGlzV29ya2VyICYmICEoc2l6ZS53aWR0aCA9PT0gd29ya2VyU2l6ZS53aWR0aCAmJiBzaXplLmhlaWdodCA9PT0gd29ya2VyU2l6ZS5oZWlnaHQpKSB7XG4gICAgICAgICAgc2l6ZS53aWR0aCA9IGNhbnZhcy53aWR0aCA9IHdvcmtlclNpemUud2lkdGg7XG4gICAgICAgICAgc2l6ZS5oZWlnaHQgPSBjYW52YXMuaGVpZ2h0ID0gd29ya2VyU2l6ZS5oZWlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXNpemUud2lkdGggJiYgIXNpemUuaGVpZ2h0KSB7XG4gICAgICAgICAgcmVzaXplcihjYW52YXMpO1xuICAgICAgICAgIHNpemUud2lkdGggPSBjYW52YXMud2lkdGg7XG4gICAgICAgICAgc2l6ZS5oZWlnaHQgPSBjYW52YXMuaGVpZ2h0O1xuICAgICAgICB9XG5cbiAgICAgICAgY29udGV4dC5jbGVhclJlY3QoMCwgMCwgc2l6ZS53aWR0aCwgc2l6ZS5oZWlnaHQpO1xuXG4gICAgICAgIGFuaW1hdGluZ0ZldHRpcyA9IGFuaW1hdGluZ0ZldHRpcy5maWx0ZXIoZnVuY3Rpb24gKGZldHRpKSB7XG4gICAgICAgICAgcmV0dXJuIHVwZGF0ZUZldHRpKGNvbnRleHQsIGZldHRpKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKGFuaW1hdGluZ0ZldHRpcy5sZW5ndGgpIHtcbiAgICAgICAgICBhbmltYXRpb25GcmFtZSA9IHJhZi5mcmFtZSh1cGRhdGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9uRG9uZSgpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGFuaW1hdGlvbkZyYW1lID0gcmFmLmZyYW1lKHVwZGF0ZSk7XG4gICAgICBkZXN0cm95ID0gb25Eb25lO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFkZEZldHRpczogZnVuY3Rpb24gKGZldHRpcykge1xuICAgICAgICBhbmltYXRpbmdGZXR0aXMgPSBhbmltYXRpbmdGZXR0aXMuY29uY2F0KGZldHRpcyk7XG5cbiAgICAgICAgcmV0dXJuIHByb207XG4gICAgICB9LFxuICAgICAgY2FudmFzOiBjYW52YXMsXG4gICAgICBwcm9taXNlOiBwcm9tLFxuICAgICAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKGFuaW1hdGlvbkZyYW1lKSB7XG4gICAgICAgICAgcmFmLmNhbmNlbChhbmltYXRpb25GcmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZGVzdHJveSkge1xuICAgICAgICAgIGRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBjb25mZXR0aUNhbm5vbihjYW52YXMsIGdsb2JhbE9wdHMpIHtcbiAgICB2YXIgaXNMaWJDYW52YXMgPSAhY2FudmFzO1xuICAgIHZhciBhbGxvd1Jlc2l6ZSA9ICEhcHJvcChnbG9iYWxPcHRzIHx8IHt9LCAncmVzaXplJyk7XG4gICAgdmFyIGdsb2JhbERpc2FibGVGb3JSZWR1Y2VkTW90aW9uID0gcHJvcChnbG9iYWxPcHRzLCAnZGlzYWJsZUZvclJlZHVjZWRNb3Rpb24nLCBCb29sZWFuKTtcbiAgICB2YXIgc2hvdWxkVXNlV29ya2VyID0gY2FuVXNlV29ya2VyICYmICEhcHJvcChnbG9iYWxPcHRzIHx8IHt9LCAndXNlV29ya2VyJyk7XG4gICAgdmFyIHdvcmtlciA9IHNob3VsZFVzZVdvcmtlciA/IGdldFdvcmtlcigpIDogbnVsbDtcbiAgICB2YXIgcmVzaXplciA9IGlzTGliQ2FudmFzID8gc2V0Q2FudmFzV2luZG93U2l6ZSA6IHNldENhbnZhc1JlY3RTaXplO1xuICAgIHZhciBpbml0aWFsaXplZCA9IChjYW52YXMgJiYgd29ya2VyKSA/ICEhY2FudmFzLl9fY29uZmV0dGlfaW5pdGlhbGl6ZWQgOiBmYWxzZTtcbiAgICB2YXIgcHJlZmVyTGVzc01vdGlvbiA9IHR5cGVvZiBtYXRjaE1lZGlhID09PSAnZnVuY3Rpb24nICYmIG1hdGNoTWVkaWEoJyhwcmVmZXJzLXJlZHVjZWQtbW90aW9uKScpLm1hdGNoZXM7XG4gICAgdmFyIGFuaW1hdGlvbk9iajtcblxuICAgIGZ1bmN0aW9uIGZpcmVMb2NhbChvcHRpb25zLCBzaXplLCBkb25lKSB7XG4gICAgICB2YXIgcGFydGljbGVDb3VudCA9IHByb3Aob3B0aW9ucywgJ3BhcnRpY2xlQ291bnQnLCBvbmx5UG9zaXRpdmVJbnQpO1xuICAgICAgdmFyIGFuZ2xlID0gcHJvcChvcHRpb25zLCAnYW5nbGUnLCBOdW1iZXIpO1xuICAgICAgdmFyIHNwcmVhZCA9IHByb3Aob3B0aW9ucywgJ3NwcmVhZCcsIE51bWJlcik7XG4gICAgICB2YXIgc3RhcnRWZWxvY2l0eSA9IHByb3Aob3B0aW9ucywgJ3N0YXJ0VmVsb2NpdHknLCBOdW1iZXIpO1xuICAgICAgdmFyIGRlY2F5ID0gcHJvcChvcHRpb25zLCAnZGVjYXknLCBOdW1iZXIpO1xuICAgICAgdmFyIGdyYXZpdHkgPSBwcm9wKG9wdGlvbnMsICdncmF2aXR5JywgTnVtYmVyKTtcbiAgICAgIHZhciBkcmlmdCA9IHByb3Aob3B0aW9ucywgJ2RyaWZ0JywgTnVtYmVyKTtcbiAgICAgIHZhciBjb2xvcnMgPSBwcm9wKG9wdGlvbnMsICdjb2xvcnMnLCBjb2xvcnNUb1JnYik7XG4gICAgICB2YXIgdGlja3MgPSBwcm9wKG9wdGlvbnMsICd0aWNrcycsIE51bWJlcik7XG4gICAgICB2YXIgc2hhcGVzID0gcHJvcChvcHRpb25zLCAnc2hhcGVzJyk7XG4gICAgICB2YXIgc2NhbGFyID0gcHJvcChvcHRpb25zLCAnc2NhbGFyJyk7XG4gICAgICB2YXIgb3JpZ2luID0gZ2V0T3JpZ2luKG9wdGlvbnMpO1xuXG4gICAgICB2YXIgdGVtcCA9IHBhcnRpY2xlQ291bnQ7XG4gICAgICB2YXIgZmV0dGlzID0gW107XG5cbiAgICAgIHZhciBzdGFydFggPSBjYW52YXMud2lkdGggKiBvcmlnaW4ueDtcbiAgICAgIHZhciBzdGFydFkgPSBjYW52YXMuaGVpZ2h0ICogb3JpZ2luLnk7XG5cbiAgICAgIHdoaWxlICh0ZW1wLS0pIHtcbiAgICAgICAgZmV0dGlzLnB1c2goXG4gICAgICAgICAgcmFuZG9tUGh5c2ljcyh7XG4gICAgICAgICAgICB4OiBzdGFydFgsXG4gICAgICAgICAgICB5OiBzdGFydFksXG4gICAgICAgICAgICBhbmdsZTogYW5nbGUsXG4gICAgICAgICAgICBzcHJlYWQ6IHNwcmVhZCxcbiAgICAgICAgICAgIHN0YXJ0VmVsb2NpdHk6IHN0YXJ0VmVsb2NpdHksXG4gICAgICAgICAgICBjb2xvcjogY29sb3JzW3RlbXAgJSBjb2xvcnMubGVuZ3RoXSxcbiAgICAgICAgICAgIHNoYXBlOiBzaGFwZXNbcmFuZG9tSW50KDAsIHNoYXBlcy5sZW5ndGgpXSxcbiAgICAgICAgICAgIHRpY2tzOiB0aWNrcyxcbiAgICAgICAgICAgIGRlY2F5OiBkZWNheSxcbiAgICAgICAgICAgIGdyYXZpdHk6IGdyYXZpdHksXG4gICAgICAgICAgICBkcmlmdDogZHJpZnQsXG4gICAgICAgICAgICBzY2FsYXI6IHNjYWxhclxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIGlmIHdlIGhhdmUgYSBwcmV2aW91cyBjYW52YXMgYWxyZWFkeSBhbmltYXRpbmcsXG4gICAgICAvLyBhZGQgdG8gaXRcbiAgICAgIGlmIChhbmltYXRpb25PYmopIHtcbiAgICAgICAgcmV0dXJuIGFuaW1hdGlvbk9iai5hZGRGZXR0aXMoZmV0dGlzKTtcbiAgICAgIH1cblxuICAgICAgYW5pbWF0aW9uT2JqID0gYW5pbWF0ZShjYW52YXMsIGZldHRpcywgcmVzaXplciwgc2l6ZSAsIGRvbmUpO1xuXG4gICAgICByZXR1cm4gYW5pbWF0aW9uT2JqLnByb21pc2U7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZmlyZShvcHRpb25zKSB7XG4gICAgICB2YXIgZGlzYWJsZUZvclJlZHVjZWRNb3Rpb24gPSBnbG9iYWxEaXNhYmxlRm9yUmVkdWNlZE1vdGlvbiB8fCBwcm9wKG9wdGlvbnMsICdkaXNhYmxlRm9yUmVkdWNlZE1vdGlvbicsIEJvb2xlYW4pO1xuICAgICAgdmFyIHpJbmRleCA9IHByb3Aob3B0aW9ucywgJ3pJbmRleCcsIE51bWJlcik7XG5cbiAgICAgIGlmIChkaXNhYmxlRm9yUmVkdWNlZE1vdGlvbiAmJiBwcmVmZXJMZXNzTW90aW9uKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzTGliQ2FudmFzICYmIGFuaW1hdGlvbk9iaikge1xuICAgICAgICAvLyB1c2UgZXhpc3RpbmcgY2FudmFzIGZyb20gaW4tcHJvZ3Jlc3MgYW5pbWF0aW9uXG4gICAgICAgIGNhbnZhcyA9IGFuaW1hdGlvbk9iai5jYW52YXM7XG4gICAgICB9IGVsc2UgaWYgKGlzTGliQ2FudmFzICYmICFjYW52YXMpIHtcbiAgICAgICAgLy8gY3JlYXRlIGFuZCBpbml0aWFsaXplIGEgbmV3IGNhbnZhc1xuICAgICAgICBjYW52YXMgPSBnZXRDYW52YXMoekluZGV4KTtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChjYW52YXMpO1xuICAgICAgfVxuXG4gICAgICBpZiAoYWxsb3dSZXNpemUgJiYgIWluaXRpYWxpemVkKSB7XG4gICAgICAgIC8vIGluaXRpYWxpemUgdGhlIHNpemUgb2YgYSB1c2VyLXN1cHBsaWVkIGNhbnZhc1xuICAgICAgICByZXNpemVyKGNhbnZhcyk7XG4gICAgICB9XG5cbiAgICAgIHZhciBzaXplID0ge1xuICAgICAgICB3aWR0aDogY2FudmFzLndpZHRoLFxuICAgICAgICBoZWlnaHQ6IGNhbnZhcy5oZWlnaHRcbiAgICAgIH07XG5cbiAgICAgIGlmICh3b3JrZXIgJiYgIWluaXRpYWxpemVkKSB7XG4gICAgICAgIHdvcmtlci5pbml0KGNhbnZhcyk7XG4gICAgICB9XG5cbiAgICAgIGluaXRpYWxpemVkID0gdHJ1ZTtcblxuICAgICAgaWYgKHdvcmtlcikge1xuICAgICAgICBjYW52YXMuX19jb25mZXR0aV9pbml0aWFsaXplZCA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIG9uUmVzaXplKCkge1xuICAgICAgICBpZiAod29ya2VyKSB7XG4gICAgICAgICAgLy8gVE9ETyB0aGlzIHJlYWxseSBzaG91bGRuJ3QgYmUgaW1tZWRpYXRlLCBiZWNhdXNlIGl0IGlzIGV4cGVuc2l2ZVxuICAgICAgICAgIHZhciBvYmogPSB7XG4gICAgICAgICAgICBnZXRCb3VuZGluZ0NsaWVudFJlY3Q6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgaWYgKCFpc0xpYkNhbnZhcykge1xuICAgICAgICAgICAgICAgIHJldHVybiBjYW52YXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgcmVzaXplcihvYmopO1xuXG4gICAgICAgICAgd29ya2VyLnBvc3RNZXNzYWdlKHtcbiAgICAgICAgICAgIHJlc2l6ZToge1xuICAgICAgICAgICAgICB3aWR0aDogb2JqLndpZHRoLFxuICAgICAgICAgICAgICBoZWlnaHQ6IG9iai5oZWlnaHRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBkb24ndCBhY3R1YWxseSBxdWVyeSB0aGUgc2l6ZSBoZXJlLCBzaW5jZSB0aGlzXG4gICAgICAgIC8vIGNhbiBleGVjdXRlIGZyZXF1ZW50bHkgYW5kIHJhcGlkbHlcbiAgICAgICAgc2l6ZS53aWR0aCA9IHNpemUuaGVpZ2h0ID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gZG9uZSgpIHtcbiAgICAgICAgYW5pbWF0aW9uT2JqID0gbnVsbDtcblxuICAgICAgICBpZiAoYWxsb3dSZXNpemUpIHtcbiAgICAgICAgICBnbG9iYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVzaXplJywgb25SZXNpemUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzTGliQ2FudmFzICYmIGNhbnZhcykge1xuICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoY2FudmFzKTtcbiAgICAgICAgICBjYW52YXMgPSBudWxsO1xuICAgICAgICAgIGluaXRpYWxpemVkID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGFsbG93UmVzaXplKSB7XG4gICAgICAgIGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBvblJlc2l6ZSwgZmFsc2UpO1xuICAgICAgfVxuXG4gICAgICBpZiAod29ya2VyKSB7XG4gICAgICAgIHJldHVybiB3b3JrZXIuZmlyZShvcHRpb25zLCBzaXplLCBkb25lKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGZpcmVMb2NhbChvcHRpb25zLCBzaXplLCBkb25lKTtcbiAgICB9XG5cbiAgICBmaXJlLnJlc2V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKHdvcmtlcikge1xuICAgICAgICB3b3JrZXIucmVzZXQoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFuaW1hdGlvbk9iaikge1xuICAgICAgICBhbmltYXRpb25PYmoucmVzZXQoKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIGZpcmU7XG4gIH1cblxuICAvLyBNYWtlIGRlZmF1bHQgZXhwb3J0IGxhenkgdG8gZGVmZXIgd29ya2VyIGNyZWF0aW9uIHVudGlsIGNhbGxlZC5cbiAgdmFyIGRlZmF1bHRGaXJlO1xuICBmdW5jdGlvbiBnZXREZWZhdWx0RmlyZSgpIHtcbiAgICBpZiAoIWRlZmF1bHRGaXJlKSB7XG4gICAgICBkZWZhdWx0RmlyZSA9IGNvbmZldHRpQ2Fubm9uKG51bGwsIHsgdXNlV29ya2VyOiB0cnVlLCByZXNpemU6IHRydWUgfSk7XG4gICAgfVxuICAgIHJldHVybiBkZWZhdWx0RmlyZTtcbiAgfVxuXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGdldERlZmF1bHRGaXJlKCkuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfTtcbiAgbW9kdWxlLmV4cG9ydHMucmVzZXQgPSBmdW5jdGlvbigpIHtcbiAgICBnZXREZWZhdWx0RmlyZSgpLnJlc2V0KCk7XG4gIH07XG4gIG1vZHVsZS5leHBvcnRzLmNyZWF0ZSA9IGNvbmZldHRpQ2Fubm9uO1xufSgoZnVuY3Rpb24gKCkge1xuICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gd2luZG93O1xuICB9XG5cbiAgaWYgKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBzZWxmO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMgfHwge307XG59KSgpLCBtb2R1bGUsIGZhbHNlKSk7XG5cbi8vIGVuZCBzb3VyY2UgY29udGVudFxuXG5leHBvcnQgZGVmYXVsdCBtb2R1bGUuZXhwb3J0cztcbmV4cG9ydCB2YXIgY3JlYXRlID0gbW9kdWxlLmV4cG9ydHMuY3JlYXRlO1xuIiwgImltcG9ydCB7IFNvY2tldCB9IGZyb20gXCJwaG9lbml4XCI7XG5pbXBvcnQgY29uZmV0dGkgZnJvbSBcImNhbnZhcy1jb25mZXR0aVwiO1xuXG5mdW5jdGlvbiBjb25uZWN0KCkge1xuICBpZiAoIXdpbmRvdy51c2VyVG9rZW4ubGVuZ3RoKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnN0IHNvY2tldCA9IG5ldyBTb2NrZXQoXCIvc29ja2V0XCIsIHsgcGFyYW1zOiB7IHRva2VuOiB3aW5kb3cudXNlclRva2VuIH0gfSk7XG5cbiAgc29ja2V0LmNvbm5lY3QoKTtcblxuICBjb25zdCBjaGFubmVsID0gc29ja2V0LmNoYW5uZWwoXCJub3RpZmljYXRpb25zOipcIiwge30pO1xuXG4gIGNoYW5uZWxcbiAgICAuam9pbigpXG4gICAgLnJlY2VpdmUoXCJlcnJvclwiLCAocmVzcCkgPT4ge1xuICAgICAgY29uc29sZS5sb2coXCJVbmFibGUgdG8gam9pbiBub3RpZmljYXRpb25zIGNoYW5uZWxcIiwgcmVzcCk7XG4gICAgfSlcbiAgICAucmVjZWl2ZShcIm9rXCIsICgpID0+IGNvbnNvbGUubG9nKFwiQ29ubmVjdGVkXCIpKTtcblxuICBjaGFubmVsLm9uKFwibGlrZVwiLCBzaG93Tm90aWZpY2F0aW9uKTtcbiAgY2hhbm5lbC5vbihcImVycm9yXCIsIHVwZGF0ZUVycm9yKTtcbiAgY2hhbm5lbC5vbihcInBsYXlfc3RhdGVcIiwgdXBkYXRlUGxheXN0YXRlKTtcbn1cblxuY29uc3QgY29uZmV0dGlzID0ge1xuICBsaWtlOiBjb25mZXR0aSxcbiAgc3VwZXJfbGlrZTogYmlnQ29uZmV0dGksXG4gIGJ1cm46ICgpID0+IHt9LFxufTtcblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gIFwicGh4OnBvaW50LWdpdmVuXCIsXG4gICh7IGRldGFpbDogeyByZWFzb24gfSB9KSA9PiB7XG4gICAgLy8gUG9pbnQgZ2l2ZW4gQlkgdGhpcyBzZXNzaW9uXG4gICAgY29uZmV0dGlzW3JlYXNvbl0oKTtcbiAgfSxcbiAgZmFsc2UsXG4pO1xuXG5mdW5jdGlvbiBzaG93Tm90aWZpY2F0aW9uKHtcbiAgdHJhY2s6IHsgYXJ0aXN0LCBuYW1lLCBpbWcgfSxcbiAgZnJvbTogeyBmaXJzdF9uYW1lIH0sXG4gIHJlYXNvbixcbn0pIHtcbiAgY29uc3QgdGl0bGVzID0ge1xuICAgIGxpa2U6IGBcdUQ4M0RcdURFMEQgJHtmaXJzdF9uYW1lfSBsaWtlZCAke25hbWV9YCxcbiAgICBzdXBlcl9saWtlOiBgXHVEODNFXHVERDI5ICR7Zmlyc3RfbmFtZX0gU1VQRVJMSUtFRCAke25hbWV9IWAsXG4gICAgYnVybjogYFx1RDgzRFx1REQyNSBPaCBkZWFyICR7bmFtZX1gLFxuICB9O1xuICBjb25zdCBtc2dUaXRsZSA9IHRpdGxlc1tyZWFzb25dO1xuICAvLyBQb2ludCByZWNlaXZlZFxuICBjb25mZXR0aXNbcmVhc29uXSgpO1xuICBjb25zdCBvcHRpb25zID0ge1xuICAgIGltYWdlOiBpbWcsXG4gICAgaWNvbjogaW1nLFxuICAgIGJvZHk6IGAke25hbWV9IFx1MjAxMyAke2FydGlzdH1gLFxuICB9O1xuICBpZiAoIShcIk5vdGlmaWNhdGlvblwiIGluIHdpbmRvdykpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKE5vdGlmaWNhdGlvbi5wZXJtaXNzaW9uID09PSBcImdyYW50ZWRcIikge1xuICAgIG5ldyBOb3RpZmljYXRpb24obXNnVGl0bGUsIG9wdGlvbnMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlcXVlc3ROb3RpZmljYXRpb25QZXJtaXNzaW9uKCkge1xuICBpZiAoIShcIk5vdGlmaWNhdGlvblwiIGluIHdpbmRvdykpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgTm90aWZpY2F0aW9uLnJlcXVlc3RQZXJtaXNzaW9uKCk7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUVycm9yKHsgZXJyb3JfY29kZSB9KSB7XG4gIGlmIChlcnJvcl9jb2RlKSB7XG4gICAgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKFwiZXJyb3JcIik7XG4gIH0gZWxzZSB7XG4gICAgY29uc29sZS5sb2coXCJSZW1vdmUgZXJyb3JcIiwgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QpO1xuICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZShcImVycm9yXCIpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVBsYXlzdGF0ZSh7IHN0YXRlIH0pIHtcbiAgLy8gVXBkYXRlIHRoaXMgZmxhZyBmb3IgdGhlIGZhdmljb24gd29ya2VyIHRvIHBpY2sgdXBcbiAgd2luZG93LnBsYXlTdGF0ZSA9IHN0YXRlO1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoKSB7XG4gIHJlcXVlc3ROb3RpZmljYXRpb25QZXJtaXNzaW9uKCk7XG4gIGNvbm5lY3QoKTtcbn1cblxudmFyIGR1cmF0aW9uID0gMTAgKiAxMDAwO1xudmFyIGVuZCA9IERhdGUubm93KCkgKyBkdXJhdGlvbjtcblxuZnVuY3Rpb24gYmlnQ29uZmV0dGkoKSB7XG4gIC8vIGxhdW5jaCBhIGZldyBjb25mZXR0aSBmcm9tIHRoZSBsZWZ0IGVkZ2VcbiAgY29uZmV0dGkoe1xuICAgIHBhcnRpY2xlQ291bnQ6IDcsXG4gICAgYW5nbGU6IDYwLFxuICAgIHNwcmVhZDogNTUsXG4gICAgb3JpZ2luOiB7IHg6IDAgfSxcbiAgfSk7XG4gIC8vIGFuZCBsYXVuY2ggYSBmZXcgZnJvbSB0aGUgcmlnaHQgZWRnZVxuICBjb25mZXR0aSh7XG4gICAgcGFydGljbGVDb3VudDogNyxcbiAgICBhbmdsZTogMTIwLFxuICAgIHNwcmVhZDogNTUsXG4gICAgb3JpZ2luOiB7IHg6IDEgfSxcbiAgfSk7XG5cbiAgLy8ga2VlcCBnb2luZyB1bnRpbCB3ZSBhcmUgb3V0IG9mIHRpbWVcbiAgaWYgKERhdGUubm93KCkgPCBlbmQpIHtcbiAgICBzZXRUaW1lb3V0KGJpZ0NvbmZldHRpLCAxMCk7XG4gIH1cbn1cbiIsICIvLyBJbXBvcnQgZGVwZW5kZW5jaWVzXG4vL1xuaW1wb3J0IFwicGhvZW5peF9odG1sXCI7XG5pbXBvcnQgeyBMaXZlU29ja2V0IH0gZnJvbSBcInBob2VuaXhfbGl2ZV92aWV3XCI7XG5pbXBvcnQgeyBTb2NrZXQgfSBmcm9tIFwicGhvZW5peFwiO1xuXG5pbXBvcnQgaW5pdEdob3N0IGZyb20gXCIuL2dob3N0XCI7XG5pbXBvcnQgbm90aWZpY2F0aW9ucyBmcm9tIFwiLi9ub3RpZmljYXRpb25zXCI7XG5cbmNvbnN0IGNzcmZUb2tlbiA9IGRvY3VtZW50XG4gIC5xdWVyeVNlbGVjdG9yKFwibWV0YVtuYW1lPSdjc3JmLXRva2VuJ11cIilcbiAgLmdldEF0dHJpYnV0ZShcImNvbnRlbnRcIik7XG5jb25zdCBsaXZlU29ja2V0ID0gbmV3IExpdmVTb2NrZXQoXCIvbGl2ZVwiLCBTb2NrZXQsIHtcbiAgcGFyYW1zOiB7IF9jc3JmX3Rva2VuOiBjc3JmVG9rZW4gfSxcbn0pO1xubGl2ZVNvY2tldC5jb25uZWN0KCk7XG5cbi8vIExvYWQgdGhlIGdob3N0IHVwIGFmdGVyIGxpdmUgdmlldyBjb25uZWN0c1xuY29uc3Qgc29ja2V0ID0gbGl2ZVNvY2tldC5nZXRTb2NrZXQoKTtcbnNvY2tldC5vbk9wZW4oKCkgPT4ge1xuICBzZXRUaW1lb3V0KGluaXRHaG9zdCwgMTAwMCk7XG59KTtcblxuY29uc3QgaXNUb2RheSA9IChtb250aCwgZGF5KSA9PiB7XG4gIGNvbnN0IHRvZGF5ID0gbmV3IERhdGUoKTtcbiAgcmV0dXJuIGRheSA9PSB0b2RheS5nZXREYXRlKCkgJiYgbW9udGggPT0gdG9kYXkuZ2V0TW9udGgoKSArIDE7XG59O1xuXG5jb25zdCBQQUREWSA9IFszLCAxN107XG5cbmlmIChpc1RvZGF5KC4uLlBBRERZKSkge1xuICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiYm9keVwiKS5jbGFzc0xpc3QuYWRkKFwicGFkZHlcIik7XG59XG5cbmNvbnN0IHNlYXJjaElucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzZWFyY2hcIik7XG5cbmlmIChzZWFyY2hJbnB1dCkge1xuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICBcImxvYWRcIixcbiAgICAoX2V2dCkgPT4ge1xuICAgICAgc2VhcmNoSW5wdXQuZm9jdXMoKTtcbiAgICB9LFxuICAgIGZhbHNlLFxuICApO1xuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICBcImtleXVwXCIsXG4gICAgKGV2dCkgPT4ge1xuICAgICAgaWYgKGV2dC5rZXkgPT09IFwiZlwiKSB7XG4gICAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBzZWFyY2hJbnB1dC5mb2N1cygpO1xuICAgICAgfVxuICAgIH0sXG4gICAgZmFsc2UsXG4gICk7XG59XG5cbm5vdGlmaWNhdGlvbnMoKTtcbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUVBLEVBQUMsWUFBVztBQUNWLFFBQUksZ0JBQWdCO0FBRXBCLGdDQUE0QjtBQUMxQixVQUFJLE9BQU8sT0FBTyxnQkFBZ0I7QUFBWSxlQUFPLE9BQU87QUFF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