From d2364276a1cbfb2b6b3851fd9fb0e48d773b923b Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 10 Oct 2020 01:21:57 -0500 Subject: [PATCH 001/373] Blocks: always see your own posts --- lib/pleroma/web/activity_pub/activity_pub.ex | 23 +++++++++++++---- test/web/activity_pub/activity_pub_test.exs | 27 ++++++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index eb44cffec..bf89c228a 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -791,10 +791,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do where: fragment( """ - ?->>'type' != 'Create' -- This isn't a Create + ?->>'type' != 'Create' -- This isn't a Create OR ?->>'inReplyTo' is null -- this isn't a reply - OR ? && array_remove(?, ?) -- The recipient is us or one of our friends, - -- unless they are the author (because authors + OR ? && array_remove(?, ?) -- The recipient is us or one of our friends, + -- unless they are the author (because authors -- are also part of the recipients). This leads -- to a bug that self-replies by friends won't -- show up. @@ -850,7 +850,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do from( [activity, object: o] in query, + # You don't block the author where: fragment("not (? = ANY(?))", activity.actor, ^blocked_ap_ids), + + # You don't block any recipients, and didn't author the post where: fragment( "((not (? && ?)) or ? = ?)", @@ -859,12 +862,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do activity.actor, ^user.ap_id ), + + # You don't block the domain of any recipients, and didn't author the post where: fragment( - "recipients_contain_blocked_domains(?, ?) = false", + "(recipients_contain_blocked_domains(?, ?) = false) or ? = ?", activity.recipients, - ^domain_blocks + ^domain_blocks, + activity.actor, + ^user.ap_id ), + + # It's not a boost of a user you block where: fragment( "not (?->>'type' = 'Announce' and ?->'to' \\?| ?)", @@ -872,6 +881,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do activity.data, ^blocked_ap_ids ), + + # You don't block the author's domain, and also don't follow the author where: fragment( "(not (split_part(?, '/', 3) = ANY(?))) or ? = ANY(?)", @@ -880,6 +891,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do activity.actor, ^following_ap_ids ), + + # Same as above, but checks the Object where: fragment( "(not (split_part(?->>'actor', '/', 3) = ANY(?))) or (?->>'actor') = ANY(?)", diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs index 804305a13..e4661b478 100644 --- a/test/web/activity_pub/activity_pub_test.exs +++ b/test/web/activity_pub/activity_pub_test.exs @@ -622,6 +622,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do assert Enum.member?(activities, activity_one) end + test "always see your own posts even when they address people you block" do + user = insert(:user) + blockee = insert(:user) + + {:ok, _} = User.block(user, blockee) + {:ok, activity} = CommonAPI.post(user, %{status: "hey! @#{blockee.nickname}"}) + + activities = ActivityPub.fetch_activities([], %{blocking_user: user}) + + assert Enum.member?(activities, activity) + end + test "doesn't return transitive interactions concerning blocked users" do blocker = insert(:user) blockee = insert(:user) @@ -721,6 +733,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do refute repeat_activity in activities end + test "see your own posts even when they adress actors from blocked domains" do + user = insert(:user) + + domain = "dogwhistle.zone" + domain_user = insert(:user, %{ap_id: "https://#{domain}/@pundit"}) + + {:ok, user} = User.block_domain(user, domain) + + {:ok, activity} = CommonAPI.post(user, %{status: "hey! @#{domain_user.nickname}"}) + + activities = ActivityPub.fetch_activities([], %{blocking_user: user}) + + assert Enum.member?(activities, activity) + end + test "does return activities from followed users on blocked domains" do domain = "meanies.social" domain_user = insert(:user, %{ap_id: "https://#{domain}/@pundit"}) From 2fc7ce3e1e2fb746305944d40ac74da16d48f7aa Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 10 Oct 2020 01:29:41 -0500 Subject: [PATCH 002/373] Blocks: add blockers_visible config --- config/config.exs | 1 + config/description.exs | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/config/config.exs b/config/config.exs index d53663d36..befc6840d 100644 --- a/config/config.exs +++ b/config/config.exs @@ -363,6 +363,7 @@ config :pleroma, :manifest, config :pleroma, :activitypub, unfollow_blocked: true, outgoing_blocks: true, + blockers_visible: true, follow_handshake_timeout: 500, note_replies_output_limit: 5, sign_object_fetches: true, diff --git a/config/description.exs b/config/description.exs index 3902b9632..4f495e828 100644 --- a/config/description.exs +++ b/config/description.exs @@ -2092,6 +2092,11 @@ config :pleroma, :config_description, [ type: :boolean, description: "Whether to federate blocks to other instances" }, + %{ + key: :blockers_visible, + type: :boolean, + description: "Whether a user can see someone who has blocked them" + }, %{ key: :sign_object_fetches, type: :boolean, From 7c2d0e378c45dd1c03fbd4a9d338bbeb4f9d2610 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 10 Oct 2020 03:41:35 -0500 Subject: [PATCH 003/373] Blocks: make blockers_visible config work --- lib/pleroma/web/activity_pub/activity_pub.ex | 27 +++++++++++++++++++ .../controllers/timeline_controller_test.exs | 18 +++++++++++++ 2 files changed, 45 insertions(+) diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index bf89c228a..c9712d245 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -410,6 +410,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do |> maybe_preload_bookmarks(opts) |> maybe_set_thread_muted_field(opts) |> restrict_blocked(opts) + |> restrict_blockers_visibility(opts) |> restrict_recipients(recipients, opts[:user]) |> restrict_filtered(opts) |> where( @@ -906,6 +907,31 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do defp restrict_blocked(query, _), do: query + defp restrict_blockers_visibility(query, %{blocking_user: %User{} = user}) do + if Config.get([:activitypub, :blockers_visible]) == true do + query + else + blocker_ap_ids = User.incoming_relationships_ungrouped_ap_ids(user, [:block]) + + from( + activity in query, + # The author doesn't block you + where: fragment("not (? = ANY(?))", activity.actor, ^blocker_ap_ids), + + # It's not a boost of a user that blocks you + where: + fragment( + "not (?->>'type' = 'Announce' and ?->'to' \\?| ?)", + activity.data, + activity.data, + ^blocker_ap_ids + ) + ) + end + end + + defp restrict_blockers_visibility(query, _), do: query + defp restrict_unlisted(query, %{restrict_unlisted: true}) do from( activity in query, @@ -1106,6 +1132,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do |> restrict_state(opts) |> restrict_favorited_by(opts) |> restrict_blocked(restrict_blocked_opts) + |> restrict_blockers_visibility(opts) |> restrict_muted(restrict_muted_opts) |> restrict_filtered(opts) |> restrict_media(opts) diff --git a/test/web/mastodon_api/controllers/timeline_controller_test.exs b/test/web/mastodon_api/controllers/timeline_controller_test.exs index c6e0268fd..e2a830811 100644 --- a/test/web/mastodon_api/controllers/timeline_controller_test.exs +++ b/test/web/mastodon_api/controllers/timeline_controller_test.exs @@ -126,6 +126,24 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do [%{"id" => ^reply_from_me}, %{"id" => ^activity_id}] = response end + test "doesn't return posts from users who blocked you when :blockers_visible is disabled" do + clear_config([:activitypub, :blockers_visible], false) + + %{conn: conn, user: blockee} = oauth_access(["read:statuses"]) + blocker = insert(:user) + {:ok, _} = User.block(blocker, blockee) + + conn = assign(conn, :user, blockee) + + {:ok, _} = CommonAPI.post(blocker, %{status: "hey!"}) + + response = + get(conn, "/api/v1/timelines/public") + |> json_response_and_validate_schema(200) + + assert length(response) == 0 + end + test "doesn't return replies if follow is posting with users from blocked domain" do %{conn: conn, user: blocker} = oauth_access(["read:statuses"]) friend = insert(:user) From 5c8d2c468c3a14cde029e7aeedd0cdb580cce1df Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 10 Oct 2020 03:44:20 -0500 Subject: [PATCH 004/373] Blocks: update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fc1750d1..bb4c6d383 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Mix tasks for controlling user account confirmation status in bulk (`mix pleroma.user confirm_all` and `mix pleroma.user unconfirm_all`) - Mix task for sending confirmation emails to all unconfirmed users (`mix pleroma.email send_confirmation_mails`) - Mix task option for force-unfollowing relays +- `[:activitypub, :blockers_visible]` config to control visibility of blockers. ### Changed @@ -48,6 +49,7 @@ switched to a new configuration mechanism, however it was not officially removed - Add documented-but-missing chat pagination. - Allow sending out emails again. +- See your own post when addressing a user from a blocked domain. ## Unreleased (Patch) From 2aeb229de3f59e1704c633c31415e7e834f6ba67 Mon Sep 17 00:00:00 2001 From: lain Date: Wed, 4 Nov 2020 16:23:24 +0100 Subject: [PATCH 005/373] Cheatsheet: Add info about :blockers_visible --- docs/configuration/cheatsheet.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md index ebf95ebc9..75cb4b348 100644 --- a/docs/configuration/cheatsheet.md +++ b/docs/configuration/cheatsheet.md @@ -205,6 +205,7 @@ config :pleroma, :mrf_user_allowlist, %{ ### :activitypub * `unfollow_blocked`: Whether blocks result in people getting unfollowed * `outgoing_blocks`: Whether to federate blocks to other instances +* `blockers_visible`: Whether a user can see the posts of users who blocked them * `deny_follow_blocked`: Whether to disallow following an account that has blocked the user in question * `sign_object_fetches`: Sign object fetches with HTTP signatures * `authorized_fetch_mode`: Require HTTP signatures for AP fetches From cc09079aea54f5ff754925e0d5fbbc3b268dcb6d Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Wed, 6 Jan 2021 15:39:14 -0600 Subject: [PATCH 006/373] Exclude blockers from notifications when `blockers_visible: false` --- lib/pleroma/notification.ex | 12 ++++++++++++ .../notification_controller_test.exs | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index dd7a1c824..e9c9b3ea2 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -132,6 +132,7 @@ defmodule Pleroma.Notification do |> preload([n, a, o], activity: {a, object: o}) |> exclude_notification_muted(user, exclude_notification_muted_opts) |> exclude_blocked(user, exclude_blocked_opts) + |> exclude_blockers(user) |> exclude_filtered(user) |> exclude_visibility(opts) end @@ -145,6 +146,17 @@ defmodule Pleroma.Notification do |> FollowingRelationship.keep_following_or_not_domain_blocked(user) end + defp exclude_blockers(query, user) do + if Pleroma.Config.get([:activitypub, :blockers_visible]) == true do + query + else + blocker_ap_ids = User.incoming_relationships_ungrouped_ap_ids(user, [:block]) + + query + |> where([n, a], a.actor not in ^blocker_ap_ids) + end + end + defp exclude_notification_muted(query, _, %{@include_muted_option => true}) do query end diff --git a/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs index 9ac8488f6..ef35bdd00 100644 --- a/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs @@ -103,6 +103,25 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do assert [_] = result end + test "excludes mentions from blockers when blockers_visible is false" do + clear_config([:activitypub, :blockers_visible], false) + + %{user: user, conn: conn} = oauth_access(["read:notifications"]) + blocker = insert(:user) + + {:ok, _} = CommonAPI.block(blocker, user) + {:ok, activity} = CommonAPI.post(blocker, %{status: "hi @#{user.nickname}"}) + + {:ok, [_notification]} = Notification.create_notifications(activity) + + conn = + conn + |> assign(:user, user) + |> get("/api/v1/notifications") + + assert [] == json_response_and_validate_schema(conn, 200) + end + test "getting a single notification" do %{user: user, conn: conn} = oauth_access(["read:notifications"]) other_user = insert(:user) From b7b05a074867c1444dd539d6d2331f6d5504f6e6 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Wed, 6 Jan 2021 15:42:36 -0600 Subject: [PATCH 007/373] Oopsie whoopsie fix changelog --- CHANGELOG.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10968d02b..dc1b4b6c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -141,13 +141,7 @@ switched to a new configuration mechanism, however it was not officially removed - Allow sending out emails again. - Allow sending chat messages to yourself - OStatus / static FE endpoints: fixed inaccessibility for anonymous users on non-federating instances, switched to handling per `:restrict_unauthenticated` setting. -<<<<<<< HEAD -- Mastodon API: Current user is now included in conversation if it's the only participant -- Mastodon API: Fixed last_status.account being not filled with account data -- See your own post when addressing a user from a blocked domain. -======= - Fix remote users with a whitespace name. ->>>>>>> upstream/develop ### Upgrade notes From 7eecc3b61d6da64e0bfdc5b155cba0dae07b84d5 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Tue, 16 Feb 2021 23:23:35 +0100 Subject: [PATCH 008/373] OpenAPI: MastodonAPI Timeline Controller --- .../api_spec/operations/timeline_operation.ex | 3 ++- .../controllers/timeline_controller_test.exs | 16 ++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/pleroma/web/api_spec/operations/timeline_operation.ex b/lib/pleroma/web/api_spec/operations/timeline_operation.ex index cae18c758..24d792916 100644 --- a/lib/pleroma/web/api_spec/operations/timeline_operation.ex +++ b/lib/pleroma/web/api_spec/operations/timeline_operation.ex @@ -115,7 +115,8 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do ], operationId: "TimelineController.hashtag", responses: %{ - 200 => Operation.response("Array of Status", "application/json", array_of_statuses()) + 200 => Operation.response("Array of Status", "application/json", array_of_statuses()), + 401 => Operation.response("Error", "application/json", ApiError) } } end diff --git a/test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs index cc409451c..ed1286675 100644 --- a/test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs @@ -905,10 +905,10 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do %{conn: auth_conn} = oauth_access(["read:statuses"]) res_conn = get(auth_conn, "#{base_uri}?local=true") - assert length(json_response(res_conn, 200)) == 1 + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 res_conn = get(auth_conn, "#{base_uri}?local=false") - assert length(json_response(res_conn, 200)) == 2 + assert length(json_response_and_validate_schema(res_conn, 200)) == 2 end test "with default settings on private instances, returns 403 for unauthenticated users", %{ @@ -922,7 +922,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do for local <- [true, false] do res_conn = get(conn, "#{base_uri}?local=#{local}") - assert json_response(res_conn, :unauthorized) == error_response + assert json_response_and_validate_schema(res_conn, :unauthorized) == error_response end ensure_authenticated_access(base_uri) @@ -939,7 +939,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do for local <- [true, false] do res_conn = get(conn, "#{base_uri}?local=#{local}") - assert json_response(res_conn, :unauthorized) == error_response + assert json_response_and_validate_schema(res_conn, :unauthorized) == error_response end ensure_authenticated_access(base_uri) @@ -951,10 +951,10 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do clear_config([:restrict_unauthenticated, :timelines, :federated], true) res_conn = get(conn, "#{base_uri}?local=true") - assert length(json_response(res_conn, 200)) == 1 + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 res_conn = get(conn, "#{base_uri}?local=false") - assert json_response(res_conn, :unauthorized) == error_response + assert json_response_and_validate_schema(res_conn, :unauthorized) == error_response ensure_authenticated_access(base_uri) end @@ -966,11 +966,11 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do clear_config([:restrict_unauthenticated, :timelines, :federated], false) res_conn = get(conn, "#{base_uri}?local=true") - assert json_response(res_conn, :unauthorized) == error_response + assert json_response_and_validate_schema(res_conn, :unauthorized) == error_response # Note: local activities get delivered as part of federated timeline res_conn = get(conn, "#{base_uri}?local=false") - assert length(json_response(res_conn, 200)) == 2 + assert length(json_response_and_validate_schema(res_conn, 200)) == 2 ensure_authenticated_access(base_uri) end From 3123ecdd6e7a189f815624ee78be4f62487aa3db Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Tue, 16 Feb 2021 23:37:16 +0100 Subject: [PATCH 009/373] OpenAPI: MastodonAPI Media Controller --- lib/pleroma/web/api_spec/operations/media_operation.ex | 1 + .../web/mastodon_api/controllers/media_controller_test.exs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/web/api_spec/operations/media_operation.ex b/lib/pleroma/web/api_spec/operations/media_operation.ex index 85aa14869..1e245b291 100644 --- a/lib/pleroma/web/api_spec/operations/media_operation.ex +++ b/lib/pleroma/web/api_spec/operations/media_operation.ex @@ -105,6 +105,7 @@ defmodule Pleroma.Web.ApiSpec.MediaOperation do responses: %{ 200 => Operation.response("Media", "application/json", Attachment), 401 => Operation.response("Media", "application/json", ApiError), + 403 => Operation.response("Media", "application/json", ApiError), 422 => Operation.response("Media", "application/json", ApiError) } } diff --git a/test/pleroma/web/mastodon_api/controllers/media_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/media_controller_test.exs index 6c8f984d5..39d7f99f6 100644 --- a/test/pleroma/web/mastodon_api/controllers/media_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/media_controller_test.exs @@ -140,7 +140,7 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do conn |> get("/api/v1/media/#{object.id}") - |> json_response(403) + |> json_response_and_validate_schema(403) end end end From e47f83cfc822716c00f3fcaffe73f31208749601 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Tue, 16 Feb 2021 23:39:07 +0100 Subject: [PATCH 010/373] OpenAPI: MastodonAPI Conversation Controller --- .../mastodon_api/controllers/conversation_controller_test.exs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/pleroma/web/mastodon_api/controllers/conversation_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/conversation_controller_test.exs index 3176f1296..00797a9ea 100644 --- a/test/pleroma/web/mastodon_api/controllers/conversation_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/conversation_controller_test.exs @@ -214,7 +214,8 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do res_conn = get(conn, "/api/v1/statuses/#{direct.id}/context") - assert %{"ancestors" => [], "descendants" => []} == json_response(res_conn, 200) + assert %{"ancestors" => [], "descendants" => []} == + json_response_and_validate_schema(res_conn, 200) end test "Removes a conversation", %{user: user_one, conn: conn} do From 3a8404820d803ccea44071178cc90f6aafcee80b Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Tue, 16 Feb 2021 23:40:50 +0100 Subject: [PATCH 011/373] Verify MastoFE Controller put_settings response --- test/pleroma/web/mastodon_api/masto_fe_controller_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/pleroma/web/mastodon_api/masto_fe_controller_test.exs b/test/pleroma/web/mastodon_api/masto_fe_controller_test.exs index ea66c708f..e679d781a 100644 --- a/test/pleroma/web/mastodon_api/masto_fe_controller_test.exs +++ b/test/pleroma/web/mastodon_api/masto_fe_controller_test.exs @@ -20,7 +20,7 @@ defmodule Pleroma.Web.MastodonAPI.MastoFEControllerTest do |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:accounts"])) |> put("/api/web/settings", %{"data" => %{"programming" => "socks"}}) - assert _result = json_response(conn, 200) + assert %{} = json_response(conn, 200) user = User.get_cached_by_ap_id(user.ap_id) assert user.mastofe_settings == %{"programming" => "socks"} From 0c7c6463d13b8a4471b8721912c82fe1cbe3e91a Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Wed, 17 Feb 2021 00:35:26 +0100 Subject: [PATCH 012/373] OpenAPI: MastodonAPI Account Controller, excluding OAuth --- .../controllers/account_controller_test.exs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs index a327c0d1d..3036e25b3 100644 --- a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs @@ -514,11 +514,11 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do {:ok, post_2} = CommonAPI.post(user, %{status: "second post"}) response_1 = get(conn, "/api/v1/accounts/#{user.id}/statuses?limit=1") - assert [res] = json_response(response_1, 200) + assert [res] = json_response_and_validate_schema(response_1, 200) assert res["id"] == post_2.id response_2 = get(conn, "/api/v1/accounts/#{user.id}/statuses?limit=1&max_id=#{res["id"]}") - assert [res] = json_response(response_2, 200) + assert [res] = json_response_and_validate_schema(response_2, 200) assert res["id"] == post_1.id refute response_1 == response_2 @@ -881,7 +881,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do assert [] == conn |> get("/api/v1/timelines/home") - |> json_response(200) + |> json_response_and_validate_schema(200) assert %{"showing_reblogs" => true} = conn @@ -892,7 +892,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do assert [%{"id" => ^reblog_id}] = conn |> get("/api/v1/timelines/home") - |> json_response(200) + |> json_response_and_validate_schema(200) end test "following with reblogs" do @@ -910,7 +910,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do assert [%{"id" => ^reblog_id}] = conn |> get("/api/v1/timelines/home") - |> json_response(200) + |> json_response_and_validate_schema(200) assert %{"showing_reblogs" => false} = conn @@ -921,7 +921,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do assert [] == conn |> get("/api/v1/timelines/home") - |> json_response(200) + |> json_response_and_validate_schema(200) end test "following / unfollowing errors", %{user: user, conn: conn} do From ef5de5eb398b6d4cbc1ed338f2f41d3bfa1c5fe9 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Wed, 17 Feb 2021 00:45:01 +0100 Subject: [PATCH 013/373] OpenAPI: MastodonAPI Status Controller --- .../web/mastodon_api/controllers/status_controller_test.exs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs index f616f405e..4c0149a4c 100644 --- a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs @@ -81,6 +81,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do "sensitive" => 0 }) + # Idempotency plug response means detection fail assert %{"id" => second_id} = json_response(conn_two, 200) assert id == second_id @@ -1542,7 +1543,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do |> assign(:token, insert(:oauth_token, user: user3, scopes: ["read:statuses"])) |> get("api/v1/timelines/home") - [reblogged_activity] = json_response(conn3, 200) + [reblogged_activity] = json_response_and_validate_schema(conn3, 200) assert reblogged_activity["reblog"]["in_reply_to_id"] == replied_to.id @@ -1896,7 +1897,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do local = Pleroma.Constants.as_local_public() assert %{"content" => "cofe", "id" => id, "visibility" => "local"} = - json_response(conn_one, 200) + json_response_and_validate_schema(conn_one, 200) assert %Activity{id: ^id, data: %{"to" => [^local]}} = Activity.get_by_id(id) end From e4743847a18cb7cbb9e607232f25eb1cf63a4551 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Wed, 17 Feb 2021 01:07:56 +0100 Subject: [PATCH 014/373] OpenAPI: PleromaAPI UserImport Controller --- lib/pleroma/web/api_spec/operations/user_import_operation.ex | 1 + .../web/pleroma_api/controllers/user_import_controller_test.exs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/web/api_spec/operations/user_import_operation.ex b/lib/pleroma/web/api_spec/operations/user_import_operation.ex index 6292e2004..8df19f1fc 100644 --- a/lib/pleroma/web/api_spec/operations/user_import_operation.ex +++ b/lib/pleroma/web/api_spec/operations/user_import_operation.ex @@ -23,6 +23,7 @@ defmodule Pleroma.Web.ApiSpec.UserImportOperation do requestBody: request_body("Parameters", import_request(), required: true), responses: %{ 200 => ok_response(), + 403 => Operation.response("Error", "application/json", ApiError), 500 => Operation.response("Error", "application/json", ApiError) }, security: [%{"oAuth" => ["write:follow"]}] diff --git a/test/pleroma/web/pleroma_api/controllers/user_import_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/user_import_controller_test.exs index 25a7f8374..d977bc3a2 100644 --- a/test/pleroma/web/pleroma_api/controllers/user_import_controller_test.exs +++ b/test/pleroma/web/pleroma_api/controllers/user_import_controller_test.exs @@ -83,7 +83,7 @@ defmodule Pleroma.Web.PleromaAPI.UserImportControllerTest do assert %{"error" => "Insufficient permissions: follow | write:follows."} == json_response(conn, 403) else - assert json_response(conn, 200) + assert json_response_and_validate_schema(conn, 200) end end end From a22c53810b36c5382c805e1c5ed7e1cf3d747ebc Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Wed, 17 Feb 2021 01:19:25 +0100 Subject: [PATCH 015/373] Remove deprecated /api/qvitter/statuses/notifications/read --- CHANGELOG.md | 3 ++ lib/pleroma/web/router.ex | 6 --- lib/pleroma/web/twitter_api/controller.ex | 33 ------------- .../web/twitter_api/controller_test.exs | 49 ------------------- 4 files changed, 3 insertions(+), 88 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50484aaef..ce0bb1cb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - The `application` metadata returned with statuses is no longer hardcoded. Apps that want to display these details will now have valid data for new posts after this change. +### Removed +- **Breaking**: Remove deprecated `/api/qvitter/statuses/notifications/read` (replaced by `/api/v1/pleroma/notifications/read`) + ## Unreleased (Patch) ## [2.3.0] - 2020-03-01 diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index de0bd27d7..ce2d701d7 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -620,12 +620,6 @@ defmodule Pleroma.Web.Router do get("/oauth_tokens", TwitterAPI.Controller, :oauth_tokens) delete("/oauth_tokens/:id", TwitterAPI.Controller, :revoke_token) - - post( - "/qvitter/statuses/notifications/read", - TwitterAPI.Controller, - :mark_notifications_as_read - ) end scope "/", Pleroma.Web do diff --git a/lib/pleroma/web/twitter_api/controller.ex b/lib/pleroma/web/twitter_api/controller.ex index 077bfa70d..e32713311 100644 --- a/lib/pleroma/web/twitter_api/controller.ex +++ b/lib/pleroma/web/twitter_api/controller.ex @@ -5,7 +5,6 @@ defmodule Pleroma.Web.TwitterAPI.Controller do use Pleroma.Web, :controller - alias Pleroma.Notification alias Pleroma.User alias Pleroma.Web.OAuth.Token alias Pleroma.Web.Plugs.EnsurePublicOrAuthenticatedPlug @@ -14,11 +13,6 @@ defmodule Pleroma.Web.TwitterAPI.Controller do require Logger - plug( - OAuthScopesPlug, - %{scopes: ["write:notifications"]} when action == :mark_notifications_as_read - ) - plug( :skip_plug, [OAuthScopesPlug, EnsurePublicOrAuthenticatedPlug] when action == :confirm_email @@ -67,31 +61,4 @@ defmodule Pleroma.Web.TwitterAPI.Controller do |> put_resp_content_type("application/json") |> send_resp(status, json) end - - def mark_notifications_as_read( - %{assigns: %{user: user}} = conn, - %{"latest_id" => latest_id} = params - ) do - Notification.set_read_up_to(user, latest_id) - - notifications = Notification.for_user(user, params) - - conn - # XXX: This is a hack because pleroma-fe still uses that API. - |> put_view(Pleroma.Web.MastodonAPI.NotificationView) - |> render("index.json", %{notifications: notifications, for: user}) - end - - def mark_notifications_as_read(%{assigns: %{user: _user}} = conn, _) do - bad_request_reply(conn, "You need to specify latest_id") - end - - defp bad_request_reply(conn, error_message) do - json = error_json(conn, error_message) - json_reply(conn, 400, json) - end - - defp error_json(conn, error_message) do - %{"error" => error_message, "request" => conn.request_path} |> Jason.encode!() - end end diff --git a/test/pleroma/web/twitter_api/controller_test.exs b/test/pleroma/web/twitter_api/controller_test.exs index 583c904b2..bca9e2dad 100644 --- a/test/pleroma/web/twitter_api/controller_test.exs +++ b/test/pleroma/web/twitter_api/controller_test.exs @@ -7,59 +7,10 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do alias Pleroma.Repo alias Pleroma.User - alias Pleroma.Web.CommonAPI alias Pleroma.Web.OAuth.Token import Pleroma.Factory - describe "POST /api/qvitter/statuses/notifications/read" do - test "without valid credentials", %{conn: conn} do - conn = post(conn, "/api/qvitter/statuses/notifications/read", %{"latest_id" => 1_234_567}) - assert json_response(conn, 403) == %{"error" => "Invalid credentials."} - end - - test "with credentials, without any params" do - %{conn: conn} = oauth_access(["write:notifications"]) - - conn = post(conn, "/api/qvitter/statuses/notifications/read") - - assert json_response(conn, 400) == %{ - "error" => "You need to specify latest_id", - "request" => "/api/qvitter/statuses/notifications/read" - } - end - - test "with credentials, with params" do - %{user: current_user, conn: conn} = - oauth_access(["read:notifications", "write:notifications"]) - - other_user = insert(:user) - - {:ok, _activity} = - CommonAPI.post(other_user, %{ - status: "Hey @#{current_user.nickname}" - }) - - response_conn = - conn - |> get("/api/v1/notifications") - - [notification] = json_response(response_conn, 200) - - assert notification["pleroma"]["is_seen"] == false - - response_conn = - conn - |> post("/api/qvitter/statuses/notifications/read", %{"latest_id" => notification["id"]}) - - [notification] = response = json_response(response_conn, 200) - - assert length(response) == 1 - - assert notification["pleroma"]["is_seen"] == true - end - end - describe "GET /api/account/confirm_email/:id/:token" do setup do {:ok, user} = From 65cd9cb6384676c1660aa7f4da0f98ff7f43b999 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Wed, 17 Feb 2021 09:41:40 +0100 Subject: [PATCH 016/373] TwitterAPI: Remove unused read notification function --- .../web/twitter_api/controllers/util_controller.ex | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index 940a645bb..60266aaab 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -10,7 +10,6 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do alias Pleroma.Config alias Pleroma.Emoji alias Pleroma.Healthcheck - alias Pleroma.Notification alias Pleroma.User alias Pleroma.Web.CommonAPI alias Pleroma.Web.Plugs.OAuthScopesPlug @@ -30,7 +29,6 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do ] ) - plug(OAuthScopesPlug, %{scopes: ["write:notifications"]} when action == :notifications_read) def remote_subscribe(conn, %{"nickname" => nick, "profile" => _}) do with %User{} = user <- User.get_cached_by_nickname(nick), @@ -62,17 +60,6 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do end end - def notifications_read(%{assigns: %{user: user}} = conn, %{"id" => notification_id}) do - with {:ok, _} <- Notification.read_one(user, notification_id) do - json(conn, %{status: "success"}) - else - {:error, message} -> - conn - |> put_resp_content_type("application/json") - |> send_resp(403, Jason.encode!(%{"error" => message})) - end - end - def frontend_configurations(conn, _params) do render(conn, "frontend_configurations.json") end From 55bdfb075c1cc5226948e3ff9d39fdae27aa9257 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Wed, 24 Feb 2021 23:40:33 +0100 Subject: [PATCH 017/373] OpenAPI: TwitterAPI Util Controller --- .../operations/twitter_util_operation.ex | 219 ++++++++++++++++++ .../controllers/util_controller.ex | 24 +- .../web/twitter_api/util_controller_test.exs | 204 +++++++++------- 3 files changed, 360 insertions(+), 87 deletions(-) create mode 100644 lib/pleroma/web/api_spec/operations/twitter_util_operation.ex diff --git a/lib/pleroma/web/api_spec/operations/twitter_util_operation.ex b/lib/pleroma/web/api_spec/operations/twitter_util_operation.ex new file mode 100644 index 000000000..62c9826f6 --- /dev/null +++ b/lib/pleroma/web/api_spec/operations/twitter_util_operation.ex @@ -0,0 +1,219 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2021 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do + alias OpenApiSpex.Operation + alias OpenApiSpex.Schema + alias Pleroma.Web.ApiSpec.Schemas.ApiError + alias Pleroma.Web.ApiSpec.Schemas.BooleanLike + + def open_api_operation(action) do + operation = String.to_existing_atom("#{action}_operation") + apply(__MODULE__, operation, []) + end + + def emoji_operation do + %Operation{ + tags: ["Emojis"], + summary: "List all custom emojis", + operationId: "UtilController.emoji", + parameters: [], + responses: %{ + 200 => + Operation.response("List", "application/json", %Schema{ + type: :object, + additionalProperties: %Schema{ + type: :object, + properties: %{ + image_url: %Schema{type: :string}, + tags: %Schema{type: :array, items: %Schema{type: :string}} + } + }, + example: %{ + "firefox" => %{ + "image_url" => "/emoji/firefox.png", + "tag" => ["Fun"] + } + } + }) + } + } + end + + def frontend_configurations_operation do + %Operation{ + tags: ["Configuration"], + summary: "Dump frontend configurations", + operationId: "UtilController.frontend_configurations", + parameters: [], + responses: %{ + 200 => + Operation.response("List", "application/json", %Schema{ + type: :object, + additionalProperties: %Schema{type: :object} + }) + } + } + end + + def change_password_operation do + %Operation{ + tags: ["Accounts"], + summary: "Change account password", + security: [%{"oAuth" => ["write:accounts"]}], + operationId: "UtilController.change_password", + parameters: [ + Operation.parameter(:password, :query, :string, "Current password", required: true), + Operation.parameter(:new_password, :query, :string, "New password", required: true), + Operation.parameter( + :new_password_confirmation, + :query, + :string, + "New password, confirmation", + required: true + ) + ], + responses: %{ + 200 => + Operation.response("Success", "application/json", %Schema{ + type: :object, + properties: %{status: %Schema{type: :string, example: "success"}} + }), + 400 => Operation.response("Error", "application/json", ApiError), + 403 => Operation.response("Error", "application/json", ApiError) + } + } + end + + def change_email_operation do + %Operation{ + tags: ["Accounts"], + summary: "Change account email", + security: [%{"oAuth" => ["write:accounts"]}], + operationId: "UtilController.change_email", + parameters: [ + Operation.parameter(:password, :query, :string, "Current password", required: true), + Operation.parameter(:email, :query, :string, "New email", required: true) + ], + requestBody: nil, + responses: %{ + 200 => + Operation.response("Success", "application/json", %Schema{ + type: :object, + properties: %{status: %Schema{type: :string, example: "success"}} + }), + 400 => Operation.response("Error", "application/json", ApiError), + 403 => Operation.response("Error", "application/json", ApiError) + } + } + end + + def update_notificaton_settings_operation do + %Operation{ + tags: ["Accounts"], + summary: "Update Notification Settings", + security: [%{"oAuth" => ["write:accounts"]}], + operationId: "UtilController.update_notificaton_settings", + parameters: [ + Operation.parameter( + :block_from_strangers, + :query, + BooleanLike, + "blocks notifications from accounts you do not follow" + ), + Operation.parameter( + :hide_notification_contents, + :query, + BooleanLike, + "removes the contents of a message from the push notification" + ) + ], + requestBody: nil, + responses: %{ + 200 => + Operation.response("Success", "application/json", %Schema{ + type: :object, + properties: %{status: %Schema{type: :string, example: "success"}} + }), + 400 => Operation.response("Error", "application/json", ApiError) + } + } + end + + def disable_account_operation do + %Operation{ + tags: ["Accounts"], + summary: "Disable Account", + security: [%{"oAuth" => ["write:accounts"]}], + operationId: "UtilController.disable_account", + parameters: [ + Operation.parameter(:password, :query, :string, "Password") + ], + responses: %{ + 200 => + Operation.response("Success", "application/json", %Schema{ + type: :object, + properties: %{status: %Schema{type: :string, example: "success"}} + }), + 403 => Operation.response("Error", "application/json", ApiError) + } + } + end + + def delete_account_operation do + %Operation{ + tags: ["Accounts"], + summary: "Delete Account", + security: [%{"oAuth" => ["write:accounts"]}], + operationId: "UtilController.delete_account", + parameters: [ + Operation.parameter(:password, :query, :string, "Password") + ], + responses: %{ + 200 => + Operation.response("Success", "application/json", %Schema{ + type: :object, + properties: %{status: %Schema{type: :string, example: "success"}} + }), + 403 => Operation.response("Error", "application/json", ApiError) + } + } + end + + def captcha_operation do + %Operation{ + summary: "Get a captcha", + operationId: "UtilController.captcha", + parameters: [], + responses: %{ + 200 => Operation.response("Success", "application/json", %Schema{type: :object}) + } + } + end + + def healthcheck_operation do + %Operation{ + tags: ["Accounts"], + summary: "Disable Account", + security: [%{"oAuth" => ["write:accounts"]}], + operationId: "UtilController.healthcheck", + parameters: [], + responses: %{ + 200 => Operation.response("Healthy", "application/json", %Schema{type: :object}), + 503 => + Operation.response("Disabled or Unhealthy", "application/json", %Schema{type: :object}) + } + } + end + + def remote_subscribe_operation do + %Operation{ + tags: ["Accounts"], + summary: "Remote Subscribe", + operationId: "UtilController.remote_subscribe", + parameters: [], + responses: %{200 => Operation.response("Web Page", "test/html", %Schema{type: :string})} + } + end +end diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index 60266aaab..a2e69666e 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -15,6 +15,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do alias Pleroma.Web.Plugs.OAuthScopesPlug alias Pleroma.Web.WebFinger + plug(Pleroma.Web.ApiSpec.CastAndValidate when action != :remote_subscribe) plug(Pleroma.Web.Plugs.FederatingPlug when action == :remote_subscribe) plug( @@ -29,6 +30,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do ] ) + defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.TwitterUtilOperation def remote_subscribe(conn, %{"nickname" => nick, "profile" => _}) do with %User{} = user <- User.get_cached_by_nickname(nick), @@ -79,13 +81,17 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do end end - def change_password(%{assigns: %{user: user}} = conn, params) do - case CommonAPI.Utils.confirm_current_password(user, params["password"]) do + def change_password(%{assigns: %{user: user}} = conn, %{ + password: password, + new_password: new_password, + new_password_confirmation: new_password_confirmation + }) do + case CommonAPI.Utils.confirm_current_password(user, password) do {:ok, user} -> with {:ok, _user} <- User.reset_password(user, %{ - password: params["new_password"], - password_confirmation: params["new_password_confirmation"] + password: new_password, + password_confirmation: new_password_confirmation }) do json(conn, %{status: "success"}) else @@ -102,10 +108,10 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do end end - def change_email(%{assigns: %{user: user}} = conn, params) do - case CommonAPI.Utils.confirm_current_password(user, params["password"]) do + def change_email(%{assigns: %{user: user}} = conn, %{password: password, email: email}) do + case CommonAPI.Utils.confirm_current_password(user, password) do {:ok, user} -> - with {:ok, _user} <- User.change_email(user, params["email"]) do + with {:ok, _user} <- User.change_email(user, email) do json(conn, %{status: "success"}) else {:error, changeset} -> @@ -122,7 +128,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do end def delete_account(%{assigns: %{user: user}} = conn, params) do - password = params["password"] || "" + password = params[:password] || "" case CommonAPI.Utils.confirm_current_password(user, password) do {:ok, user} -> @@ -135,7 +141,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do end def disable_account(%{assigns: %{user: user}} = conn, params) do - case CommonAPI.Utils.confirm_current_password(user, params["password"]) do + case CommonAPI.Utils.confirm_current_password(user, params[:password]) do {:ok, user} -> User.set_activation_async(user, false) json(conn, %{status: "success"}) diff --git a/test/pleroma/web/twitter_api/util_controller_test.exs b/test/pleroma/web/twitter_api/util_controller_test.exs index bdbc478c3..cc17940b5 100644 --- a/test/pleroma/web/twitter_api/util_controller_test.exs +++ b/test/pleroma/web/twitter_api/util_controller_test.exs @@ -25,11 +25,14 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do test "it updates notification settings", %{user: user, conn: conn} do conn - |> put("/api/pleroma/notification_settings", %{ - "block_from_strangers" => true, - "bar" => 1 - }) - |> json_response(:ok) + |> put( + "/api/pleroma/notification_settings?#{ + URI.encode_query(%{ + block_from_strangers: true + }) + }" + ) + |> json_response_and_validate_schema(:ok) user = refresh_record(user) @@ -41,8 +44,14 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do test "it updates notification settings to enable hiding contents", %{user: user, conn: conn} do conn - |> put("/api/pleroma/notification_settings", %{"hide_notification_contents" => "1"}) - |> json_response(:ok) + |> put( + "/api/pleroma/notification_settings?#{ + URI.encode_query(%{ + hide_notification_contents: 1 + }) + }" + ) + |> json_response_and_validate_schema(:ok) user = refresh_record(user) @@ -70,7 +79,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do response = conn |> get("/api/pleroma/frontend_configurations") - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) assert response == Jason.encode!(config |> Enum.into(%{})) |> Jason.decode!() end @@ -81,7 +90,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do emoji = conn |> get("/api/pleroma/emoji") - |> json_response(200) + |> json_response_and_validate_schema(200) assert Enum.all?(emoji, fn {_key, @@ -103,7 +112,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do response = conn |> get("/api/pleroma/healthcheck") - |> json_response(503) + |> json_response_and_validate_schema(503) assert response == %{} end @@ -116,7 +125,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do response = conn |> get("/api/pleroma/healthcheck") - |> json_response(200) + |> json_response_and_validate_schema(200) assert %{ "active" => _, @@ -136,7 +145,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do response = conn |> get("/api/pleroma/healthcheck") - |> json_response(503) + |> json_response_and_validate_schema(503) assert %{ "active" => _, @@ -155,8 +164,8 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do test "with valid permissions and password, it disables the account", %{conn: conn, user: user} do response = conn - |> post("/api/pleroma/disable_account", %{"password" => "test"}) - |> json_response(:ok) + |> post("/api/pleroma/disable_account?password=test") + |> json_response_and_validate_schema(:ok) assert response == %{"status" => "success"} ObanHelpers.perform_all() @@ -171,8 +180,8 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do response = conn - |> post("/api/pleroma/disable_account", %{"password" => "test1"}) - |> json_response(:ok) + |> post("/api/pleroma/disable_account?password=test1") + |> json_response_and_validate_schema(:ok) assert response == %{"error" => "Invalid password."} user = User.get_cached_by_id(user.id) @@ -252,54 +261,61 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do conn = conn |> assign(:token, nil) - |> post("/api/pleroma/change_email") + |> post( + "/api/pleroma/change_email?#{ + URI.encode_query(%{password: "hi", email: "test@test.com"}) + }" + ) - assert json_response(conn, 403) == %{"error" => "Insufficient permissions: write:accounts."} + assert json_response_and_validate_schema(conn, 403) == %{ + "error" => "Insufficient permissions: write:accounts." + } end test "with proper permissions and invalid password", %{conn: conn} do conn = - post(conn, "/api/pleroma/change_email", %{ - "password" => "hi", - "email" => "test@test.com" - }) + post( + conn, + "/api/pleroma/change_email?#{ + URI.encode_query(%{password: "hi", email: "test@test.com"}) + }" + ) - assert json_response(conn, 200) == %{"error" => "Invalid password."} + assert json_response_and_validate_schema(conn, 200) == %{"error" => "Invalid password."} end test "with proper permissions, valid password and invalid email", %{ conn: conn } do conn = - post(conn, "/api/pleroma/change_email", %{ - "password" => "test", - "email" => "foobar" - }) + post( + conn, + "/api/pleroma/change_email?#{URI.encode_query(%{password: "test", email: "foobar"})}" + ) - assert json_response(conn, 200) == %{"error" => "Email has invalid format."} + assert json_response_and_validate_schema(conn, 200) == %{ + "error" => "Email has invalid format." + } end test "with proper permissions, valid password and no email", %{ conn: conn } do - conn = - post(conn, "/api/pleroma/change_email", %{ - "password" => "test" - }) + conn = post(conn, "/api/pleroma/change_email?#{URI.encode_query(%{password: "test"})}") - assert json_response(conn, 200) == %{"error" => "Email can't be blank."} + assert %{"error" => "Missing field: email."} = json_response_and_validate_schema(conn, 400) end test "with proper permissions, valid password and blank email", %{ conn: conn } do conn = - post(conn, "/api/pleroma/change_email", %{ - "password" => "test", - "email" => "" - }) + post( + conn, + "/api/pleroma/change_email?#{URI.encode_query(%{password: "test", email: ""})}" + ) - assert json_response(conn, 200) == %{"error" => "Email can't be blank."} + assert json_response_and_validate_schema(conn, 200) == %{"error" => "Email can't be blank."} end test "with proper permissions, valid password and non unique email", %{ @@ -308,24 +324,28 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do user = insert(:user) conn = - post(conn, "/api/pleroma/change_email", %{ - "password" => "test", - "email" => user.email - }) + post( + conn, + "/api/pleroma/change_email?#{URI.encode_query(%{password: "test", email: user.email})}" + ) - assert json_response(conn, 200) == %{"error" => "Email has already been taken."} + assert json_response_and_validate_schema(conn, 200) == %{ + "error" => "Email has already been taken." + } end test "with proper permissions, valid password and valid email", %{ conn: conn } do conn = - post(conn, "/api/pleroma/change_email", %{ - "password" => "test", - "email" => "cofe@foobar.com" - }) + post( + conn, + "/api/pleroma/change_email?#{ + URI.encode_query(%{password: "test", email: "cofe@foobar.com"}) + }" + ) - assert json_response(conn, 200) == %{"status" => "success"} + assert json_response_and_validate_schema(conn, 200) == %{"status" => "success"} end end @@ -336,20 +356,35 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do conn = conn |> assign(:token, nil) - |> post("/api/pleroma/change_password") + |> post( + "/api/pleroma/change_password?#{ + URI.encode_query(%{ + password: "hi", + new_password: "newpass", + new_password_confirmation: "newpass" + }) + }" + ) - assert json_response(conn, 403) == %{"error" => "Insufficient permissions: write:accounts."} + assert json_response_and_validate_schema(conn, 403) == %{ + "error" => "Insufficient permissions: write:accounts." + } end test "with proper permissions and invalid password", %{conn: conn} do conn = - post(conn, "/api/pleroma/change_password", %{ - "password" => "hi", - "new_password" => "newpass", - "new_password_confirmation" => "newpass" - }) + post( + conn, + "/api/pleroma/change_password?#{ + URI.encode_query(%{ + password: "hi", + new_password: "newpass", + new_password_confirmation: "newpass" + }) + }" + ) - assert json_response(conn, 200) == %{"error" => "Invalid password."} + assert json_response_and_validate_schema(conn, 200) == %{"error" => "Invalid password."} end test "with proper permissions, valid password and new password and confirmation not matching", @@ -357,13 +392,18 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do conn: conn } do conn = - post(conn, "/api/pleroma/change_password", %{ - "password" => "test", - "new_password" => "newpass", - "new_password_confirmation" => "notnewpass" - }) + post( + conn, + "/api/pleroma/change_password?#{ + URI.encode_query(%{ + password: "test", + new_password: "newpass", + new_password_confirmation: "notnewpass" + }) + }" + ) - assert json_response(conn, 200) == %{ + assert json_response_and_validate_schema(conn, 200) == %{ "error" => "New password does not match confirmation." } end @@ -372,13 +412,14 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do conn: conn } do conn = - post(conn, "/api/pleroma/change_password", %{ - "password" => "test", - "new_password" => "", - "new_password_confirmation" => "" - }) + post( + conn, + "/api/pleroma/change_password?#{ + URI.encode_query(%{password: "test", new_password: "", new_password_confirmation: ""}) + }" + ) - assert json_response(conn, 200) == %{ + assert json_response_and_validate_schema(conn, 200) == %{ "error" => "New password can't be blank." } end @@ -388,13 +429,18 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do user: user } do conn = - post(conn, "/api/pleroma/change_password", %{ - "password" => "test", - "new_password" => "newpass", - "new_password_confirmation" => "newpass" - }) + post( + conn, + "/api/pleroma/change_password?#{ + URI.encode_query(%{ + password: "test", + new_password: "newpass", + new_password_confirmation: "newpass" + }) + }" + ) - assert json_response(conn, 200) == %{"status" => "success"} + assert json_response_and_validate_schema(conn, 200) == %{"status" => "success"} fetched_user = User.get_cached_by_id(user.id) assert Pleroma.Password.Pbkdf2.verify_pass("newpass", fetched_user.password_hash) == true end @@ -409,7 +455,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do |> assign(:token, nil) |> post("/api/pleroma/delete_account") - assert json_response(conn, 403) == + assert json_response_and_validate_schema(conn, 403) == %{"error" => "Insufficient permissions: write:accounts."} end @@ -417,14 +463,16 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do for params <- [%{"password" => "hi"}, %{}] do ret_conn = post(conn, "/api/pleroma/delete_account", params) - assert json_response(ret_conn, 200) == %{"error" => "Invalid password."} + assert json_response_and_validate_schema(ret_conn, 200) == %{ + "error" => "Invalid password." + } end end test "with proper permissions and valid password", %{conn: conn, user: user} do - conn = post(conn, "/api/pleroma/delete_account", %{"password" => "test"}) + conn = post(conn, "/api/pleroma/delete_account?password=test") ObanHelpers.perform_all() - assert json_response(conn, 200) == %{"status" => "success"} + assert json_response_and_validate_schema(conn, 200) == %{"status" => "success"} user = User.get_by_id(user.id) refute user.is_active From e56779dd8d1668177afa199aaa836bea70e68420 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Thu, 10 Sep 2020 11:09:11 +0200 Subject: [PATCH 018/373] Transmogrifier: Simplify fix_explicit_addressing and fix_implicit_addressing --- .../web/activity_pub/transmogrifier.ex | 51 ++++++------------- .../web/activity_pub/transmogrifier_test.exs | 6 +-- 2 files changed, 19 insertions(+), 38 deletions(-) diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 4070ed14d..047f23918 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -72,17 +72,21 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end end - def fix_explicit_addressing( - %{"to" => to, "cc" => cc} = object, - explicit_mentions, - follower_collection - ) do - explicit_to = Enum.filter(to, fn x -> x in explicit_mentions end) + # if directMessage flag is set to true, leave the addressing alone + def fix_explicit_addressing(%{"directMessage" => true} = object, _follower_collection), + do: object + def fix_explicit_addressing(%{"to" => to, "cc" => cc} = object, follower_collection) do + explicit_mentions = + Utils.determine_explicit_mentions(object) ++ + [Pleroma.Constants.as_public(), follower_collection] + + explicit_to = Enum.filter(to, fn x -> x in explicit_mentions end) explicit_cc = Enum.filter(to, fn x -> x not in explicit_mentions end) final_cc = (cc ++ explicit_cc) + |> Enum.filter(& &1) |> Enum.reject(fn x -> String.ends_with?(x, "/followers") and x != follower_collection end) |> Enum.uniq() @@ -91,29 +95,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do |> Map.put("cc", final_cc) end - def fix_explicit_addressing(object, _explicit_mentions, _followers_collection), do: object - - # if directMessage flag is set to true, leave the addressing alone - def fix_explicit_addressing(%{"directMessage" => true} = object), do: object - - def fix_explicit_addressing(object) do - explicit_mentions = Utils.determine_explicit_mentions(object) - - %User{follower_address: follower_collection} = - object - |> Containment.get_actor() - |> User.get_cached_by_ap_id() - - explicit_mentions = - explicit_mentions ++ - [ - Pleroma.Constants.as_public(), - follower_collection - ] - - fix_explicit_addressing(object, explicit_mentions, follower_collection) - end - # if as:Public is addressed, then make sure the followers collection is also addressed # so that the activities will be delivered to local users. def fix_implicit_addressing(%{"to" => to, "cc" => cc} = object, followers_collection) do @@ -137,19 +118,19 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end end - def fix_implicit_addressing(object, _), do: object - def fix_addressing(object) do - {:ok, %User{} = user} = User.get_or_fetch_by_ap_id(object["actor"]) - followers_collection = User.ap_followers(user) + {:ok, %User{follower_address: follower_collection}} = + object + |> Containment.get_actor() + |> User.get_or_fetch_by_ap_id() object |> fix_addressing_list("to") |> fix_addressing_list("cc") |> fix_addressing_list("bto") |> fix_addressing_list("bcc") - |> fix_explicit_addressing() - |> fix_implicit_addressing(followers_collection) + |> fix_explicit_addressing(follower_collection) + |> fix_implicit_addressing(follower_collection) end def fix_actor(%{"attributedTo" => actor} = object) do diff --git a/test/pleroma/web/activity_pub/transmogrifier_test.exs b/test/pleroma/web/activity_pub/transmogrifier_test.exs index 4c3fcb44a..bb0b58e4d 100644 --- a/test/pleroma/web/activity_pub/transmogrifier_test.exs +++ b/test/pleroma/web/activity_pub/transmogrifier_test.exs @@ -446,7 +446,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do end) } - fixed_object = Transmogrifier.fix_explicit_addressing(object) + fixed_object = Transmogrifier.fix_explicit_addressing(object, user.follower_address) assert Enum.all?(explicitly_mentioned_actors, &(&1 in fixed_object["to"])) refute "https://social.beepboop.ga/users/dirb" in fixed_object["to"] assert "https://social.beepboop.ga/users/dirb" in fixed_object["cc"] @@ -459,7 +459,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do "cc" => [] } - fixed_object = Transmogrifier.fix_explicit_addressing(object) + fixed_object = Transmogrifier.fix_explicit_addressing(object, user.follower_address) assert user.follower_address in fixed_object["to"] refute user.follower_address in fixed_object["cc"] end @@ -473,7 +473,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do "cc" => [user.follower_address, recipient.follower_address] } - fixed_object = Transmogrifier.fix_explicit_addressing(object) + fixed_object = Transmogrifier.fix_explicit_addressing(object, user.follower_address) assert user.follower_address in fixed_object["cc"] refute recipient.follower_address in fixed_object["cc"] From e2a3365b5ce86293a5fed28c06b2e7d9dd97c9d1 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Thu, 10 Sep 2020 11:08:05 +0200 Subject: [PATCH 019/373] ObjectValidator.CommonFixes: Introduce fix_objects_defaults and fix_activity_defaults --- .../object_validators/recipients.ex | 22 +++++++++------ .../article_note_validator.ex | 3 +- .../audio_video_validator.ex | 3 +- .../object_validators/common_fixes.ex | 28 +++++++++++++++---- .../create_generic_validator.ex | 12 +------- .../object_validators/event_validator.ex | 4 +-- .../object_validators/question_validator.ex | 4 +-- .../object_validators/recipients_test.exs | 2 +- .../transmogrifier/audio_handling_test.exs | 6 +++- .../transmogrifier/event_handling_test.exs | 2 +- 10 files changed, 50 insertions(+), 36 deletions(-) diff --git a/lib/pleroma/ecto_type/activity_pub/object_validators/recipients.ex b/lib/pleroma/ecto_type/activity_pub/object_validators/recipients.ex index af4b0e527..b76547e75 100644 --- a/lib/pleroma/ecto_type/activity_pub/object_validators/recipients.ex +++ b/lib/pleroma/ecto_type/activity_pub/object_validators/recipients.ex @@ -15,19 +15,23 @@ defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.Recipients do def cast(data) when is_list(data) do data - |> Enum.reduce_while({:ok, []}, fn element, {:ok, list} -> - case ObjectID.cast(element) do - {:ok, id} -> - {:cont, {:ok, [id | list]}} + |> Enum.reduce_while({:ok, []}, fn + nil, {:ok, list} -> + {:cont, {:ok, list}} - _ -> - {:halt, :error} - end + element, {:ok, list} -> + case ObjectID.cast(element) do + {:ok, id} -> + {:cont, {:ok, [id | list]}} + + _ -> + {:halt, {:error, element}} + end end) end - def cast(_) do - :error + def cast(data) do + {:error, data} end def dump(data) do diff --git a/lib/pleroma/web/activity_pub/object_validators/article_note_validator.ex b/lib/pleroma/web/activity_pub/object_validators/article_note_validator.ex index 39ef6dc29..d2026b5ea 100644 --- a/lib/pleroma/web/activity_pub/object_validators/article_note_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/article_note_validator.ex @@ -79,9 +79,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNoteValidator do defp fix(data) do data - |> CommonFixes.fix_defaults() - |> CommonFixes.fix_attribution() |> CommonFixes.fix_actor() + |> CommonFixes.fix_object_defaults() |> fix_url() |> Transmogrifier.fix_emoji() end diff --git a/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex b/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex index 8a5a60526..8ee432947 100644 --- a/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex @@ -120,9 +120,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioVideoValidator do defp fix(data) do data - |> CommonFixes.fix_defaults() - |> CommonFixes.fix_attribution() |> CommonFixes.fix_actor() + |> CommonFixes.fix_object_defaults() |> Transmogrifier.fix_emoji() |> fix_url() |> fix_content() diff --git a/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex b/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex index 5f2c633bc..950eb1494 100644 --- a/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex +++ b/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex @@ -3,26 +3,44 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do + alias Pleroma.EctoType.ActivityPub.ObjectValidators alias Pleroma.Object.Containment + alias Pleroma.User + alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.ActivityPub.Utils - # based on Pleroma.Web.ActivityPub.Utils.lazy_put_objects_defaults - def fix_defaults(data) do + def fix_object_defaults(data) do %{data: %{"id" => context}, id: context_id} = Utils.create_context(data["context"] || data["conversation"]) + %User{follower_address: follower_collection} = User.get_cached_by_ap_id(data["attributedTo"]) + {:ok, to} = ObjectValidators.Recipients.cast(data["to"] || []) + {:ok, cc} = ObjectValidators.Recipients.cast(data["cc"] || []) + data |> Map.put("context", context) |> Map.put("context_id", context_id) + |> Map.put("to", to) + |> Map.put("cc", cc) + |> Transmogrifier.fix_explicit_addressing(follower_collection) + |> Transmogrifier.fix_implicit_addressing(follower_collection) end - def fix_attribution(data) do + def fix_activity_defaults(data, meta) do + object = meta[:object_data] || %{} + data - |> Map.put_new("actor", data["attributedTo"]) + |> Map.put_new("to", object["to"] || []) + |> Map.put_new("cc", object["cc"] || []) + |> Map.put_new("bto", object["bto"] || []) + |> Map.put_new("bcc", object["bcc"] || []) end def fix_actor(data) do - actor = Containment.get_actor(data) + actor = + data + |> Map.put_new("actor", data["attributedTo"]) + |> Containment.get_actor() data |> Map.put("actor", actor) diff --git a/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex b/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex index e06e442f4..99e8dc6c7 100644 --- a/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex @@ -62,21 +62,11 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator do end end - defp fix_addressing(data, meta) do - if object = meta[:object_data] do - data - |> Map.put_new("to", object["to"] || []) - |> Map.put_new("cc", object["cc"] || []) - else - data - end - end - defp fix(data, meta) do data |> fix_context(meta) - |> fix_addressing(meta) |> CommonFixes.fix_actor() + |> CommonFixes.fix_activity_defaults(meta) end defp validate_data(cng, meta) do diff --git a/lib/pleroma/web/activity_pub/object_validators/event_validator.ex b/lib/pleroma/web/activity_pub/object_validators/event_validator.ex index d42458ef5..fee2e997a 100644 --- a/lib/pleroma/web/activity_pub/object_validators/event_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/event_validator.ex @@ -72,8 +72,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EventValidator do defp fix(data) do data - |> CommonFixes.fix_defaults() - |> CommonFixes.fix_attribution() + |> CommonFixes.fix_actor() + |> CommonFixes.fix_object_defaults() |> Transmogrifier.fix_emoji() end diff --git a/lib/pleroma/web/activity_pub/object_validators/question_validator.ex b/lib/pleroma/web/activity_pub/object_validators/question_validator.ex index 7012e2e1d..083d08ec4 100644 --- a/lib/pleroma/web/activity_pub/object_validators/question_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/question_validator.ex @@ -83,8 +83,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do defp fix(data) do data - |> CommonFixes.fix_defaults() - |> CommonFixes.fix_attribution() + |> CommonFixes.fix_actor() + |> CommonFixes.fix_object_defaults() |> Transmogrifier.fix_emoji() |> fix_closed() end diff --git a/test/pleroma/ecto_type/activity_pub/object_validators/recipients_test.exs b/test/pleroma/ecto_type/activity_pub/object_validators/recipients_test.exs index d3a2fd13f..ce8bef39f 100644 --- a/test/pleroma/ecto_type/activity_pub/object_validators/recipients_test.exs +++ b/test/pleroma/ecto_type/activity_pub/object_validators/recipients_test.exs @@ -9,7 +9,7 @@ defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.RecipientsTest do test "it asserts that all elements of the list are object ids" do list = ["https://lain.com/users/lain", "invalid"] - assert :error == Recipients.cast(list) + assert {:error, "invalid"} == Recipients.cast(list) end test "it works with a list" do diff --git a/test/pleroma/web/activity_pub/transmogrifier/audio_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/audio_handling_test.exs index e733f167d..032ad24b5 100644 --- a/test/pleroma/web/activity_pub/transmogrifier/audio_handling_test.exs +++ b/test/pleroma/web/activity_pub/transmogrifier/audio_handling_test.exs @@ -24,6 +24,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AudioHandlingTest do "actor" => "http://mastodon.example.org/users/admin", "object" => %{ "type" => "Audio", + "to" => ["https://www.w3.org/ns/activitystreams#Public"], + "cc" => [], "id" => "http://mastodon.example.org/users/admin/listens/1234", "attributedTo" => "http://mastodon.example.org/users/admin", "title" => "lain radio episode 1", @@ -61,7 +63,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AudioHandlingTest do assert object.data["to"] == ["https://www.w3.org/ns/activitystreams#Public"] - assert object.data["cc"] == [] + assert object.data["cc"] == [ + "https://channels.tests.funkwhale.audio/federation/actors/compositions/followers" + ] assert object.data["url"] == "https://channels.tests.funkwhale.audio/library/tracks/74" diff --git a/test/pleroma/web/activity_pub/transmogrifier/event_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/event_handling_test.exs index c4879fda1..14f5f704a 100644 --- a/test/pleroma/web/activity_pub/transmogrifier/event_handling_test.exs +++ b/test/pleroma/web/activity_pub/transmogrifier/event_handling_test.exs @@ -31,7 +31,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.EventHandlingTest do ) assert object.data["to"] == ["https://www.w3.org/ns/activitystreams#Public"] - assert object.data["cc"] == [] + assert object.data["cc"] == ["https://mobilizon.org/@tcit/followers"] assert object.data["url"] == "https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39" From c9449326747f8d33357f5179e69d3024b39089a0 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Thu, 10 Sep 2020 11:11:10 +0200 Subject: [PATCH 020/373] Pipeline Ingestion: Note --- .../object_validators/recipients.ex | 25 +-- lib/pleroma/web/activity_pub/activity_pub.ex | 2 +- .../web/activity_pub/object_validator.ex | 7 +- .../article_note_validator.ex | 29 +++- .../object_validators/common_fixes.ex | 18 +- .../object_validators/common_validations.ex | 1 + .../create_note_validator.ex | 29 ---- lib/pleroma/web/activity_pub/side_effects.ex | 15 +- .../web/activity_pub/transmogrifier.ex | 12 +- lib/pleroma/web/federator.ex | 5 + .../activitypub-client-post-activity.json | 1 + test/pleroma/activity_test.exs | 4 +- .../object_validators/recipients_test.exs | 4 +- test/pleroma/notification_test.exs | 6 + .../activity_pub_controller_test.exs | 45 ++--- .../transmogrifier/note_handling_test.exs | 155 ++++++++---------- .../web/activity_pub/transmogrifier_test.exs | 4 +- test/pleroma/web/federator_test.exs | 6 +- .../static_fe/static_fe_controller_test.exs | 13 +- 19 files changed, 202 insertions(+), 179 deletions(-) delete mode 100644 lib/pleroma/web/activity_pub/object_validators/create_note_validator.ex diff --git a/lib/pleroma/ecto_type/activity_pub/object_validators/recipients.ex b/lib/pleroma/ecto_type/activity_pub/object_validators/recipients.ex index b76547e75..a03471462 100644 --- a/lib/pleroma/ecto_type/activity_pub/object_validators/recipients.ex +++ b/lib/pleroma/ecto_type/activity_pub/object_validators/recipients.ex @@ -13,20 +13,23 @@ defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.Recipients do cast([object]) end + def cast(object) when is_map(object) do + case ObjectID.cast(object) do + {:ok, data} -> {:ok, data} + _ -> :error + end + end + def cast(data) when is_list(data) do data - |> Enum.reduce_while({:ok, []}, fn - nil, {:ok, list} -> - {:cont, {:ok, list}} + |> Enum.reduce_while({:ok, []}, fn element, {:ok, list} -> + case ObjectID.cast(element) do + {:ok, id} -> + {:cont, {:ok, [id | list]}} - element, {:ok, list} -> - case ObjectID.cast(element) do - {:ok, id} -> - {:cont, {:ok, [id | list]}} - - _ -> - {:halt, {:error, element}} - end + _ -> + {:cont, {:ok, list}} + end end) end diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index efbf92c70..b74af3f3b 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -88,7 +88,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do defp increase_replies_count_if_reply(_create_data), do: :noop - @object_types ~w[ChatMessage Question Answer Audio Video Event Article] + @object_types ~w[ChatMessage Question Answer Audio Video Event Article Note] @impl true def persist(%{"type" => type} = object, meta) when type in @object_types do with {:ok, object} <- Object.create(object) do diff --git a/lib/pleroma/web/activity_pub/object_validator.ex b/lib/pleroma/web/activity_pub/object_validator.ex index 70d9a35a9..e5b35cdd4 100644 --- a/lib/pleroma/web/activity_pub/object_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validator.ex @@ -101,7 +101,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do %{"type" => "Create", "object" => %{"type" => objtype} = object} = create_activity, meta ) - when objtype in ~w[Question Answer Audio Video Event Article] do + when objtype in ~w[Question Answer Audio Video Event Article Note] do with {:ok, object_data} <- cast_and_apply(object), meta = Keyword.put(meta, :object_data, object_data |> stringify_keys), {:ok, create_activity} <- @@ -114,7 +114,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do end def validate(%{"type" => type} = object, meta) - when type in ~w[Event Question Audio Video Article] do + when type in ~w[Event Question Audio Video Article Note] do validator = case type do "Event" -> EventValidator @@ -122,6 +122,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do "Audio" -> AudioVideoValidator "Video" -> AudioVideoValidator "Article" -> ArticleNoteValidator + "Note" -> ArticleNoteValidator end with {:ok, object} <- @@ -183,7 +184,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do EventValidator.cast_and_apply(object) end - def cast_and_apply(%{"type" => "Article"} = object) do + def cast_and_apply(%{"type" => type} = object) when type in ~w[Article Note] do ArticleNoteValidator.cast_and_apply(object) end diff --git a/lib/pleroma/web/activity_pub/object_validators/article_note_validator.ex b/lib/pleroma/web/activity_pub/object_validators/article_note_validator.ex index d2026b5ea..193f85f49 100644 --- a/lib/pleroma/web/activity_pub/object_validators/article_note_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/article_note_validator.ex @@ -50,6 +50,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNoteValidator do field(:likes, {:array, ObjectValidators.ObjectID}, default: []) field(:announcements, {:array, ObjectValidators.ObjectID}, default: []) + + field(:replies, {:array, ObjectValidators.ObjectID}, default: []) end def cast_and_apply(data) do @@ -65,24 +67,39 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNoteValidator do end def cast_data(data) do - data = fix(data) - %__MODULE__{} |> changeset(data) end - defp fix_url(%{"url" => url} = data) when is_map(url) do - Map.put(data, "url", url["href"]) - end - + defp fix_url(%{"url" => url} = data) when is_bitstring(url), do: data + defp fix_url(%{"url" => url} = data) when is_map(url), do: Map.put(data, "url", url["href"]) defp fix_url(data), do: data + defp fix_tag(%{"tag" => tag} = data) when is_list(tag), do: data + defp fix_tag(%{"tag" => tag} = data) when is_map(tag), do: Map.put(data, "tag", [tag]) + defp fix_tag(data), do: Map.drop(data, ["tag"]) + + defp fix_replies(%{"replies" => %{"first" => %{"items" => replies}}} = data) + when is_list(replies), + do: Map.put(data, "replies", replies) + + defp fix_replies(%{"replies" => %{"items" => replies}} = data) when is_list(replies), + do: Map.put(data, "replies", replies) + + defp fix_replies(%{"replies" => replies} = data) when is_bitstring(replies), + do: Map.drop(data, ["replies"]) + + defp fix_replies(data), do: data + defp fix(data) do data |> CommonFixes.fix_actor() |> CommonFixes.fix_object_defaults() |> fix_url() + |> fix_tag() + |> fix_replies() |> Transmogrifier.fix_emoji() + |> Transmogrifier.fix_content_map() end def changeset(struct, data) do diff --git a/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex b/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex index 950eb1494..7309f6af2 100644 --- a/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex +++ b/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex @@ -26,14 +26,20 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do |> Transmogrifier.fix_implicit_addressing(follower_collection) end - def fix_activity_defaults(data, meta) do + defp fix_activity_recipients(activity, field, object) do + {:ok, data} = ObjectValidators.Recipients.cast(activity[field] || object[field]) + + Map.put(activity, field, data) + end + + def fix_activity_defaults(activity, meta) do object = meta[:object_data] || %{} - data - |> Map.put_new("to", object["to"] || []) - |> Map.put_new("cc", object["cc"] || []) - |> Map.put_new("bto", object["bto"] || []) - |> Map.put_new("bcc", object["bcc"] || []) + activity + |> fix_activity_recipients("to", object) + |> fix_activity_recipients("cc", object) + |> fix_activity_recipients("bto", object) + |> fix_activity_recipients("bcc", object) end def fix_actor(data) do diff --git a/lib/pleroma/web/activity_pub/object_validators/common_validations.ex b/lib/pleroma/web/activity_pub/object_validators/common_validations.ex index 093549a45..85ac07044 100644 --- a/lib/pleroma/web/activity_pub/object_validators/common_validations.ex +++ b/lib/pleroma/web/activity_pub/object_validators/common_validations.ex @@ -14,6 +14,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations do fields |> Enum.map(fn field -> get_field(cng, field) end) |> Enum.any?(fn + nil -> false [] -> false _ -> true end) diff --git a/lib/pleroma/web/activity_pub/object_validators/create_note_validator.ex b/lib/pleroma/web/activity_pub/object_validators/create_note_validator.ex deleted file mode 100644 index a85a0298c..000000000 --- a/lib/pleroma/web/activity_pub/object_validators/create_note_validator.ex +++ /dev/null @@ -1,29 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateNoteValidator do - use Ecto.Schema - - alias Pleroma.EctoType.ActivityPub.ObjectValidators - alias Pleroma.Web.ActivityPub.ObjectValidators.NoteValidator - - import Ecto.Changeset - - @primary_key false - - embedded_schema do - field(:id, ObjectValidators.ObjectID, primary_key: true) - field(:actor, ObjectValidators.ObjectID) - field(:type, :string) - field(:to, ObjectValidators.Recipients, default: []) - field(:cc, ObjectValidators.Recipients, default: []) - field(:bto, ObjectValidators.Recipients, default: []) - field(:bcc, ObjectValidators.Recipients, default: []) - embeds_one(:object, NoteValidator) - end - - def cast_data(data) do - cast(%__MODULE__{}, data, __schema__(:fields)) - end -end diff --git a/lib/pleroma/web/activity_pub/side_effects.ex b/lib/pleroma/web/activity_pub/side_effects.ex index 0b9a9f0c5..3234b9e43 100644 --- a/lib/pleroma/web/activity_pub/side_effects.ex +++ b/lib/pleroma/web/activity_pub/side_effects.ex @@ -203,6 +203,19 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do Object.increase_replies_count(in_reply_to) end + reply_depth = (meta[:depth] || 0) + 1 + + # FIXME: Force inReplyTo to replies + if Pleroma.Web.Federator.allowed_thread_distance?(reply_depth) and + object.data["replies"] != nil do + for reply_id <- object.data["replies"] do + Pleroma.Workers.RemoteFetcherWorker.enqueue("fetch_remote", %{ + "id" => reply_id, + "depth" => reply_depth + }) + end + end + ConcurrentLimiter.limit(Pleroma.Web.RichMedia.Helpers, fn -> Task.start(fn -> Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity) end) end) @@ -366,7 +379,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do end def handle_object_creation(%{"type" => objtype} = object, meta) - when objtype in ~w[Audio Video Question Event Article] do + when objtype in ~w[Audio Video Question Event Article Note] do with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do {:ok, object, meta} end diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 047f23918..28bc25363 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -404,10 +404,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do # - tags # - emoji def handle_incoming( - %{"type" => "Create", "object" => %{"type" => objtype} = object} = data, + %{"type" => "Create", "object" => %{"type" => "Page"} = object} = data, options - ) - when objtype in ~w{Note Page} do + ) do actor = Containment.get_actor(data) with nil <- Activity.get_create_by_object_ap_id(object["id"]), @@ -499,14 +498,15 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do def handle_incoming( %{"type" => "Create", "object" => %{"type" => objtype, "id" => obj_id}} = data, - _options + options ) - when objtype in ~w{Question Answer ChatMessage Audio Video Event Article} do + when objtype in ~w{Question Answer ChatMessage Audio Video Event Article Note} do data = Map.put(data, "object", strip_internal_fields(data["object"])) + options = Keyword.put(options, :local, false) with {:ok, %User{}} <- ObjectValidator.fetch_actor(data), nil <- Activity.get_create_by_object_ap_id(obj_id), - {:ok, activity, _} <- Pipeline.common_pipeline(data, local: false) do + {:ok, activity, _} <- Pipeline.common_pipeline(data, options) do {:ok, activity} else %Activity{} = activity -> {:ok, activity} diff --git a/lib/pleroma/web/federator.ex b/lib/pleroma/web/federator.ex index f5ef76d32..69cfc2d52 100644 --- a/lib/pleroma/web/federator.ex +++ b/lib/pleroma/web/federator.ex @@ -96,6 +96,11 @@ defmodule Pleroma.Web.Federator do Logger.debug("Unhandled actor #{actor}, #{inspect(e)}") {:error, e} + {:error, {:validate_object, _}} = e -> + Logger.error("Incoming AP doc validation error: #{inspect(e)}") + Logger.debug(Jason.encode!(params, pretty: true)) + e + e -> # Just drop those for now Logger.debug(fn -> "Unhandled activity\n" <> Jason.encode!(params, pretty: true) end) diff --git a/test/fixtures/activitypub-client-post-activity.json b/test/fixtures/activitypub-client-post-activity.json index c985e072b..e592081bc 100644 --- a/test/fixtures/activitypub-client-post-activity.json +++ b/test/fixtures/activitypub-client-post-activity.json @@ -3,6 +3,7 @@ "type": "Create", "object": { "type": "Note", + "to": ["https://www.w3.org/ns/activitystreams#Public"], "content": "It's a note" }, "to": ["https://www.w3.org/ns/activitystreams#Public"] diff --git a/test/pleroma/activity_test.exs b/test/pleroma/activity_test.exs index 390a06344..9911aa45c 100644 --- a/test/pleroma/activity_test.exs +++ b/test/pleroma/activity_test.exs @@ -123,7 +123,8 @@ defmodule Pleroma.ActivityTest do "type" => "Note", "content" => "find me!", "id" => "http://mastodon.example.org/users/admin/objects/1", - "attributedTo" => "http://mastodon.example.org/users/admin" + "attributedTo" => "http://mastodon.example.org/users/admin", + "to" => ["https://www.w3.org/ns/activitystreams#Public"] }, "to" => ["https://www.w3.org/ns/activitystreams#Public"] } @@ -132,6 +133,7 @@ defmodule Pleroma.ActivityTest do {:ok, japanese_activity} = Pleroma.Web.CommonAPI.post(user, %{status: "更新情報"}) {:ok, job} = Pleroma.Web.Federator.incoming_ap_doc(params) {:ok, remote_activity} = ObanHelpers.perform(job) + remote_activity = Activity.get_by_id_with_object(remote_activity.id) %{ japanese_activity: japanese_activity, diff --git a/test/pleroma/ecto_type/activity_pub/object_validators/recipients_test.exs b/test/pleroma/ecto_type/activity_pub/object_validators/recipients_test.exs index ce8bef39f..4cdafa898 100644 --- a/test/pleroma/ecto_type/activity_pub/object_validators/recipients_test.exs +++ b/test/pleroma/ecto_type/activity_pub/object_validators/recipients_test.exs @@ -6,10 +6,10 @@ defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.RecipientsTest do alias Pleroma.EctoType.ActivityPub.ObjectValidators.Recipients use Pleroma.DataCase, async: true - test "it asserts that all elements of the list are object ids" do + test "it only keeps elements that are valid object ids" do list = ["https://lain.com/users/lain", "invalid"] - assert {:error, "invalid"} == Recipients.cast(list) + assert {:ok, ["https://lain.com/users/lain"]} == Recipients.cast(list) end test "it works with a list" do diff --git a/test/pleroma/notification_test.exs b/test/pleroma/notification_test.exs index abf1b0410..85f895f0f 100644 --- a/test/pleroma/notification_test.exs +++ b/test/pleroma/notification_test.exs @@ -624,6 +624,8 @@ defmodule Pleroma.NotificationTest do "actor" => user.ap_id, "object" => %{ "type" => "Note", + "id" => Pleroma.Web.ActivityPub.Utils.generate_object_id(), + "to" => ["https://www.w3.org/ns/activitystreams#Public"], "content" => "message with a Mention tag, but no explicit tagging", "tag" => [ %{ @@ -655,6 +657,9 @@ defmodule Pleroma.NotificationTest do "actor" => user.ap_id, "object" => %{ "type" => "Note", + "id" => Pleroma.Web.ActivityPub.Utils.generate_object_id(), + "to" => ["https://www.w3.org/ns/activitystreams#Public"], + "cc" => [other_user.ap_id], "content" => "hi everyone", "attributedTo" => user.ap_id } @@ -951,6 +956,7 @@ defmodule Pleroma.NotificationTest do "cc" => [], "object" => %{ "type" => "Note", + "id" => remote_user.ap_id <> "/objects/test", "content" => "Hello!", "tag" => [ %{ diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs index 19e04d472..2de52323e 100644 --- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs @@ -539,7 +539,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do File.read!("test/fixtures/mastodon-post-activity.json") |> Jason.decode!() |> Map.put("actor", user.ap_id) - |> put_in(["object", "attridbutedTo"], user.ap_id) + |> put_in(["object", "attributedTo"], user.ap_id) conn = conn @@ -820,29 +820,34 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do assert Instances.reachable?(sender_host) end + @tag capture_log: true test "it removes all follower collections but actor's", %{conn: conn} do [actor, recipient] = insert_pair(:user) - data = - File.read!("test/fixtures/activitypub-client-post-activity.json") - |> Jason.decode!() + to = [ + recipient.ap_id, + recipient.follower_address, + "https://www.w3.org/ns/activitystreams#Public" + ] - object = Map.put(data["object"], "attributedTo", actor.ap_id) + cc = [recipient.follower_address, actor.follower_address] - data = - data - |> Map.put("id", Utils.generate_object_id()) - |> Map.put("actor", actor.ap_id) - |> Map.put("object", object) - |> Map.put("cc", [ - recipient.follower_address, - actor.follower_address - ]) - |> Map.put("to", [ - recipient.ap_id, - recipient.follower_address, - "https://www.w3.org/ns/activitystreams#Public" - ]) + data = %{ + "@context" => ["https://www.w3.org/ns/activitystreams"], + "type" => "Create", + "id" => Utils.generate_activity_id(), + "to" => to, + "cc" => cc, + "actor" => actor.ap_id, + "object" => %{ + "type" => "Note", + "to" => to, + "cc" => cc, + "content" => "It's a note", + "attributedTo" => actor.ap_id, + "id" => Utils.generate_object_id() + } + } conn |> assign(:valid_signature, true) @@ -852,7 +857,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do ObanHelpers.perform(all_enqueued(worker: ReceiverWorker)) - activity = Activity.get_by_ap_id(data["id"]) + assert activity = Activity.get_by_ap_id(data["id"]) assert activity.id assert actor.follower_address in activity.recipients diff --git a/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs index deb956410..3eeae4004 100644 --- a/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs +++ b/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs @@ -14,7 +14,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do import Mock import Pleroma.Factory - import ExUnit.CaptureLog setup_all do Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) @@ -147,9 +146,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do data |> Map.put("object", object) - assert capture_log(fn -> - {:ok, _returned_activity} = Transmogrifier.handle_incoming(data) - end) =~ "[warn] Couldn't fetch \"https://404.site/whatever\", error: nil" + assert {:ok, _returned_activity} = Transmogrifier.handle_incoming(data) end test "it does not work for deactivated users" do @@ -221,8 +218,25 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) object = Object.normalize(data["object"], fetch: false) - assert Enum.at(Object.tags(object), 2) == "moo" - assert Object.hashtags(object) == ["moo"] + assert match?( + %{ + "href" => "http://localtesting.pleroma.lol/users/lain", + "name" => "@lain@localtesting.pleroma.lol", + "type" => "Mention" + }, + Enum.at(object.data["tag"], 0) + ) + + assert match?( + %{ + "href" => "http://mastodon.example.org/tags/moo", + "name" => "#moo", + "type" => "Hashtag" + }, + Enum.at(object.data["tag"], 1) + ) + + assert "moo" == Enum.at(object.data["tag"], 2) end test "it works for incoming notices with contentMap" do @@ -276,13 +290,11 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do File.read!("test/fixtures/mastodon-post-activity.json") |> Jason.decode!() |> Map.put("actor", user.ap_id) - |> Map.put("to", nil) |> Map.put("cc", nil) object = data["object"] |> Map.put("attributedTo", user.ap_id) - |> Map.put("to", nil) |> Map.put("cc", nil) |> Map.put("id", user.ap_id <> "/activities/12345678") @@ -290,8 +302,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) - assert !is_nil(data["to"]) - assert !is_nil(data["cc"]) + refute is_nil(data["cc"]) end test "it strips internal likes" do @@ -330,70 +341,46 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do end test "it correctly processes messages with non-array to field" do - user = insert(:user) + data = + File.read!("test/fixtures/mastodon-post-activity.json") + |> Poison.decode!() + |> Map.put("to", "https://www.w3.org/ns/activitystreams#Public") + |> put_in(["object", "to"], "https://www.w3.org/ns/activitystreams#Public") - message = %{ - "@context" => "https://www.w3.org/ns/activitystreams", - "to" => "https://www.w3.org/ns/activitystreams#Public", - "type" => "Create", - "object" => %{ - "content" => "blah blah blah", - "type" => "Note", - "attributedTo" => user.ap_id, - "inReplyTo" => nil - }, - "actor" => user.ap_id - } + assert {:ok, activity} = Transmogrifier.handle_incoming(data) - assert {:ok, activity} = Transmogrifier.handle_incoming(message) + assert [ + "http://mastodon.example.org/users/admin/followers", + "http://localtesting.pleroma.lol/users/lain" + ] == activity.data["cc"] assert ["https://www.w3.org/ns/activitystreams#Public"] == activity.data["to"] end test "it correctly processes messages with non-array cc field" do - user = insert(:user) + data = + File.read!("test/fixtures/mastodon-post-activity.json") + |> Poison.decode!() + |> Map.put("cc", "http://mastodon.example.org/users/admin/followers") + |> put_in(["object", "cc"], "http://mastodon.example.org/users/admin/followers") - message = %{ - "@context" => "https://www.w3.org/ns/activitystreams", - "to" => user.follower_address, - "cc" => "https://www.w3.org/ns/activitystreams#Public", - "type" => "Create", - "object" => %{ - "content" => "blah blah blah", - "type" => "Note", - "attributedTo" => user.ap_id, - "inReplyTo" => nil - }, - "actor" => user.ap_id - } + assert {:ok, activity} = Transmogrifier.handle_incoming(data) - assert {:ok, activity} = Transmogrifier.handle_incoming(message) - - assert ["https://www.w3.org/ns/activitystreams#Public"] == activity.data["cc"] - assert [user.follower_address] == activity.data["to"] + assert ["http://mastodon.example.org/users/admin/followers"] == activity.data["cc"] + assert ["https://www.w3.org/ns/activitystreams#Public"] == activity.data["to"] end test "it correctly processes messages with weirdness in address fields" do - user = insert(:user) + data = + File.read!("test/fixtures/mastodon-post-activity.json") + |> Poison.decode!() + |> Map.put("cc", ["http://mastodon.example.org/users/admin/followers", ["¿"]]) + |> put_in(["object", "cc"], ["http://mastodon.example.org/users/admin/followers", ["¿"]]) - message = %{ - "@context" => "https://www.w3.org/ns/activitystreams", - "to" => [nil, user.follower_address], - "cc" => ["https://www.w3.org/ns/activitystreams#Public", ["¿"]], - "type" => "Create", - "object" => %{ - "content" => "…", - "type" => "Note", - "attributedTo" => user.ap_id, - "inReplyTo" => nil - }, - "actor" => user.ap_id - } + assert {:ok, activity} = Transmogrifier.handle_incoming(data) - assert {:ok, activity} = Transmogrifier.handle_incoming(message) - - assert ["https://www.w3.org/ns/activitystreams#Public"] == activity.data["cc"] - assert [user.follower_address] == activity.data["to"] + assert ["http://mastodon.example.org/users/admin/followers"] == activity.data["cc"] + assert ["https://www.w3.org/ns/activitystreams#Public"] == activity.data["to"] end end @@ -419,7 +406,11 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do } do clear_config([:instance, :federation_incoming_replies_max_depth], 10) - {:ok, _activity} = Transmogrifier.handle_incoming(data) + {:ok, activity} = Transmogrifier.handle_incoming(data) + + object = Object.normalize(activity.data["object"]) + + assert object.data["replies"] == items for id <- items do job_args = %{"op" => "fetch_remote", "id" => id, "depth" => 1} @@ -442,45 +433,41 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do setup do: clear_config([:instance, :federation_incoming_replies_max_depth]) setup do - user = insert(:user) + replies = %{ + "type" => "Collection", + "items" => [ + Pleroma.Web.ActivityPub.Utils.generate_object_id(), + Pleroma.Web.ActivityPub.Utils.generate_object_id() + ] + } - {:ok, activity} = CommonAPI.post(user, %{status: "post1"}) + activity = + File.read!("test/fixtures/mastodon-post-activity.json") + |> Poison.decode!() + |> Kernel.put_in(["object", "replies"], replies) - {:ok, reply1} = - CommonAPI.post(user, %{status: "reply1", in_reply_to_status_id: activity.id}) - - {:ok, reply2} = - CommonAPI.post(user, %{status: "reply2", in_reply_to_status_id: activity.id}) - - replies_uris = Enum.map([reply1, reply2], fn a -> a.object.data["id"] end) - - {:ok, federation_output} = Transmogrifier.prepare_outgoing(activity.data) - - Repo.delete(activity.object) - Repo.delete(activity) - - %{federation_output: federation_output, replies_uris: replies_uris} + %{activity: activity} end test "schedules background fetching of `replies` items if max thread depth limit allows", %{ - federation_output: federation_output, - replies_uris: replies_uris + activity: activity } do clear_config([:instance, :federation_incoming_replies_max_depth], 1) - {:ok, _activity} = Transmogrifier.handle_incoming(federation_output) + assert {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(activity) + object = Object.normalize(data["object"]) - for id <- replies_uris do + for id <- object.data["replies"] do job_args = %{"op" => "fetch_remote", "id" => id, "depth" => 1} assert_enqueued(worker: Pleroma.Workers.RemoteFetcherWorker, args: job_args) end end test "does NOT schedule background fetching of `replies` beyond max thread depth limit allows", - %{federation_output: federation_output} do + %{activity: activity} do clear_config([:instance, :federation_incoming_replies_max_depth], 0) - {:ok, _activity} = Transmogrifier.handle_incoming(federation_output) + {:ok, _activity} = Transmogrifier.handle_incoming(activity) assert all_enqueued(worker: Pleroma.Workers.RemoteFetcherWorker) == [] end @@ -498,6 +485,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do "object" => %{ "to" => ["https://www.w3.org/ns/activitystreams#Public"], "cc" => [], + "id" => Utils.generate_object_id(), "type" => "Note", "content" => "Hi", "inReplyTo" => nil, @@ -522,6 +510,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do "object" => %{ "to" => ["https://www.w3.org/ns/activitystreams#Public"], "cc" => [], + "id" => Utils.generate_object_id(), "type" => "Note", "content" => "Hi", "inReplyTo" => nil, diff --git a/test/pleroma/web/activity_pub/transmogrifier_test.exs b/test/pleroma/web/activity_pub/transmogrifier_test.exs index bb0b58e4d..5a3b57acb 100644 --- a/test/pleroma/web/activity_pub/transmogrifier_test.exs +++ b/test/pleroma/web/activity_pub/transmogrifier_test.exs @@ -11,6 +11,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do alias Pleroma.Tests.ObanHelpers alias Pleroma.User alias Pleroma.Web.ActivityPub.Transmogrifier + alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.AdminAPI.AccountView alias Pleroma.Web.CommonAPI @@ -159,8 +160,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do {:ok, activity} = CommonAPI.post(user, %{status: "hey"}) {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) - assert modified["@context"] == - Pleroma.Web.ActivityPub.Utils.make_json_ld_header()["@context"] + assert modified["@context"] == Utils.make_json_ld_header()["@context"] assert modified["object"]["conversation"] == modified["context"] end diff --git a/test/pleroma/web/federator_test.exs b/test/pleroma/web/federator_test.exs index 532ee6d30..372b6a73a 100644 --- a/test/pleroma/web/federator_test.exs +++ b/test/pleroma/web/federator_test.exs @@ -123,7 +123,8 @@ defmodule Pleroma.Web.FederatorTest do "type" => "Note", "content" => "hi world!", "id" => "http://mastodon.example.org/users/admin/objects/1", - "attributedTo" => "http://mastodon.example.org/users/admin" + "attributedTo" => "http://mastodon.example.org/users/admin", + "to" => ["https://www.w3.org/ns/activitystreams#Public"] }, "to" => ["https://www.w3.org/ns/activitystreams#Public"] } @@ -145,7 +146,8 @@ defmodule Pleroma.Web.FederatorTest do "type" => "Note", "content" => "hi world!", "id" => "http://mastodon.example.org/users/admin/objects/1", - "attributedTo" => "http://mastodon.example.org/users/admin" + "attributedTo" => "http://mastodon.example.org/users/admin", + "to" => ["https://www.w3.org/ns/activitystreams#Public"] }, "to" => ["https://www.w3.org/ns/activitystreams#Public"] } diff --git a/test/pleroma/web/static_fe/static_fe_controller_test.exs b/test/pleroma/web/static_fe/static_fe_controller_test.exs index 2af14dfeb..5752cffda 100644 --- a/test/pleroma/web/static_fe/static_fe_controller_test.exs +++ b/test/pleroma/web/static_fe/static_fe_controller_test.exs @@ -7,6 +7,7 @@ defmodule Pleroma.Web.StaticFE.StaticFEControllerTest do alias Pleroma.Activity alias Pleroma.Web.ActivityPub.Transmogrifier + alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.CommonAPI import Pleroma.Factory @@ -185,16 +186,16 @@ defmodule Pleroma.Web.StaticFE.StaticFEControllerTest do test "302 for remote cached status", %{conn: conn, user: user} do message = %{ "@context" => "https://www.w3.org/ns/activitystreams", - "to" => user.follower_address, - "cc" => "https://www.w3.org/ns/activitystreams#Public", "type" => "Create", + "actor" => user.ap_id, "object" => %{ + "to" => user.follower_address, + "cc" => "https://www.w3.org/ns/activitystreams#Public", + "id" => Utils.generate_object_id(), "content" => "blah blah blah", "type" => "Note", - "attributedTo" => user.ap_id, - "inReplyTo" => nil - }, - "actor" => user.ap_id + "attributedTo" => user.ap_id + } } assert {:ok, activity} = Transmogrifier.handle_incoming(message) From 641184fc7aff694e4e7e802b9204a1d313c0877c Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Thu, 10 Sep 2020 19:45:42 +0200 Subject: [PATCH 021/373] recipients fixes/hardening for CreateGenericValidator --- .../object_validators/recipients.ex | 25 ++++---- .../object_validators/common_fixes.ex | 34 ++++++----- .../create_generic_validator.ex | 60 +++++++++++++------ .../transmogrifier/note_handling_test.exs | 12 ++-- 4 files changed, 82 insertions(+), 49 deletions(-) diff --git a/lib/pleroma/ecto_type/activity_pub/object_validators/recipients.ex b/lib/pleroma/ecto_type/activity_pub/object_validators/recipients.ex index a03471462..06fed8fb3 100644 --- a/lib/pleroma/ecto_type/activity_pub/object_validators/recipients.ex +++ b/lib/pleroma/ecto_type/activity_pub/object_validators/recipients.ex @@ -15,22 +15,27 @@ defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.Recipients do def cast(object) when is_map(object) do case ObjectID.cast(object) do - {:ok, data} -> {:ok, data} + {:ok, data} -> {:ok, [data]} _ -> :error end end def cast(data) when is_list(data) do - data - |> Enum.reduce_while({:ok, []}, fn element, {:ok, list} -> - case ObjectID.cast(element) do - {:ok, id} -> - {:cont, {:ok, [id | list]}} + data = + data + |> Enum.reduce_while([], fn element, list -> + case ObjectID.cast(element) do + {:ok, id} -> + {:cont, [id | list]} - _ -> - {:cont, {:ok, list}} - end - end) + _ -> + {:cont, list} + end + end) + |> Enum.sort() + |> Enum.uniq() + + {:ok, data} end def cast(data) do diff --git a/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex b/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex index 7309f6af2..009cd51b0 100644 --- a/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex +++ b/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex @@ -9,37 +9,39 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.ActivityPub.Utils + def cast_recipients(message, field, field_fallback \\ []) do + {:ok, data} = ObjectValidators.Recipients.cast(message[field] || field_fallback) + + Map.put(message, field, data) + end + def fix_object_defaults(data) do %{data: %{"id" => context}, id: context_id} = Utils.create_context(data["context"] || data["conversation"]) %User{follower_address: follower_collection} = User.get_cached_by_ap_id(data["attributedTo"]) - {:ok, to} = ObjectValidators.Recipients.cast(data["to"] || []) - {:ok, cc} = ObjectValidators.Recipients.cast(data["cc"] || []) data |> Map.put("context", context) |> Map.put("context_id", context_id) - |> Map.put("to", to) - |> Map.put("cc", cc) + |> cast_recipients("to") + |> cast_recipients("cc") + |> cast_recipients("bto") + |> cast_recipients("bcc") |> Transmogrifier.fix_explicit_addressing(follower_collection) |> Transmogrifier.fix_implicit_addressing(follower_collection) end - defp fix_activity_recipients(activity, field, object) do - {:ok, data} = ObjectValidators.Recipients.cast(activity[field] || object[field]) - - Map.put(activity, field, data) - end - - def fix_activity_defaults(activity, meta) do - object = meta[:object_data] || %{} + def fix_activity_addressing(activity, _meta) do + %User{follower_address: follower_collection} = User.get_cached_by_ap_id(activity["actor"]) activity - |> fix_activity_recipients("to", object) - |> fix_activity_recipients("cc", object) - |> fix_activity_recipients("bto", object) - |> fix_activity_recipients("bcc", object) + |> cast_recipients("to") + |> cast_recipients("cc") + |> cast_recipients("bto") + |> cast_recipients("bcc") + |> Transmogrifier.fix_explicit_addressing(follower_collection) + |> Transmogrifier.fix_implicit_addressing(follower_collection) end def fix_actor(data) do diff --git a/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex b/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex index 99e8dc6c7..51d43e8d0 100644 --- a/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex @@ -10,8 +10,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator do alias Pleroma.EctoType.ActivityPub.ObjectValidators alias Pleroma.Object + alias Pleroma.User alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations + alias Pleroma.Web.ActivityPub.Transmogrifier import Ecto.Changeset @@ -23,6 +25,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator do field(:type, :string) field(:to, ObjectValidators.Recipients, default: []) field(:cc, ObjectValidators.Recipients, default: []) + field(:bto, ObjectValidators.Recipients, default: []) + field(:bcc, ObjectValidators.Recipients, default: []) field(:object, ObjectValidators.ObjectID) field(:expires_at, ObjectValidators.DateTime) @@ -54,29 +58,38 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator do |> cast(data, __schema__(:fields)) end - defp fix_context(data, meta) do - if object = meta[:object_data] do - Map.put_new(data, "context", object["context"]) - else - data - end + # CommonFixes.fix_activity_addressing adapted for Create specific behavior + defp fix_addressing(data, object) do + %User{follower_address: follower_collection} = User.get_cached_by_ap_id(data["actor"]) + + data + |> CommonFixes.cast_recipients("to", object["to"]) + |> CommonFixes.cast_recipients("cc", object["cc"]) + |> CommonFixes.cast_recipients("bto", object["bto"]) + |> CommonFixes.cast_recipients("bcc", object["bcc"]) + |> Transmogrifier.fix_explicit_addressing(follower_collection) + |> Transmogrifier.fix_implicit_addressing(follower_collection) end - defp fix(data, meta) do + def fix(data, meta) do + object = meta[:object_data] + data - |> fix_context(meta) |> CommonFixes.fix_actor() - |> CommonFixes.fix_activity_defaults(meta) + |> Map.put_new("context", object["context"]) + |> fix_addressing(object) end defp validate_data(cng, meta) do + object = meta[:object_data] + cng - |> validate_required([:actor, :type, :object]) + |> validate_required([:actor, :type, :object, :to, :cc]) |> validate_inclusion(:type, ["Create"]) |> CommonValidations.validate_actor_presence() - |> CommonValidations.validate_any_presence([:to, :cc]) - |> validate_actors_match(meta) - |> validate_context_match(meta) + |> validate_actors_match(object) + |> validate_context_match(object) + |> validate_addressing_match(object) |> validate_object_nonexistence() |> validate_object_containment() end @@ -108,8 +121,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator do end) end - def validate_actors_match(cng, meta) do - attributed_to = meta[:object_data]["attributedTo"] || meta[:object_data]["actor"] + def validate_actors_match(cng, object) do + attributed_to = object["attributedTo"] || object["actor"] cng |> validate_change(:actor, fn :actor, actor -> @@ -121,7 +134,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator do end) end - def validate_context_match(cng, %{object_data: %{"context" => object_context}}) do + def validate_context_match(cng, %{"context" => object_context}) do cng |> validate_change(:context, fn :context, context -> if context == object_context do @@ -132,5 +145,18 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator do end) end - def validate_context_match(cng, _), do: cng + def validate_addressing_match(cng, object) do + [:to, :cc, :bcc, :bto] + |> Enum.reduce(cng, fn field, cng -> + object_data = object[to_string(field)] + + validate_change(cng, field, fn field, data -> + if data == object_data do + [] + else + [{field, "field doesn't match with object (#{inspect(object_data)})"}] + end + end) + end) + end end diff --git a/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs index 3eeae4004..b79f2c94c 100644 --- a/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs +++ b/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs @@ -171,8 +171,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do assert data["to"] == ["https://www.w3.org/ns/activitystreams#Public"] assert data["cc"] == [ - "http://mastodon.example.org/users/admin/followers", - "http://localtesting.pleroma.lol/users/lain" + "http://localtesting.pleroma.lol/users/lain", + "http://mastodon.example.org/users/admin/followers" ] assert data["actor"] == "http://mastodon.example.org/users/admin" @@ -185,8 +185,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do assert object_data["to"] == ["https://www.w3.org/ns/activitystreams#Public"] assert object_data["cc"] == [ - "http://mastodon.example.org/users/admin/followers", - "http://localtesting.pleroma.lol/users/lain" + "http://localtesting.pleroma.lol/users/lain", + "http://mastodon.example.org/users/admin/followers" ] assert object_data["actor"] == "http://mastodon.example.org/users/admin" @@ -350,8 +350,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do assert {:ok, activity} = Transmogrifier.handle_incoming(data) assert [ - "http://mastodon.example.org/users/admin/followers", - "http://localtesting.pleroma.lol/users/lain" + "http://localtesting.pleroma.lol/users/lain", + "http://mastodon.example.org/users/admin/followers" ] == activity.data["cc"] assert ["https://www.w3.org/ns/activitystreams#Public"] == activity.data["to"] From 96212b2e32e2542964c665f091158fb1ff1d987d Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Tue, 15 Sep 2020 17:22:08 +0200 Subject: [PATCH 022/373] Fix addressing --- lib/pleroma/object/fetcher.ex | 7 ++++-- .../object_validators/common_fixes.ex | 25 +++++++++++-------- .../create_generic_validator.ex | 9 +++---- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/lib/pleroma/object/fetcher.ex b/lib/pleroma/object/fetcher.ex index bcccf1c4c..82d2c8bcb 100644 --- a/lib/pleroma/object/fetcher.ex +++ b/lib/pleroma/object/fetcher.ex @@ -4,6 +4,7 @@ defmodule Pleroma.Object.Fetcher do alias Pleroma.HTTP + alias Pleroma.Maps alias Pleroma.Object alias Pleroma.Object.Containment alias Pleroma.Repo @@ -124,12 +125,14 @@ defmodule Pleroma.Object.Fetcher do defp prepare_activity_params(data) do %{ "type" => "Create", - "to" => data["to"] || [], - "cc" => data["cc"] || [], # Should we seriously keep this attributedTo thing? "actor" => data["actor"] || data["attributedTo"], "object" => data } + |> Maps.put_if_present("to", data["to"]) + |> Maps.put_if_present("cc", data["cc"]) + |> Maps.put_if_present("bto", data["bto"]) + |> Maps.put_if_present("bcc", data["bcc"]) end def fetch_object_from_id!(id, options \\ []) do diff --git a/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex b/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex index 009cd51b0..c958fcc5d 100644 --- a/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex +++ b/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex @@ -9,9 +9,14 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.ActivityPub.Utils - def cast_recipients(message, field, field_fallback \\ []) do + def cast_and_filter_recipients(message, field, follower_collection, field_fallback \\ []) do {:ok, data} = ObjectValidators.Recipients.cast(message[field] || field_fallback) + data = + Enum.reject(data, fn x -> + String.ends_with?(x, "/followers") and x != follower_collection + end) + Map.put(message, field, data) end @@ -24,11 +29,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do data |> Map.put("context", context) |> Map.put("context_id", context_id) - |> cast_recipients("to") - |> cast_recipients("cc") - |> cast_recipients("bto") - |> cast_recipients("bcc") - |> Transmogrifier.fix_explicit_addressing(follower_collection) + |> cast_and_filter_recipients("to", follower_collection) + |> cast_and_filter_recipients("cc", follower_collection) + |> cast_and_filter_recipients("bto", follower_collection) + |> cast_and_filter_recipients("bcc", follower_collection) |> Transmogrifier.fix_implicit_addressing(follower_collection) end @@ -36,11 +40,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do %User{follower_address: follower_collection} = User.get_cached_by_ap_id(activity["actor"]) activity - |> cast_recipients("to") - |> cast_recipients("cc") - |> cast_recipients("bto") - |> cast_recipients("bcc") - |> Transmogrifier.fix_explicit_addressing(follower_collection) + |> cast_and_filter_recipients("to", follower_collection) + |> cast_and_filter_recipients("cc", follower_collection) + |> cast_and_filter_recipients("bto", follower_collection) + |> cast_and_filter_recipients("bcc", follower_collection) |> Transmogrifier.fix_implicit_addressing(follower_collection) end diff --git a/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex b/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex index 51d43e8d0..d2de53049 100644 --- a/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/create_generic_validator.ex @@ -63,11 +63,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidator do %User{follower_address: follower_collection} = User.get_cached_by_ap_id(data["actor"]) data - |> CommonFixes.cast_recipients("to", object["to"]) - |> CommonFixes.cast_recipients("cc", object["cc"]) - |> CommonFixes.cast_recipients("bto", object["bto"]) - |> CommonFixes.cast_recipients("bcc", object["bcc"]) - |> Transmogrifier.fix_explicit_addressing(follower_collection) + |> CommonFixes.cast_and_filter_recipients("to", follower_collection, object["to"]) + |> CommonFixes.cast_and_filter_recipients("cc", follower_collection, object["cc"]) + |> CommonFixes.cast_and_filter_recipients("bto", follower_collection, object["bto"]) + |> CommonFixes.cast_and_filter_recipients("bcc", follower_collection, object["bcc"]) |> Transmogrifier.fix_implicit_addressing(follower_collection) end From d1205406d9237c72d10df937dd8d2d4da2786cc5 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Tue, 15 Sep 2020 18:18:57 +0200 Subject: [PATCH 023/373] ActivityPubControllerTest: Apply same addr changes to object --- lib/pleroma/web/activity_pub/utils.ex | 5 +++- .../activity_pub_controller_test.exs | 30 ++++++++++++++----- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index a4dc469dc..e81623d83 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -97,7 +97,10 @@ defmodule Pleroma.Web.ActivityPub.Utils do if need_splice? do cc_list = extract_list(params["cc"]) - Map.put(params, "cc", [ap_id | cc_list]) + + params + |> Map.put("cc", [ap_id | cc_list]) + |> Kernel.put_in(["object", "cc"], [ap_id | cc_list]) else params end diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs index 2de52323e..f6ea9e2ca 100644 --- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs @@ -649,7 +649,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do test "it inserts an incoming activity into the database", %{conn: conn, data: data} do user = insert(:user) - data = Map.put(data, "bcc", [user.ap_id]) + + data = + data + |> Map.put("bcc", [user.ap_id]) + |> Kernel.put_in(["object", "bcc"], [user.ap_id]) conn = conn @@ -666,8 +670,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do user = insert(:user) data = - Map.put(data, "to", user.ap_id) - |> Map.delete("cc") + data + |> Map.put("to", user.ap_id) + |> Map.put("cc", []) + |> Kernel.put_in(["object", "to"], user.ap_id) + |> Kernel.put_in(["object", "cc"], []) conn = conn @@ -684,8 +691,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do user = insert(:user) data = - Map.put(data, "cc", user.ap_id) - |> Map.delete("to") + data + |> Map.put("to", []) + |> Map.put("cc", user.ap_id) + |> Kernel.put_in(["object", "to"], []) + |> Kernel.put_in(["object", "cc"], user.ap_id) conn = conn @@ -703,9 +713,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do user = insert(:user) data = - Map.put(data, "bcc", user.ap_id) - |> Map.delete("to") - |> Map.delete("cc") + data + |> Map.put("to", []) + |> Map.put("cc", []) + |> Map.put("bcc", user.ap_id) + |> Kernel.put_in(["object", "to"], []) + |> Kernel.put_in(["object", "cc"], []) + |> Kernel.put_in(["object", "bcc"], user.ap_id) conn = conn From b0c778fde77f5ec2320b0bd0327e8a13b0f39a63 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Tue, 15 Sep 2020 18:19:38 +0200 Subject: [PATCH 024/373] NoteHandlingTest: remove fix_explicit_addressing-related test --- .../transmogrifier/note_handling_test.exs | 42 +++---------------- 1 file changed, 6 insertions(+), 36 deletions(-) diff --git a/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs index b79f2c94c..1846b2291 100644 --- a/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs +++ b/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs @@ -10,6 +10,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do alias Pleroma.Object alias Pleroma.User alias Pleroma.Web.ActivityPub.Transmogrifier + alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.CommonAPI import Mock @@ -42,36 +43,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do assert Object.hashtags(object) == ["test"] end - test "it cleans up incoming notices which are not really DMs" do - user = insert(:user) - other_user = insert(:user) - - to = [user.ap_id, other_user.ap_id] - - data = - File.read!("test/fixtures/mastodon-post-activity.json") - |> Jason.decode!() - |> Map.put("to", to) - |> Map.put("cc", []) - - object = - data["object"] - |> Map.put("to", to) - |> Map.put("cc", []) - - data = Map.put(data, "object", object) - - {:ok, %Activity{data: data, local: false} = activity} = Transmogrifier.handle_incoming(data) - - assert data["to"] == [] - assert data["cc"] == to - - object_data = Object.normalize(activity, fetch: false).data - - assert object_data["to"] == [] - assert object_data["cc"] == to - end - test "it ignores an incoming notice if we already have it" do activity = insert(:note_activity) @@ -321,9 +292,11 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do object = Map.put(data["object"], "likes", likes) data = Map.put(data, "object", object) - {:ok, %Activity{object: object}} = Transmogrifier.handle_incoming(data) + {:ok, %Activity{} = activity} = Transmogrifier.handle_incoming(data) - refute Map.has_key?(object.data, "likes") + object = Object.normalize(activity) + + assert object.data["likes"] == [] end test "it strips internal reactions" do @@ -435,10 +408,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do setup do replies = %{ "type" => "Collection", - "items" => [ - Pleroma.Web.ActivityPub.Utils.generate_object_id(), - Pleroma.Web.ActivityPub.Utils.generate_object_id() - ] + "items" => [Utils.generate_object_id(), Utils.generate_object_id()] } activity = From 461123110b7cf47f4d2c01d1dd6992a2b63337fe Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Thu, 17 Sep 2020 16:17:16 +0200 Subject: [PATCH 025/373] Object.Fetcher: Fix getting transmogrifier reject reason --- lib/pleroma/object/fetcher.ex | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/pleroma/object/fetcher.ex b/lib/pleroma/object/fetcher.ex index 82d2c8bcb..4ca67f0fd 100644 --- a/lib/pleroma/object/fetcher.ex +++ b/lib/pleroma/object/fetcher.ex @@ -102,6 +102,9 @@ defmodule Pleroma.Object.Fetcher do {:transmogrifier, {:error, {:reject, e}}} -> {:reject, e} + {:transmogrifier, {:reject, e}} -> + {:reject, e} + {:transmogrifier, _} = e -> {:error, e} From 6c9f6e62c8453f023c6ec9106d1a7c3e66ab95b7 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Mon, 28 Sep 2020 19:34:27 +0200 Subject: [PATCH 026/373] transmogrifier: Fixing votes from Note to Answer --- .../object_validators/answer_validator.ex | 7 ++++++ .../web/activity_pub/transmogrifier.ex | 22 ++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/lib/pleroma/web/activity_pub/object_validators/answer_validator.ex b/lib/pleroma/web/activity_pub/object_validators/answer_validator.ex index c9bd9e42d..3451e1ff8 100644 --- a/lib/pleroma/web/activity_pub/object_validators/answer_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/answer_validator.ex @@ -6,6 +6,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnswerValidator do use Ecto.Schema alias Pleroma.EctoType.ActivityPub.ObjectValidators + alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations import Ecto.Changeset @@ -23,6 +24,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnswerValidator do field(:name, :string) field(:inReplyTo, ObjectValidators.ObjectID) field(:attributedTo, ObjectValidators.ObjectID) + field(:context, :string) # TODO: Remove actor on objects field(:actor, ObjectValidators.ObjectID) @@ -46,6 +48,11 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnswerValidator do end def changeset(struct, data) do + data = + data + |> CommonFixes.fix_actor() + |> CommonFixes.fix_object_defaults() + struct |> cast(data, __schema__(:fields)) end diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 28bc25363..454bbce9d 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -43,7 +43,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do |> fix_content_map() |> fix_addressing() |> fix_summary() - |> fix_type(options) end def fix_summary(%{"summary" => nil} = object) do @@ -321,19 +320,18 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do def fix_content_map(object), do: object - def fix_type(object, options \\ []) + defp fix_type(%{"type" => "Note", "inReplyTo" => reply_id, "name" => _} = object, options) + when is_binary(reply_id) do + options = Keyword.put(options, :fetch, true) - def fix_type(%{"inReplyTo" => reply_id, "name" => _} = object, options) - when is_binary(reply_id) do - with true <- Federator.allowed_thread_distance?(options[:depth]), - {:ok, %{data: %{"type" => "Question"} = _} = _} <- get_obj_helper(reply_id, options) do + with %Object{data: %{"type" => "Question"}} <- Object.normalize(reply_id, options) do Map.put(object, "type", "Answer") else _ -> object end end - def fix_type(object, _), do: object + defp fix_type(object, _options), do: object # Reduce the object list to find the reported user. defp get_reported(objects) do @@ -501,7 +499,15 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do options ) when objtype in ~w{Question Answer ChatMessage Audio Video Event Article Note} do - data = Map.put(data, "object", strip_internal_fields(data["object"])) + fetch_options = Keyword.put(options, :depth, (options[:depth] || 0) + 1) + + object = + data["object"] + |> strip_internal_fields() + |> fix_type(fetch_options) + |> fix_in_reply_to(fetch_options) + + data = Map.put(data, "object", object) options = Keyword.put(options, :local, false) with {:ok, %User{}} <- ObjectValidator.fetch_actor(data), From 0b88accae632e371becacb16be4e8798aa80c705 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Wed, 21 Oct 2020 01:20:06 +0200 Subject: [PATCH 027/373] fetcher_test: Fix missing mock function --- test/pleroma/object/fetcher_test.exs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/pleroma/object/fetcher_test.exs b/test/pleroma/object/fetcher_test.exs index a7ac90348..8d9c6c3cb 100644 --- a/test/pleroma/object/fetcher_test.exs +++ b/test/pleroma/object/fetcher_test.exs @@ -66,6 +66,14 @@ defmodule Pleroma.Object.FetcherTest do %Tesla.Env{ status: 500 } + + %{ + method: :get, + url: "https://stereophonic.space/objects/02997b83-3ea7-4b63-94af-ef3aa2d4ed17" + } -> + %Tesla.Env{ + status: 500 + } end) :ok From 53193b84b1d07c9fd3c6b80c04e3eada4fb4cd59 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Fri, 27 Nov 2020 00:25:24 +0100 Subject: [PATCH 028/373] =?UTF-8?q?utils:=20Fix=20maybe=5Fsplice=5Frecipie?= =?UTF-8?q?nt=20when=20"object"=20isn=E2=80=99t=20a=20map?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pleroma/maps.ex | 6 ++++++ lib/pleroma/web/activity_pub/utils.ex | 6 +++--- .../web/activity_pub/activity_pub_controller_test.exs | 1 - 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/pleroma/maps.ex b/lib/pleroma/maps.ex index 0d2e94248..b08b83305 100644 --- a/lib/pleroma/maps.ex +++ b/lib/pleroma/maps.ex @@ -12,4 +12,10 @@ defmodule Pleroma.Maps do _ -> map end end + + def safe_put_in(data, keys, value) when is_map(data) and is_list(keys) do + Kernel.put_in(data, keys, value) + rescue + _ -> data + end end diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index e81623d83..0d1a6d0f1 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -96,11 +96,11 @@ defmodule Pleroma.Web.ActivityPub.Utils do !label_in_collection?(ap_id, params["cc"]) if need_splice? do - cc_list = extract_list(params["cc"]) + cc = [ap_id | extract_list(params["cc"])] params - |> Map.put("cc", [ap_id | cc_list]) - |> Kernel.put_in(["object", "cc"], [ap_id | cc_list]) + |> Map.put("cc", cc) + |> Maps.safe_put_in(["object", "cc"], cc) else params end diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs index f6ea9e2ca..f3ce703e2 100644 --- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs @@ -1003,7 +1003,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do "actor" => remote_actor, "content" => "test report", "id" => "https://#{remote_domain}/e3b12fd1-948c-446e-b93b-a5e67edbe1d8", - "nickname" => reported_user.nickname, "object" => [ reported_user.ap_id, note.data["object"] From 6d6bef64bf3b37457b71cf7025e84aa9017a3b86 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Thu, 25 Mar 2021 10:17:26 +0100 Subject: [PATCH 029/373] fetcher_test: Remove assert on fake Create having an ap_id --- test/pleroma/object/fetcher_test.exs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/pleroma/object/fetcher_test.exs b/test/pleroma/object/fetcher_test.exs index 8d9c6c3cb..bd0a6e497 100644 --- a/test/pleroma/object/fetcher_test.exs +++ b/test/pleroma/object/fetcher_test.exs @@ -132,8 +132,7 @@ defmodule Pleroma.Object.FetcherTest do {:ok, object} = Fetcher.fetch_object_from_id("http://mastodon.example.org/@admin/99541947525187367") - assert activity = Activity.get_create_by_object_ap_id(object.data["id"]) - assert activity.data["id"] + assert _activity = Activity.get_create_by_object_ap_id(object.data["id"]) {:ok, object_again} = Fetcher.fetch_object_from_id("http://mastodon.example.org/@admin/99541947525187367") From 5ef4659b373ae1106090952ff3e963b419fa1d72 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Mon, 5 Apr 2021 18:57:14 +0200 Subject: [PATCH 030/373] test/pleroma/web/common_api_test.exs: Strip : around emoji key-name --- test/pleroma/web/common_api_test.exs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/pleroma/web/common_api_test.exs b/test/pleroma/web/common_api_test.exs index 6619f8fc8..86c12f0b2 100644 --- a/test/pleroma/web/common_api_test.exs +++ b/test/pleroma/web/common_api_test.exs @@ -539,8 +539,8 @@ defmodule Pleroma.Web.CommonAPITest do spoiler_text: ":joker_smile:" }) - assert Object.normalize(reply_activity).data["emoji"][":joker_smile:"] - refute Object.normalize(reply_activity).data["emoji"][":joker_disapprove:"] + assert Object.normalize(reply_activity).data["emoji"]["joker_smile"] + refute Object.normalize(reply_activity).data["emoji"]["joker_disapprove"] end test "deactivated users can't post" do From 4f55d5123b9d2110ff803e8e9cd2c0f968bc63fc Mon Sep 17 00:00:00 2001 From: Sean King Date: Thu, 15 Apr 2021 22:56:21 -0600 Subject: [PATCH 031/373] Remove MastoFE-related backend code and frontend pieces --- lib/pleroma/web/masto_fe_controller.ex | 65 - .../controllers/app_controller.ex | 5 +- .../controllers/auth_controller.ex | 108 - lib/pleroma/web/o_auth/o_auth_controller.ex | 3 - lib/pleroma/web/router.ex | 32 - .../web/templates/masto_fe/index.html.eex | 35 - lib/pleroma/web/views/masto_fe_view.ex | 91 - priv/static/packs/arrow-key-navigation.js | 2 - priv/static/packs/arrow-key-navigation.js.map | 1 - priv/static/packs/base_polyfills.js | 3 - .../packs/base_polyfills.js.LICENSE.txt | 5 - priv/static/packs/base_polyfills.js.map | 1 - priv/static/packs/common.js | 3 - priv/static/packs/common.js.LICENSE.txt | 1 - priv/static/packs/common.js.map | 1 - .../packs/containers/media_container.js | 3 - .../containers/media_container.js.LICENSE.txt | 149 - .../packs/containers/media_container.js.map | 1 - priv/static/packs/core/admin.js | 2 - priv/static/packs/core/admin.js.map | 1 - priv/static/packs/core/auth.js | 3 - priv/static/packs/core/auth.js.LICENSE.txt | 7 - priv/static/packs/core/auth.js.map | 1 - priv/static/packs/core/common.css | 6 - priv/static/packs/core/common.css.map | 1 - priv/static/packs/core/common.js | 2 - priv/static/packs/core/common.js.map | 1 - priv/static/packs/core/embed.js | 2 - priv/static/packs/core/embed.js.map | 1 - priv/static/packs/core/mailer.css | 3 - priv/static/packs/core/mailer.css.map | 1 - priv/static/packs/core/mailer.js | 2 - priv/static/packs/core/mailer.js.map | 1 - priv/static/packs/core/modal.js | 2 - priv/static/packs/core/modal.js.map | 1 - priv/static/packs/core/public.js | 2 - priv/static/packs/core/public.js.map | 1 - priv/static/packs/core/settings.js | 3 - .../static/packs/core/settings.js.LICENSE.txt | 7 - priv/static/packs/core/settings.js.map | 1 - priv/static/packs/emoji_picker.js | 2 - priv/static/packs/emoji_picker.js.map | 1 - priv/static/packs/extra_polyfills.js | 3 - .../packs/extra_polyfills.js.LICENSE.txt | 1 - priv/static/packs/extra_polyfills.js.map | 1 - priv/static/packs/features/account_gallery.js | 2 - .../packs/features/account_gallery.js.map | 1 - .../static/packs/features/account_timeline.js | 2 - .../packs/features/account_timeline.js.map | 1 - priv/static/packs/features/blocks.js | 2 - priv/static/packs/features/blocks.js.map | 1 - .../packs/features/bookmarked_statuses.js | 2 - .../packs/features/bookmarked_statuses.js.map | 1 - .../packs/features/community_timeline.js | 2 - .../packs/features/community_timeline.js.map | 1 - priv/static/packs/features/compose.js | 2 - priv/static/packs/features/compose.js.map | 1 - priv/static/packs/features/direct_timeline.js | 2 - .../packs/features/direct_timeline.js.map | 1 - priv/static/packs/features/directory.js | 2 - priv/static/packs/features/directory.js.map | 1 - priv/static/packs/features/domain_blocks.js | 2 - .../packs/features/domain_blocks.js.map | 1 - .../packs/features/favourited_statuses.js | 2 - .../packs/features/favourited_statuses.js.map | 1 - priv/static/packs/features/favourites.js | 2 - priv/static/packs/features/favourites.js.map | 1 - priv/static/packs/features/follow_requests.js | 2 - .../packs/features/follow_requests.js.map | 1 - priv/static/packs/features/followers.js | 2 - priv/static/packs/features/followers.js.map | 1 - priv/static/packs/features/following.js | 2 - priv/static/packs/features/following.js.map | 1 - .../packs/features/generic_not_found.js | 2 - .../packs/features/generic_not_found.js.map | 1 - priv/static/packs/features/getting_started.js | 2 - .../packs/features/getting_started.js.map | 1 - .../packs/features/glitch/async/directory.js | 2 - .../features/glitch/async/directory.js.map | 1 - .../packs/features/glitch/async/list_adder.js | 2 - .../features/glitch/async/list_adder.js.map | 1 - .../packs/features/glitch/async/search.js | 2 - .../packs/features/glitch/async/search.js.map | 1 - .../static/packs/features/hashtag_timeline.js | 2 - .../packs/features/hashtag_timeline.js.map | 1 - priv/static/packs/features/home_timeline.js | 2 - .../packs/features/home_timeline.js.map | 1 - .../packs/features/keyboard_shortcuts.js | 2 - .../packs/features/keyboard_shortcuts.js.map | 1 - priv/static/packs/features/list_adder.js | 2 - priv/static/packs/features/list_adder.js.map | 1 - priv/static/packs/features/list_editor.js | 2 - priv/static/packs/features/list_editor.js.map | 1 - priv/static/packs/features/list_timeline.js | 2 - .../packs/features/list_timeline.js.map | 1 - priv/static/packs/features/lists.js | 2 - priv/static/packs/features/lists.js.map | 1 - priv/static/packs/features/mutes.js | 2 - priv/static/packs/features/mutes.js.map | 1 - priv/static/packs/features/notifications.js | 2 - .../packs/features/notifications.js.map | 1 - priv/static/packs/features/pinned_statuses.js | 2 - .../packs/features/pinned_statuses.js.map | 1 - priv/static/packs/features/public_timeline.js | 2 - .../packs/features/public_timeline.js.map | 1 - priv/static/packs/features/reblogs.js | 2 - priv/static/packs/features/reblogs.js.map | 1 - priv/static/packs/features/search.js | 2 - priv/static/packs/features/search.js.map | 1 - priv/static/packs/features/status.js | 2 - priv/static/packs/features/status.js.map | 1 - priv/static/packs/flavours/glitch/about.js | 3 - .../flavours/glitch/about.js.LICENSE.txt | 193 -- .../static/packs/flavours/glitch/about.js.map | 1 - priv/static/packs/flavours/glitch/admin.js | 3 - .../flavours/glitch/admin.js.LICENSE.txt | 41 - .../static/packs/flavours/glitch/admin.js.map | 1 - .../flavours/glitch/async/account_gallery.js | 2 - .../glitch/async/account_gallery.js.map | 1 - .../flavours/glitch/async/account_timeline.js | 2 - .../glitch/async/account_timeline.js.map | 1 - .../flavours/glitch/async/block_modal.js | 2 - .../flavours/glitch/async/block_modal.js.map | 1 - .../packs/flavours/glitch/async/blocks.js | 2 - .../packs/flavours/glitch/async/blocks.js.map | 1 - .../glitch/async/bookmarked_statuses.js | 2 - .../glitch/async/bookmarked_statuses.js.map | 1 - .../glitch/async/community_timeline.js | 2 - .../glitch/async/community_timeline.js.map | 1 - .../packs/flavours/glitch/async/compose.js | 2 - .../flavours/glitch/async/compose.js.map | 1 - .../flavours/glitch/async/direct_timeline.js | 2 - .../glitch/async/direct_timeline.js.map | 1 - .../flavours/glitch/async/domain_blocks.js | 2 - .../glitch/async/domain_blocks.js.map | 1 - .../flavours/glitch/async/embed_modal.js | 2 - .../flavours/glitch/async/embed_modal.js.map | 1 - .../flavours/glitch/async/emoji_picker.js | 2 - .../flavours/glitch/async/emoji_picker.js.map | 1 - .../glitch/async/favourited_statuses.js | 2 - .../glitch/async/favourited_statuses.js.map | 1 - .../packs/flavours/glitch/async/favourites.js | 2 - .../flavours/glitch/async/favourites.js.map | 1 - .../flavours/glitch/async/follow_requests.js | 2 - .../glitch/async/follow_requests.js.map | 1 - .../packs/flavours/glitch/async/followers.js | 2 - .../flavours/glitch/async/followers.js.map | 1 - .../packs/flavours/glitch/async/following.js | 2 - .../flavours/glitch/async/following.js.map | 1 - .../glitch/async/generic_not_found.js | 2 - .../glitch/async/generic_not_found.js.map | 1 - .../flavours/glitch/async/getting_started.js | 2 - .../glitch/async/getting_started.js.map | 1 - .../glitch/async/getting_started_misc.js | 2 - .../glitch/async/getting_started_misc.js.map | 1 - .../flavours/glitch/async/hashtag_timeline.js | 2 - .../glitch/async/hashtag_timeline.js.map | 1 - .../flavours/glitch/async/home_timeline.js | 2 - .../glitch/async/home_timeline.js.map | 1 - .../glitch/async/keyboard_shortcuts.js | 2 - .../glitch/async/keyboard_shortcuts.js.map | 1 - .../flavours/glitch/async/list_editor.js | 2 - .../flavours/glitch/async/list_editor.js.map | 1 - .../flavours/glitch/async/list_timeline.js | 2 - .../glitch/async/list_timeline.js.map | 1 - .../packs/flavours/glitch/async/lists.js | 2 - .../packs/flavours/glitch/async/lists.js.map | 1 - .../packs/flavours/glitch/async/mute_modal.js | 2 - .../flavours/glitch/async/mute_modal.js.map | 1 - .../packs/flavours/glitch/async/mutes.js | 2 - .../packs/flavours/glitch/async/mutes.js.map | 1 - .../flavours/glitch/async/notifications.js | 2 - .../glitch/async/notifications.js.map | 1 - .../flavours/glitch/async/onboarding_modal.js | 2 - .../glitch/async/onboarding_modal.js.map | 1 - .../glitch/async/pinned_accounts_editor.js | 2 - .../async/pinned_accounts_editor.js.map | 1 - .../flavours/glitch/async/pinned_statuses.js | 2 - .../glitch/async/pinned_statuses.js.map | 1 - .../flavours/glitch/async/public_timeline.js | 2 - .../glitch/async/public_timeline.js.map | 1 - .../packs/flavours/glitch/async/reblogs.js | 2 - .../flavours/glitch/async/reblogs.js.map | 1 - .../flavours/glitch/async/report_modal.js | 2 - .../flavours/glitch/async/report_modal.js.map | 1 - .../flavours/glitch/async/settings_modal.js | 2 - .../glitch/async/settings_modal.js.map | 1 - .../packs/flavours/glitch/async/status.js | 2 - .../packs/flavours/glitch/async/status.js.map | 1 - priv/static/packs/flavours/glitch/common.css | 3 - .../packs/flavours/glitch/common.css.map | 1 - priv/static/packs/flavours/glitch/common.js | 2 - .../packs/flavours/glitch/common.js.map | 1 - priv/static/packs/flavours/glitch/embed.js | 3 - .../flavours/glitch/embed.js.LICENSE.txt | 41 - .../static/packs/flavours/glitch/embed.js.map | 1 - priv/static/packs/flavours/glitch/error.js | 2 - .../static/packs/flavours/glitch/error.js.map | 1 - priv/static/packs/flavours/glitch/home.js | 3 - .../packs/flavours/glitch/home.js.LICENSE.txt | 202 -- priv/static/packs/flavours/glitch/home.js.map | 1 - priv/static/packs/flavours/glitch/public.js | 3 - .../flavours/glitch/public.js.LICENSE.txt | 41 - .../packs/flavours/glitch/public.js.map | 1 - priv/static/packs/flavours/glitch/settings.js | 2 - .../packs/flavours/glitch/settings.js.map | 1 - priv/static/packs/flavours/glitch/share.js | 3 - .../flavours/glitch/share.js.LICENSE.txt | 193 -- .../static/packs/flavours/glitch/share.js.map | 1 - priv/static/packs/flavours/vanilla/about.css | 6 - .../packs/flavours/vanilla/about.css.map | 1 - priv/static/packs/flavours/vanilla/about.js | 3 - .../flavours/vanilla/about.js.LICENSE.txt | 193 -- .../packs/flavours/vanilla/about.js.map | 1 - priv/static/packs/flavours/vanilla/admin.css | 6 - .../packs/flavours/vanilla/admin.css.map | 1 - priv/static/packs/flavours/vanilla/admin.js | 3 - .../flavours/vanilla/admin.js.LICENSE.txt | 41 - .../packs/flavours/vanilla/admin.js.map | 1 - priv/static/packs/flavours/vanilla/common.css | 3 - .../packs/flavours/vanilla/common.css.map | 1 - priv/static/packs/flavours/vanilla/common.js | 2 - .../packs/flavours/vanilla/common.js.map | 1 - priv/static/packs/flavours/vanilla/embed.css | 6 - .../packs/flavours/vanilla/embed.css.map | 1 - priv/static/packs/flavours/vanilla/embed.js | 3 - .../flavours/vanilla/embed.js.LICENSE.txt | 41 - .../packs/flavours/vanilla/embed.js.map | 1 - priv/static/packs/flavours/vanilla/error.js | 2 - .../packs/flavours/vanilla/error.js.map | 1 - priv/static/packs/flavours/vanilla/home.css | 6 - .../packs/flavours/vanilla/home.css.map | 1 - priv/static/packs/flavours/vanilla/home.js | 3 - .../flavours/vanilla/home.js.LICENSE.txt | 193 -- .../static/packs/flavours/vanilla/home.js.map | 1 - priv/static/packs/flavours/vanilla/public.css | 6 - .../packs/flavours/vanilla/public.css.map | 1 - priv/static/packs/flavours/vanilla/public.js | 3 - .../flavours/vanilla/public.js.LICENSE.txt | 41 - .../packs/flavours/vanilla/public.js.map | 1 - .../packs/flavours/vanilla/settings.css | 6 - .../packs/flavours/vanilla/settings.css.map | 1 - .../static/packs/flavours/vanilla/settings.js | 3 - .../flavours/vanilla/settings.js.LICENSE.txt | 41 - .../packs/flavours/vanilla/settings.js.map | 1 - priv/static/packs/flavours/vanilla/share.css | 6 - .../packs/flavours/vanilla/share.css.map | 1 - priv/static/packs/flavours/vanilla/share.js | 3 - .../flavours/vanilla/share.js.LICENSE.txt | 191 -- .../packs/flavours/vanilla/share.js.map | 1 - priv/static/packs/locales.js | 2 - priv/static/packs/locales.js.map | 1 - priv/static/packs/locales/glitch/ar.js | 2 - priv/static/packs/locales/glitch/ar.js.map | 1 - priv/static/packs/locales/glitch/ast.js | 2 - priv/static/packs/locales/glitch/ast.js.map | 1 - priv/static/packs/locales/glitch/bg.js | 2 - priv/static/packs/locales/glitch/bg.js.map | 1 - priv/static/packs/locales/glitch/bn.js | 2 - priv/static/packs/locales/glitch/bn.js.map | 1 - priv/static/packs/locales/glitch/br.js | 2 - priv/static/packs/locales/glitch/br.js.map | 1 - priv/static/packs/locales/glitch/ca.js | 2 - priv/static/packs/locales/glitch/ca.js.map | 1 - priv/static/packs/locales/glitch/co.js | 2 - priv/static/packs/locales/glitch/co.js.map | 1 - priv/static/packs/locales/glitch/cs.js | 2 - priv/static/packs/locales/glitch/cs.js.map | 1 - priv/static/packs/locales/glitch/cy.js | 2 - priv/static/packs/locales/glitch/cy.js.map | 1 - priv/static/packs/locales/glitch/da.js | 2 - priv/static/packs/locales/glitch/da.js.map | 1 - priv/static/packs/locales/glitch/de.js | 2 - priv/static/packs/locales/glitch/de.js.map | 1 - priv/static/packs/locales/glitch/el.js | 2 - priv/static/packs/locales/glitch/el.js.map | 1 - priv/static/packs/locales/glitch/en.js | 2 - priv/static/packs/locales/glitch/en.js.map | 1 - priv/static/packs/locales/glitch/eo.js | 2 - priv/static/packs/locales/glitch/eo.js.map | 1 - priv/static/packs/locales/glitch/es-AR.js | 2 - priv/static/packs/locales/glitch/es-AR.js.map | 1 - priv/static/packs/locales/glitch/es.js | 2 - priv/static/packs/locales/glitch/es.js.map | 1 - priv/static/packs/locales/glitch/et.js | 2 - priv/static/packs/locales/glitch/et.js.map | 1 - priv/static/packs/locales/glitch/eu.js | 2 - priv/static/packs/locales/glitch/eu.js.map | 1 - priv/static/packs/locales/glitch/fa.js | 2 - priv/static/packs/locales/glitch/fa.js.map | 1 - priv/static/packs/locales/glitch/fi.js | 2 - priv/static/packs/locales/glitch/fi.js.map | 1 - priv/static/packs/locales/glitch/fr.js | 2 - priv/static/packs/locales/glitch/fr.js.map | 1 - priv/static/packs/locales/glitch/ga.js | 2 - priv/static/packs/locales/glitch/ga.js.map | 1 - priv/static/packs/locales/glitch/gl.js | 2 - priv/static/packs/locales/glitch/gl.js.map | 1 - priv/static/packs/locales/glitch/he.js | 2 - priv/static/packs/locales/glitch/he.js.map | 1 - priv/static/packs/locales/glitch/hi.js | 2 - priv/static/packs/locales/glitch/hi.js.map | 1 - priv/static/packs/locales/glitch/hr.js | 2 - priv/static/packs/locales/glitch/hr.js.map | 1 - priv/static/packs/locales/glitch/hu.js | 2 - priv/static/packs/locales/glitch/hu.js.map | 1 - priv/static/packs/locales/glitch/hy.js | 2 - priv/static/packs/locales/glitch/hy.js.map | 1 - priv/static/packs/locales/glitch/id.js | 2 - priv/static/packs/locales/glitch/id.js.map | 1 - priv/static/packs/locales/glitch/io.js | 2 - priv/static/packs/locales/glitch/io.js.map | 1 - priv/static/packs/locales/glitch/is.js | 2 - priv/static/packs/locales/glitch/is.js.map | 1 - priv/static/packs/locales/glitch/it.js | 2 - priv/static/packs/locales/glitch/it.js.map | 1 - priv/static/packs/locales/glitch/ja.js | 2 - priv/static/packs/locales/glitch/ja.js.map | 1 - priv/static/packs/locales/glitch/ka.js | 2 - priv/static/packs/locales/glitch/ka.js.map | 1 - priv/static/packs/locales/glitch/kab.js | 2 - priv/static/packs/locales/glitch/kab.js.map | 1 - priv/static/packs/locales/glitch/kk.js | 2 - priv/static/packs/locales/glitch/kk.js.map | 1 - priv/static/packs/locales/glitch/kn.js | 2 - priv/static/packs/locales/glitch/kn.js.map | 1 - priv/static/packs/locales/glitch/ko.js | 2 - priv/static/packs/locales/glitch/ko.js.map | 1 - priv/static/packs/locales/glitch/lt.js | 2 - priv/static/packs/locales/glitch/lt.js.map | 1 - priv/static/packs/locales/glitch/lv.js | 2 - priv/static/packs/locales/glitch/lv.js.map | 1 - priv/static/packs/locales/glitch/mk.js | 2 - priv/static/packs/locales/glitch/mk.js.map | 1 - priv/static/packs/locales/glitch/ml.js | 2 - priv/static/packs/locales/glitch/ml.js.map | 1 - priv/static/packs/locales/glitch/mr.js | 2 - priv/static/packs/locales/glitch/mr.js.map | 1 - priv/static/packs/locales/glitch/ms.js | 2 - priv/static/packs/locales/glitch/ms.js.map | 1 - priv/static/packs/locales/glitch/nl.js | 2 - priv/static/packs/locales/glitch/nl.js.map | 1 - priv/static/packs/locales/glitch/nn.js | 2 - priv/static/packs/locales/glitch/nn.js.map | 1 - priv/static/packs/locales/glitch/no.js | 2 - priv/static/packs/locales/glitch/no.js.map | 1 - priv/static/packs/locales/glitch/oc.js | 2 - priv/static/packs/locales/glitch/oc.js.map | 1 - priv/static/packs/locales/glitch/pl.js | 2 - priv/static/packs/locales/glitch/pl.js.map | 1 - priv/static/packs/locales/glitch/pt-BR.js | 2 - priv/static/packs/locales/glitch/pt-BR.js.map | 1 - priv/static/packs/locales/glitch/pt-PT.js | 2 - priv/static/packs/locales/glitch/pt-PT.js.map | 1 - priv/static/packs/locales/glitch/ro.js | 2 - priv/static/packs/locales/glitch/ro.js.map | 1 - priv/static/packs/locales/glitch/ru.js | 2 - priv/static/packs/locales/glitch/ru.js.map | 1 - priv/static/packs/locales/glitch/sk.js | 2 - priv/static/packs/locales/glitch/sk.js.map | 1 - priv/static/packs/locales/glitch/sl.js | 2 - priv/static/packs/locales/glitch/sl.js.map | 1 - priv/static/packs/locales/glitch/sq.js | 2 - priv/static/packs/locales/glitch/sq.js.map | 1 - priv/static/packs/locales/glitch/sr-Latn.js | 2 - .../packs/locales/glitch/sr-Latn.js.map | 1 - priv/static/packs/locales/glitch/sr.js | 2 - priv/static/packs/locales/glitch/sr.js.map | 1 - priv/static/packs/locales/glitch/sv.js | 2 - priv/static/packs/locales/glitch/sv.js.map | 1 - priv/static/packs/locales/glitch/ta.js | 2 - priv/static/packs/locales/glitch/ta.js.map | 1 - priv/static/packs/locales/glitch/te.js | 2 - priv/static/packs/locales/glitch/te.js.map | 1 - priv/static/packs/locales/glitch/th.js | 2 - priv/static/packs/locales/glitch/th.js.map | 1 - priv/static/packs/locales/glitch/tr.js | 2 - priv/static/packs/locales/glitch/tr.js.map | 1 - priv/static/packs/locales/glitch/uk.js | 2 - priv/static/packs/locales/glitch/uk.js.map | 1 - priv/static/packs/locales/glitch/ur.js | 2 - priv/static/packs/locales/glitch/ur.js.map | 1 - priv/static/packs/locales/glitch/vi.js | 2 - priv/static/packs/locales/glitch/vi.js.map | 1 - priv/static/packs/locales/glitch/zh-CN.js | 2 - priv/static/packs/locales/glitch/zh-CN.js.map | 1 - priv/static/packs/locales/glitch/zh-HK.js | 2 - priv/static/packs/locales/glitch/zh-HK.js.map | 1 - priv/static/packs/locales/glitch/zh-TW.js | 2 - priv/static/packs/locales/glitch/zh-TW.js.map | 1 - priv/static/packs/locales/vanilla/ar.js | 2 - priv/static/packs/locales/vanilla/ar.js.map | 1 - priv/static/packs/locales/vanilla/ast.js | 2 - priv/static/packs/locales/vanilla/ast.js.map | 1 - priv/static/packs/locales/vanilla/bg.js | 2 - priv/static/packs/locales/vanilla/bg.js.map | 1 - priv/static/packs/locales/vanilla/bn.js | 2 - priv/static/packs/locales/vanilla/bn.js.map | 1 - priv/static/packs/locales/vanilla/br.js | 2 - priv/static/packs/locales/vanilla/br.js.map | 1 - priv/static/packs/locales/vanilla/ca.js | 2 - priv/static/packs/locales/vanilla/ca.js.map | 1 - priv/static/packs/locales/vanilla/co.js | 2 - priv/static/packs/locales/vanilla/co.js.map | 1 - priv/static/packs/locales/vanilla/cs.js | 2 - priv/static/packs/locales/vanilla/cs.js.map | 1 - priv/static/packs/locales/vanilla/cy.js | 2 - priv/static/packs/locales/vanilla/cy.js.map | 1 - priv/static/packs/locales/vanilla/da.js | 2 - priv/static/packs/locales/vanilla/da.js.map | 1 - priv/static/packs/locales/vanilla/de.js | 2 - priv/static/packs/locales/vanilla/de.js.map | 1 - priv/static/packs/locales/vanilla/el.js | 2 - priv/static/packs/locales/vanilla/el.js.map | 1 - priv/static/packs/locales/vanilla/en.js | 2 - priv/static/packs/locales/vanilla/en.js.map | 1 - priv/static/packs/locales/vanilla/eo.js | 2 - priv/static/packs/locales/vanilla/eo.js.map | 1 - priv/static/packs/locales/vanilla/es-AR.js | 2 - .../static/packs/locales/vanilla/es-AR.js.map | 1 - priv/static/packs/locales/vanilla/es.js | 2 - priv/static/packs/locales/vanilla/es.js.map | 1 - priv/static/packs/locales/vanilla/et.js | 2 - priv/static/packs/locales/vanilla/et.js.map | 1 - priv/static/packs/locales/vanilla/eu.js | 2 - priv/static/packs/locales/vanilla/eu.js.map | 1 - priv/static/packs/locales/vanilla/fa.js | 2 - priv/static/packs/locales/vanilla/fa.js.map | 1 - priv/static/packs/locales/vanilla/fi.js | 2 - priv/static/packs/locales/vanilla/fi.js.map | 1 - priv/static/packs/locales/vanilla/fr.js | 2 - priv/static/packs/locales/vanilla/fr.js.map | 1 - priv/static/packs/locales/vanilla/ga.js | 2 - priv/static/packs/locales/vanilla/ga.js.map | 1 - priv/static/packs/locales/vanilla/gl.js | 2 - priv/static/packs/locales/vanilla/gl.js.map | 1 - priv/static/packs/locales/vanilla/he.js | 2 - priv/static/packs/locales/vanilla/he.js.map | 1 - priv/static/packs/locales/vanilla/hi.js | 2 - priv/static/packs/locales/vanilla/hi.js.map | 1 - priv/static/packs/locales/vanilla/hr.js | 2 - priv/static/packs/locales/vanilla/hr.js.map | 1 - priv/static/packs/locales/vanilla/hu.js | 2 - priv/static/packs/locales/vanilla/hu.js.map | 1 - priv/static/packs/locales/vanilla/hy.js | 2 - priv/static/packs/locales/vanilla/hy.js.map | 1 - priv/static/packs/locales/vanilla/id.js | 2 - priv/static/packs/locales/vanilla/id.js.map | 1 - priv/static/packs/locales/vanilla/io.js | 2 - priv/static/packs/locales/vanilla/io.js.map | 1 - priv/static/packs/locales/vanilla/is.js | 2 - priv/static/packs/locales/vanilla/is.js.map | 1 - priv/static/packs/locales/vanilla/it.js | 2 - priv/static/packs/locales/vanilla/it.js.map | 1 - priv/static/packs/locales/vanilla/ja.js | 2 - priv/static/packs/locales/vanilla/ja.js.map | 1 - priv/static/packs/locales/vanilla/ka.js | 2 - priv/static/packs/locales/vanilla/ka.js.map | 1 - priv/static/packs/locales/vanilla/kab.js | 2 - priv/static/packs/locales/vanilla/kab.js.map | 1 - priv/static/packs/locales/vanilla/kk.js | 2 - priv/static/packs/locales/vanilla/kk.js.map | 1 - priv/static/packs/locales/vanilla/kn.js | 2 - priv/static/packs/locales/vanilla/kn.js.map | 1 - priv/static/packs/locales/vanilla/ko.js | 2 - priv/static/packs/locales/vanilla/ko.js.map | 1 - priv/static/packs/locales/vanilla/lt.js | 2 - priv/static/packs/locales/vanilla/lt.js.map | 1 - priv/static/packs/locales/vanilla/lv.js | 2 - priv/static/packs/locales/vanilla/lv.js.map | 1 - priv/static/packs/locales/vanilla/mk.js | 2 - priv/static/packs/locales/vanilla/mk.js.map | 1 - priv/static/packs/locales/vanilla/ml.js | 2 - priv/static/packs/locales/vanilla/ml.js.map | 1 - priv/static/packs/locales/vanilla/mr.js | 2 - priv/static/packs/locales/vanilla/mr.js.map | 1 - priv/static/packs/locales/vanilla/ms.js | 2 - priv/static/packs/locales/vanilla/ms.js.map | 1 - priv/static/packs/locales/vanilla/nl.js | 2 - priv/static/packs/locales/vanilla/nl.js.map | 1 - priv/static/packs/locales/vanilla/nn.js | 2 - priv/static/packs/locales/vanilla/nn.js.map | 1 - priv/static/packs/locales/vanilla/no.js | 2 - priv/static/packs/locales/vanilla/no.js.map | 1 - priv/static/packs/locales/vanilla/oc.js | 2 - priv/static/packs/locales/vanilla/oc.js.map | 1 - priv/static/packs/locales/vanilla/pl.js | 2 - priv/static/packs/locales/vanilla/pl.js.map | 1 - priv/static/packs/locales/vanilla/pt-BR.js | 2 - .../static/packs/locales/vanilla/pt-BR.js.map | 1 - priv/static/packs/locales/vanilla/pt-PT.js | 2 - .../static/packs/locales/vanilla/pt-PT.js.map | 1 - priv/static/packs/locales/vanilla/ro.js | 2 - priv/static/packs/locales/vanilla/ro.js.map | 1 - priv/static/packs/locales/vanilla/ru.js | 2 - priv/static/packs/locales/vanilla/ru.js.map | 1 - priv/static/packs/locales/vanilla/sk.js | 2 - priv/static/packs/locales/vanilla/sk.js.map | 1 - priv/static/packs/locales/vanilla/sl.js | 2 - priv/static/packs/locales/vanilla/sl.js.map | 1 - priv/static/packs/locales/vanilla/sq.js | 2 - priv/static/packs/locales/vanilla/sq.js.map | 1 - priv/static/packs/locales/vanilla/sr-Latn.js | 2 - .../packs/locales/vanilla/sr-Latn.js.map | 1 - priv/static/packs/locales/vanilla/sr.js | 2 - priv/static/packs/locales/vanilla/sr.js.map | 1 - priv/static/packs/locales/vanilla/sv.js | 2 - priv/static/packs/locales/vanilla/sv.js.map | 1 - priv/static/packs/locales/vanilla/ta.js | 2 - priv/static/packs/locales/vanilla/ta.js.map | 1 - priv/static/packs/locales/vanilla/te.js | 2 - priv/static/packs/locales/vanilla/te.js.map | 1 - priv/static/packs/locales/vanilla/th.js | 2 - priv/static/packs/locales/vanilla/th.js.map | 1 - priv/static/packs/locales/vanilla/tr.js | 2 - priv/static/packs/locales/vanilla/tr.js.map | 1 - priv/static/packs/locales/vanilla/uk.js | 2 - priv/static/packs/locales/vanilla/uk.js.map | 1 - priv/static/packs/locales/vanilla/ur.js | 2 - priv/static/packs/locales/vanilla/ur.js.map | 1 - priv/static/packs/locales/vanilla/vi.js | 2 - priv/static/packs/locales/vanilla/vi.js.map | 1 - priv/static/packs/locales/vanilla/zh-CN.js | 2 - .../static/packs/locales/vanilla/zh-CN.js.map | 1 - priv/static/packs/locales/vanilla/zh-HK.js | 2 - .../static/packs/locales/vanilla/zh-HK.js.map | 1 - priv/static/packs/locales/vanilla/zh-TW.js | 2 - .../static/packs/locales/vanilla/zh-TW.js.map | 1 - priv/static/packs/manifest.json | 2377 --------------- ...eview-bb9cc15a0102bfaf65712e5cff7e58df.jpg | Bin 197277 -> 0 bytes ...rawer-ee1bfcbe5811ea31771b7187c7507ee6.png | Bin 3269 -> 0 bytes ...tched-33467bf8c8d2b995d6c76d8810aba3db.png | Bin 3544 -> 0 bytes .../fonts/fontawesome-webfont-674f50d2.eot | Bin 165742 -> 0 bytes .../fonts/fontawesome-webfont-912ec66d.svg | 2671 ----------------- .../fonts/fontawesome-webfont-af7ae505.woff2 | Bin 77160 -> 0 bytes .../fonts/fontawesome-webfont-b06871f2.ttf | Bin 165548 -> 0 bytes .../fonts/fontawesome-webfont-fee66e71.woff | Bin 98024 -> 0 bytes ...Serif-a678e38bb3e20736cbed7a6925f24666.ttf | Bin 626300 -> 0 bytes ...frame-3446d4d28d72aef2f64f7fabae30eb4a.png | Bin 378 -> 0 bytes ..._wave-afb828463da264adbce26a3f17731f6c.gif | Bin 8897 -> 0 bytes ...about-ffafc67a2e97ca436da6c1bf61a8ab68.png | Bin 497 -> 0 bytes ...locks-0b0e54d45ff0177b02e1357ac09c0d51.png | Bin 356 -> 0 bytes ...ached-108e30d96e1d5152be7fe2978bcdfe14.svg | 2 - ..._done-dba357bfbba455428787fefc655ce120.svg | 4 - ...email-1346985c7aaceb601b0d4257133254f4.svg | 4 - ...nload-4b5c054e76b0df3cbbc851854cd10c3c.svg | 4 - ..._flag-6cc7d5ce6f0c35fe10e0f05494b2aba8.svg | 4 - ...uests-32eaf00987b072b2b12f8015d6a6a250.png | Bin 561 -> 0 bytes ...grade-8e81b8e88c2b5834347a2a226c65d440.svg | 4 - ..._home-433b9d93fc1f035ec09330c2512a4879.png | Bin 328 -> 0 bytes ...tcuts-4b183486762cfcc9f0de7522520a5485.png | Bin 384 -> 0 bytes ...likes-27b8551da2d56d81062818c035ed622e.png | Bin 326 -> 0 bytes ...lists-ae69bf4fb26c40d2c9b056c55c9153e2.png | Bin 437 -> 0 bytes ...local-eade3ebeb7ac50f798cd40ed5fe62232.png | Bin 599 -> 0 bytes ..._open-c9627928caaaa505ac7de2a64bd065ec.svg | 4 - ...ogout-3abd28c4fc25290e6e4088c50d3352f4.png | Bin 383 -> 0 bytes ...mutes-5e7612d5c63fedb3fc59558284304cfc.png | Bin 411 -> 0 bytes ...n_add-5c56ef10b9e99e77a44d89041f4b77b5.svg | 4 - ...n_pin-79e04b07bcaa1266eee3164e83f574b4.png | Bin 337 -> 0 bytes ...ublic-2d798a39bb2bd6314e47b00669686556.png | Bin 688 -> 0 bytes ...reply-b5e28e1fe6acd4ec003e643e947f1c4a.svg | 4 - ...tings-e7c53fb8ee137f93827e2db21f507cb1.png | Bin 639 -> 0 bytes ...black-24a8608615e64fe9a08a898c25552819.svg | 1 - ...ached-26ffa26120a2a16a9be78a75cc603793.png | Bin 423 -> 0 bytes ..._done-e07ea253e82d137816cfb8d77a3b1562.png | Bin 253 -> 0 bytes ...email-ed5d2a37fa765e4c5fec080a82b0a783.png | Bin 387 -> 0 bytes ...nload-0b212ed1bca11e1e02539a20b3821d87.png | Bin 225 -> 0 bytes ...grade-1f9e039d0f024626ab071d18098b65a0.png | Bin 412 -> 0 bytes ..._open-d377f10d3f005d0d042a1ee1dee8284d.png | Bin 387 -> 0 bytes ...n_add-44d0a8dfa7dce95be5f6e3cfe0cdd133.png | Bin 376 -> 0 bytes ...reply-1c00f97d10006dd420bc620b26a79d8a.png | Bin 319 -> 0 bytes ...rning-af2b38fe580f274ca4c80479bd12141e.png | Bin 371 -> 0 bytes ...ybase-22af312ae5def3706736e6a014fdc761.png | Bin 12665 -> 0 bytes ...ticle-6490ecbb61185e86e62dca0845cf2dcf.png | Bin 2199 -> 0 bytes ...start-d443e819b6248a54c6eb466c75938306.png | Bin 263 -> 0 bytes .../void-4c8270c17facce6d53726a2ebb9745f2.png | Bin 174 -> 0 bytes priv/static/packs/modals/block_modal.js | 2 - priv/static/packs/modals/block_modal.js.map | 1 - priv/static/packs/modals/embed_modal.js | 2 - priv/static/packs/modals/embed_modal.js.map | 1 - priv/static/packs/modals/mute_modal.js | 2 - priv/static/packs/modals/mute_modal.js.map | 1 - priv/static/packs/modals/report_modal.js | 2 - priv/static/packs/modals/report_modal.js.map | 1 - priv/static/packs/ocr/tesseract-core.wasm.js | 21 - priv/static/packs/ocr/worker.min.js | 17 - .../packs/skins/glitch/contrast/common.css | 3 - .../skins/glitch/contrast/common.css.map | 1 - .../packs/skins/glitch/contrast/common.js | 2 - .../packs/skins/glitch/contrast/common.js.map | 1 - .../skins/glitch/mastodon-light/common.css | 3 - .../glitch/mastodon-light/common.css.map | 1 - .../skins/glitch/mastodon-light/common.js | 2 - .../skins/glitch/mastodon-light/common.js.map | 1 - .../packs/skins/vanilla/contrast/common.css | 3 - .../skins/vanilla/contrast/common.css.map | 1 - .../packs/skins/vanilla/contrast/common.js | 2 - .../skins/vanilla/contrast/common.js.map | 1 - .../skins/vanilla/mastodon-light/common.css | 3 - .../vanilla/mastodon-light/common.css.map | 1 - .../skins/vanilla/mastodon-light/common.js | 2 - .../vanilla/mastodon-light/common.js.map | 1 - .../packs/skins/vanilla/win95/common.css | 3 - .../packs/skins/vanilla/win95/common.css.map | 1 - .../packs/skins/vanilla/win95/common.js | 2 - .../packs/skins/vanilla/win95/common.js.map | 1 - priv/static/packs/tesseract.js | 3 - priv/static/packs/tesseract.js.LICENSE.txt | 8 - priv/static/packs/tesseract.js.map | 1 - priv/static/sw.js | 10 - priv/static/sw.js.map | 1 - 611 files changed, 1 insertion(+), 7958 deletions(-) delete mode 100644 lib/pleroma/web/masto_fe_controller.ex delete mode 100644 lib/pleroma/web/mastodon_api/controllers/auth_controller.ex delete mode 100644 lib/pleroma/web/templates/masto_fe/index.html.eex delete mode 100644 lib/pleroma/web/views/masto_fe_view.ex delete mode 100644 priv/static/packs/arrow-key-navigation.js delete mode 100644 priv/static/packs/arrow-key-navigation.js.map delete mode 100644 priv/static/packs/base_polyfills.js delete mode 100644 priv/static/packs/base_polyfills.js.LICENSE.txt delete mode 100644 priv/static/packs/base_polyfills.js.map delete mode 100644 priv/static/packs/common.js delete mode 100644 priv/static/packs/common.js.LICENSE.txt delete mode 100644 priv/static/packs/common.js.map delete mode 100644 priv/static/packs/containers/media_container.js delete mode 100644 priv/static/packs/containers/media_container.js.LICENSE.txt delete mode 100644 priv/static/packs/containers/media_container.js.map delete mode 100644 priv/static/packs/core/admin.js delete mode 100644 priv/static/packs/core/admin.js.map delete mode 100644 priv/static/packs/core/auth.js delete mode 100644 priv/static/packs/core/auth.js.LICENSE.txt delete mode 100644 priv/static/packs/core/auth.js.map delete mode 100644 priv/static/packs/core/common.css delete mode 100644 priv/static/packs/core/common.css.map delete mode 100644 priv/static/packs/core/common.js delete mode 100644 priv/static/packs/core/common.js.map delete mode 100644 priv/static/packs/core/embed.js delete mode 100644 priv/static/packs/core/embed.js.map delete mode 100644 priv/static/packs/core/mailer.css delete mode 100644 priv/static/packs/core/mailer.css.map delete mode 100644 priv/static/packs/core/mailer.js delete mode 100644 priv/static/packs/core/mailer.js.map delete mode 100644 priv/static/packs/core/modal.js delete mode 100644 priv/static/packs/core/modal.js.map delete mode 100644 priv/static/packs/core/public.js delete mode 100644 priv/static/packs/core/public.js.map delete mode 100644 priv/static/packs/core/settings.js delete mode 100644 priv/static/packs/core/settings.js.LICENSE.txt delete mode 100644 priv/static/packs/core/settings.js.map delete mode 100644 priv/static/packs/emoji_picker.js delete mode 100644 priv/static/packs/emoji_picker.js.map delete mode 100644 priv/static/packs/extra_polyfills.js delete mode 100644 priv/static/packs/extra_polyfills.js.LICENSE.txt delete mode 100644 priv/static/packs/extra_polyfills.js.map delete mode 100644 priv/static/packs/features/account_gallery.js delete mode 100644 priv/static/packs/features/account_gallery.js.map delete mode 100644 priv/static/packs/features/account_timeline.js delete mode 100644 priv/static/packs/features/account_timeline.js.map delete mode 100644 priv/static/packs/features/blocks.js delete mode 100644 priv/static/packs/features/blocks.js.map delete mode 100644 priv/static/packs/features/bookmarked_statuses.js delete mode 100644 priv/static/packs/features/bookmarked_statuses.js.map delete mode 100644 priv/static/packs/features/community_timeline.js delete mode 100644 priv/static/packs/features/community_timeline.js.map delete mode 100644 priv/static/packs/features/compose.js delete mode 100644 priv/static/packs/features/compose.js.map delete mode 100644 priv/static/packs/features/direct_timeline.js delete mode 100644 priv/static/packs/features/direct_timeline.js.map delete mode 100644 priv/static/packs/features/directory.js delete mode 100644 priv/static/packs/features/directory.js.map delete mode 100644 priv/static/packs/features/domain_blocks.js delete mode 100644 priv/static/packs/features/domain_blocks.js.map delete mode 100644 priv/static/packs/features/favourited_statuses.js delete mode 100644 priv/static/packs/features/favourited_statuses.js.map delete mode 100644 priv/static/packs/features/favourites.js delete mode 100644 priv/static/packs/features/favourites.js.map delete mode 100644 priv/static/packs/features/follow_requests.js delete mode 100644 priv/static/packs/features/follow_requests.js.map delete mode 100644 priv/static/packs/features/followers.js delete mode 100644 priv/static/packs/features/followers.js.map delete mode 100644 priv/static/packs/features/following.js delete mode 100644 priv/static/packs/features/following.js.map delete mode 100644 priv/static/packs/features/generic_not_found.js delete mode 100644 priv/static/packs/features/generic_not_found.js.map delete mode 100644 priv/static/packs/features/getting_started.js delete mode 100644 priv/static/packs/features/getting_started.js.map delete mode 100644 priv/static/packs/features/glitch/async/directory.js delete mode 100644 priv/static/packs/features/glitch/async/directory.js.map delete mode 100644 priv/static/packs/features/glitch/async/list_adder.js delete mode 100644 priv/static/packs/features/glitch/async/list_adder.js.map delete mode 100644 priv/static/packs/features/glitch/async/search.js delete mode 100644 priv/static/packs/features/glitch/async/search.js.map delete mode 100644 priv/static/packs/features/hashtag_timeline.js delete mode 100644 priv/static/packs/features/hashtag_timeline.js.map delete mode 100644 priv/static/packs/features/home_timeline.js delete mode 100644 priv/static/packs/features/home_timeline.js.map delete mode 100644 priv/static/packs/features/keyboard_shortcuts.js delete mode 100644 priv/static/packs/features/keyboard_shortcuts.js.map delete mode 100644 priv/static/packs/features/list_adder.js delete mode 100644 priv/static/packs/features/list_adder.js.map delete mode 100644 priv/static/packs/features/list_editor.js delete mode 100644 priv/static/packs/features/list_editor.js.map delete mode 100644 priv/static/packs/features/list_timeline.js delete mode 100644 priv/static/packs/features/list_timeline.js.map delete mode 100644 priv/static/packs/features/lists.js delete mode 100644 priv/static/packs/features/lists.js.map delete mode 100644 priv/static/packs/features/mutes.js delete mode 100644 priv/static/packs/features/mutes.js.map delete mode 100644 priv/static/packs/features/notifications.js delete mode 100644 priv/static/packs/features/notifications.js.map delete mode 100644 priv/static/packs/features/pinned_statuses.js delete mode 100644 priv/static/packs/features/pinned_statuses.js.map delete mode 100644 priv/static/packs/features/public_timeline.js delete mode 100644 priv/static/packs/features/public_timeline.js.map delete mode 100644 priv/static/packs/features/reblogs.js delete mode 100644 priv/static/packs/features/reblogs.js.map delete mode 100644 priv/static/packs/features/search.js delete mode 100644 priv/static/packs/features/search.js.map delete mode 100644 priv/static/packs/features/status.js delete mode 100644 priv/static/packs/features/status.js.map delete mode 100644 priv/static/packs/flavours/glitch/about.js delete mode 100644 priv/static/packs/flavours/glitch/about.js.LICENSE.txt delete mode 100644 priv/static/packs/flavours/glitch/about.js.map delete mode 100644 priv/static/packs/flavours/glitch/admin.js delete mode 100644 priv/static/packs/flavours/glitch/admin.js.LICENSE.txt delete mode 100644 priv/static/packs/flavours/glitch/admin.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/account_gallery.js delete mode 100644 priv/static/packs/flavours/glitch/async/account_gallery.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/account_timeline.js delete mode 100644 priv/static/packs/flavours/glitch/async/account_timeline.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/block_modal.js delete mode 100644 priv/static/packs/flavours/glitch/async/block_modal.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/blocks.js delete mode 100644 priv/static/packs/flavours/glitch/async/blocks.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/bookmarked_statuses.js delete mode 100644 priv/static/packs/flavours/glitch/async/bookmarked_statuses.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/community_timeline.js delete mode 100644 priv/static/packs/flavours/glitch/async/community_timeline.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/compose.js delete mode 100644 priv/static/packs/flavours/glitch/async/compose.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/direct_timeline.js delete mode 100644 priv/static/packs/flavours/glitch/async/direct_timeline.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/domain_blocks.js delete mode 100644 priv/static/packs/flavours/glitch/async/domain_blocks.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/embed_modal.js delete mode 100644 priv/static/packs/flavours/glitch/async/embed_modal.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/emoji_picker.js delete mode 100644 priv/static/packs/flavours/glitch/async/emoji_picker.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/favourited_statuses.js delete mode 100644 priv/static/packs/flavours/glitch/async/favourited_statuses.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/favourites.js delete mode 100644 priv/static/packs/flavours/glitch/async/favourites.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/follow_requests.js delete mode 100644 priv/static/packs/flavours/glitch/async/follow_requests.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/followers.js delete mode 100644 priv/static/packs/flavours/glitch/async/followers.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/following.js delete mode 100644 priv/static/packs/flavours/glitch/async/following.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/generic_not_found.js delete mode 100644 priv/static/packs/flavours/glitch/async/generic_not_found.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/getting_started.js delete mode 100644 priv/static/packs/flavours/glitch/async/getting_started.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/getting_started_misc.js delete mode 100644 priv/static/packs/flavours/glitch/async/getting_started_misc.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/hashtag_timeline.js delete mode 100644 priv/static/packs/flavours/glitch/async/hashtag_timeline.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/home_timeline.js delete mode 100644 priv/static/packs/flavours/glitch/async/home_timeline.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/keyboard_shortcuts.js delete mode 100644 priv/static/packs/flavours/glitch/async/keyboard_shortcuts.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/list_editor.js delete mode 100644 priv/static/packs/flavours/glitch/async/list_editor.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/list_timeline.js delete mode 100644 priv/static/packs/flavours/glitch/async/list_timeline.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/lists.js delete mode 100644 priv/static/packs/flavours/glitch/async/lists.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/mute_modal.js delete mode 100644 priv/static/packs/flavours/glitch/async/mute_modal.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/mutes.js delete mode 100644 priv/static/packs/flavours/glitch/async/mutes.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/notifications.js delete mode 100644 priv/static/packs/flavours/glitch/async/notifications.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/onboarding_modal.js delete mode 100644 priv/static/packs/flavours/glitch/async/onboarding_modal.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/pinned_accounts_editor.js delete mode 100644 priv/static/packs/flavours/glitch/async/pinned_accounts_editor.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/pinned_statuses.js delete mode 100644 priv/static/packs/flavours/glitch/async/pinned_statuses.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/public_timeline.js delete mode 100644 priv/static/packs/flavours/glitch/async/public_timeline.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/reblogs.js delete mode 100644 priv/static/packs/flavours/glitch/async/reblogs.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/report_modal.js delete mode 100644 priv/static/packs/flavours/glitch/async/report_modal.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/settings_modal.js delete mode 100644 priv/static/packs/flavours/glitch/async/settings_modal.js.map delete mode 100644 priv/static/packs/flavours/glitch/async/status.js delete mode 100644 priv/static/packs/flavours/glitch/async/status.js.map delete mode 100644 priv/static/packs/flavours/glitch/common.css delete mode 100644 priv/static/packs/flavours/glitch/common.css.map delete mode 100644 priv/static/packs/flavours/glitch/common.js delete mode 100644 priv/static/packs/flavours/glitch/common.js.map delete mode 100644 priv/static/packs/flavours/glitch/embed.js delete mode 100644 priv/static/packs/flavours/glitch/embed.js.LICENSE.txt delete mode 100644 priv/static/packs/flavours/glitch/embed.js.map delete mode 100644 priv/static/packs/flavours/glitch/error.js delete mode 100644 priv/static/packs/flavours/glitch/error.js.map delete mode 100644 priv/static/packs/flavours/glitch/home.js delete mode 100644 priv/static/packs/flavours/glitch/home.js.LICENSE.txt delete mode 100644 priv/static/packs/flavours/glitch/home.js.map delete mode 100644 priv/static/packs/flavours/glitch/public.js delete mode 100644 priv/static/packs/flavours/glitch/public.js.LICENSE.txt delete mode 100644 priv/static/packs/flavours/glitch/public.js.map delete mode 100644 priv/static/packs/flavours/glitch/settings.js delete mode 100644 priv/static/packs/flavours/glitch/settings.js.map delete mode 100644 priv/static/packs/flavours/glitch/share.js delete mode 100644 priv/static/packs/flavours/glitch/share.js.LICENSE.txt delete mode 100644 priv/static/packs/flavours/glitch/share.js.map delete mode 100644 priv/static/packs/flavours/vanilla/about.css delete mode 100644 priv/static/packs/flavours/vanilla/about.css.map delete mode 100644 priv/static/packs/flavours/vanilla/about.js delete mode 100644 priv/static/packs/flavours/vanilla/about.js.LICENSE.txt delete mode 100644 priv/static/packs/flavours/vanilla/about.js.map delete mode 100644 priv/static/packs/flavours/vanilla/admin.css delete mode 100644 priv/static/packs/flavours/vanilla/admin.css.map delete mode 100644 priv/static/packs/flavours/vanilla/admin.js delete mode 100644 priv/static/packs/flavours/vanilla/admin.js.LICENSE.txt delete mode 100644 priv/static/packs/flavours/vanilla/admin.js.map delete mode 100644 priv/static/packs/flavours/vanilla/common.css delete mode 100644 priv/static/packs/flavours/vanilla/common.css.map delete mode 100644 priv/static/packs/flavours/vanilla/common.js delete mode 100644 priv/static/packs/flavours/vanilla/common.js.map delete mode 100644 priv/static/packs/flavours/vanilla/embed.css delete mode 100644 priv/static/packs/flavours/vanilla/embed.css.map delete mode 100644 priv/static/packs/flavours/vanilla/embed.js delete mode 100644 priv/static/packs/flavours/vanilla/embed.js.LICENSE.txt delete mode 100644 priv/static/packs/flavours/vanilla/embed.js.map delete mode 100644 priv/static/packs/flavours/vanilla/error.js delete mode 100644 priv/static/packs/flavours/vanilla/error.js.map delete mode 100644 priv/static/packs/flavours/vanilla/home.css delete mode 100644 priv/static/packs/flavours/vanilla/home.css.map delete mode 100644 priv/static/packs/flavours/vanilla/home.js delete mode 100644 priv/static/packs/flavours/vanilla/home.js.LICENSE.txt delete mode 100644 priv/static/packs/flavours/vanilla/home.js.map delete mode 100644 priv/static/packs/flavours/vanilla/public.css delete mode 100644 priv/static/packs/flavours/vanilla/public.css.map delete mode 100644 priv/static/packs/flavours/vanilla/public.js delete mode 100644 priv/static/packs/flavours/vanilla/public.js.LICENSE.txt delete mode 100644 priv/static/packs/flavours/vanilla/public.js.map delete mode 100644 priv/static/packs/flavours/vanilla/settings.css delete mode 100644 priv/static/packs/flavours/vanilla/settings.css.map delete mode 100644 priv/static/packs/flavours/vanilla/settings.js delete mode 100644 priv/static/packs/flavours/vanilla/settings.js.LICENSE.txt delete mode 100644 priv/static/packs/flavours/vanilla/settings.js.map delete mode 100644 priv/static/packs/flavours/vanilla/share.css delete mode 100644 priv/static/packs/flavours/vanilla/share.css.map delete mode 100644 priv/static/packs/flavours/vanilla/share.js delete mode 100644 priv/static/packs/flavours/vanilla/share.js.LICENSE.txt delete mode 100644 priv/static/packs/flavours/vanilla/share.js.map delete mode 100644 priv/static/packs/locales.js delete mode 100644 priv/static/packs/locales.js.map delete mode 100644 priv/static/packs/locales/glitch/ar.js delete mode 100644 priv/static/packs/locales/glitch/ar.js.map delete mode 100644 priv/static/packs/locales/glitch/ast.js delete mode 100644 priv/static/packs/locales/glitch/ast.js.map delete mode 100644 priv/static/packs/locales/glitch/bg.js delete mode 100644 priv/static/packs/locales/glitch/bg.js.map delete mode 100644 priv/static/packs/locales/glitch/bn.js delete mode 100644 priv/static/packs/locales/glitch/bn.js.map delete mode 100644 priv/static/packs/locales/glitch/br.js delete mode 100644 priv/static/packs/locales/glitch/br.js.map delete mode 100644 priv/static/packs/locales/glitch/ca.js delete mode 100644 priv/static/packs/locales/glitch/ca.js.map delete mode 100644 priv/static/packs/locales/glitch/co.js delete mode 100644 priv/static/packs/locales/glitch/co.js.map delete mode 100644 priv/static/packs/locales/glitch/cs.js delete mode 100644 priv/static/packs/locales/glitch/cs.js.map delete mode 100644 priv/static/packs/locales/glitch/cy.js delete mode 100644 priv/static/packs/locales/glitch/cy.js.map delete mode 100644 priv/static/packs/locales/glitch/da.js delete mode 100644 priv/static/packs/locales/glitch/da.js.map delete mode 100644 priv/static/packs/locales/glitch/de.js delete mode 100644 priv/static/packs/locales/glitch/de.js.map delete mode 100644 priv/static/packs/locales/glitch/el.js delete mode 100644 priv/static/packs/locales/glitch/el.js.map delete mode 100644 priv/static/packs/locales/glitch/en.js delete mode 100644 priv/static/packs/locales/glitch/en.js.map delete mode 100644 priv/static/packs/locales/glitch/eo.js delete mode 100644 priv/static/packs/locales/glitch/eo.js.map delete mode 100644 priv/static/packs/locales/glitch/es-AR.js delete mode 100644 priv/static/packs/locales/glitch/es-AR.js.map delete mode 100644 priv/static/packs/locales/glitch/es.js delete mode 100644 priv/static/packs/locales/glitch/es.js.map delete mode 100644 priv/static/packs/locales/glitch/et.js delete mode 100644 priv/static/packs/locales/glitch/et.js.map delete mode 100644 priv/static/packs/locales/glitch/eu.js delete mode 100644 priv/static/packs/locales/glitch/eu.js.map delete mode 100644 priv/static/packs/locales/glitch/fa.js delete mode 100644 priv/static/packs/locales/glitch/fa.js.map delete mode 100644 priv/static/packs/locales/glitch/fi.js delete mode 100644 priv/static/packs/locales/glitch/fi.js.map delete mode 100644 priv/static/packs/locales/glitch/fr.js delete mode 100644 priv/static/packs/locales/glitch/fr.js.map delete mode 100644 priv/static/packs/locales/glitch/ga.js delete mode 100644 priv/static/packs/locales/glitch/ga.js.map delete mode 100644 priv/static/packs/locales/glitch/gl.js delete mode 100644 priv/static/packs/locales/glitch/gl.js.map delete mode 100644 priv/static/packs/locales/glitch/he.js delete mode 100644 priv/static/packs/locales/glitch/he.js.map delete mode 100644 priv/static/packs/locales/glitch/hi.js delete mode 100644 priv/static/packs/locales/glitch/hi.js.map delete mode 100644 priv/static/packs/locales/glitch/hr.js delete mode 100644 priv/static/packs/locales/glitch/hr.js.map delete mode 100644 priv/static/packs/locales/glitch/hu.js delete mode 100644 priv/static/packs/locales/glitch/hu.js.map delete mode 100644 priv/static/packs/locales/glitch/hy.js delete mode 100644 priv/static/packs/locales/glitch/hy.js.map delete mode 100644 priv/static/packs/locales/glitch/id.js delete mode 100644 priv/static/packs/locales/glitch/id.js.map delete mode 100644 priv/static/packs/locales/glitch/io.js delete mode 100644 priv/static/packs/locales/glitch/io.js.map delete mode 100644 priv/static/packs/locales/glitch/is.js delete mode 100644 priv/static/packs/locales/glitch/is.js.map delete mode 100644 priv/static/packs/locales/glitch/it.js delete mode 100644 priv/static/packs/locales/glitch/it.js.map delete mode 100644 priv/static/packs/locales/glitch/ja.js delete mode 100644 priv/static/packs/locales/glitch/ja.js.map delete mode 100644 priv/static/packs/locales/glitch/ka.js delete mode 100644 priv/static/packs/locales/glitch/ka.js.map delete mode 100644 priv/static/packs/locales/glitch/kab.js delete mode 100644 priv/static/packs/locales/glitch/kab.js.map delete mode 100644 priv/static/packs/locales/glitch/kk.js delete mode 100644 priv/static/packs/locales/glitch/kk.js.map delete mode 100644 priv/static/packs/locales/glitch/kn.js delete mode 100644 priv/static/packs/locales/glitch/kn.js.map delete mode 100644 priv/static/packs/locales/glitch/ko.js delete mode 100644 priv/static/packs/locales/glitch/ko.js.map delete mode 100644 priv/static/packs/locales/glitch/lt.js delete mode 100644 priv/static/packs/locales/glitch/lt.js.map delete mode 100644 priv/static/packs/locales/glitch/lv.js delete mode 100644 priv/static/packs/locales/glitch/lv.js.map delete mode 100644 priv/static/packs/locales/glitch/mk.js delete mode 100644 priv/static/packs/locales/glitch/mk.js.map delete mode 100644 priv/static/packs/locales/glitch/ml.js delete mode 100644 priv/static/packs/locales/glitch/ml.js.map delete mode 100644 priv/static/packs/locales/glitch/mr.js delete mode 100644 priv/static/packs/locales/glitch/mr.js.map delete mode 100644 priv/static/packs/locales/glitch/ms.js delete mode 100644 priv/static/packs/locales/glitch/ms.js.map delete mode 100644 priv/static/packs/locales/glitch/nl.js delete mode 100644 priv/static/packs/locales/glitch/nl.js.map delete mode 100644 priv/static/packs/locales/glitch/nn.js delete mode 100644 priv/static/packs/locales/glitch/nn.js.map delete mode 100644 priv/static/packs/locales/glitch/no.js delete mode 100644 priv/static/packs/locales/glitch/no.js.map delete mode 100644 priv/static/packs/locales/glitch/oc.js delete mode 100644 priv/static/packs/locales/glitch/oc.js.map delete mode 100644 priv/static/packs/locales/glitch/pl.js delete mode 100644 priv/static/packs/locales/glitch/pl.js.map delete mode 100644 priv/static/packs/locales/glitch/pt-BR.js delete mode 100644 priv/static/packs/locales/glitch/pt-BR.js.map delete mode 100644 priv/static/packs/locales/glitch/pt-PT.js delete mode 100644 priv/static/packs/locales/glitch/pt-PT.js.map delete mode 100644 priv/static/packs/locales/glitch/ro.js delete mode 100644 priv/static/packs/locales/glitch/ro.js.map delete mode 100644 priv/static/packs/locales/glitch/ru.js delete mode 100644 priv/static/packs/locales/glitch/ru.js.map delete mode 100644 priv/static/packs/locales/glitch/sk.js delete mode 100644 priv/static/packs/locales/glitch/sk.js.map delete mode 100644 priv/static/packs/locales/glitch/sl.js delete mode 100644 priv/static/packs/locales/glitch/sl.js.map delete mode 100644 priv/static/packs/locales/glitch/sq.js delete mode 100644 priv/static/packs/locales/glitch/sq.js.map delete mode 100644 priv/static/packs/locales/glitch/sr-Latn.js delete mode 100644 priv/static/packs/locales/glitch/sr-Latn.js.map delete mode 100644 priv/static/packs/locales/glitch/sr.js delete mode 100644 priv/static/packs/locales/glitch/sr.js.map delete mode 100644 priv/static/packs/locales/glitch/sv.js delete mode 100644 priv/static/packs/locales/glitch/sv.js.map delete mode 100644 priv/static/packs/locales/glitch/ta.js delete mode 100644 priv/static/packs/locales/glitch/ta.js.map delete mode 100644 priv/static/packs/locales/glitch/te.js delete mode 100644 priv/static/packs/locales/glitch/te.js.map delete mode 100644 priv/static/packs/locales/glitch/th.js delete mode 100644 priv/static/packs/locales/glitch/th.js.map delete mode 100644 priv/static/packs/locales/glitch/tr.js delete mode 100644 priv/static/packs/locales/glitch/tr.js.map delete mode 100644 priv/static/packs/locales/glitch/uk.js delete mode 100644 priv/static/packs/locales/glitch/uk.js.map delete mode 100644 priv/static/packs/locales/glitch/ur.js delete mode 100644 priv/static/packs/locales/glitch/ur.js.map delete mode 100644 priv/static/packs/locales/glitch/vi.js delete mode 100644 priv/static/packs/locales/glitch/vi.js.map delete mode 100644 priv/static/packs/locales/glitch/zh-CN.js delete mode 100644 priv/static/packs/locales/glitch/zh-CN.js.map delete mode 100644 priv/static/packs/locales/glitch/zh-HK.js delete mode 100644 priv/static/packs/locales/glitch/zh-HK.js.map delete mode 100644 priv/static/packs/locales/glitch/zh-TW.js delete mode 100644 priv/static/packs/locales/glitch/zh-TW.js.map delete mode 100644 priv/static/packs/locales/vanilla/ar.js delete mode 100644 priv/static/packs/locales/vanilla/ar.js.map delete mode 100644 priv/static/packs/locales/vanilla/ast.js delete mode 100644 priv/static/packs/locales/vanilla/ast.js.map delete mode 100644 priv/static/packs/locales/vanilla/bg.js delete mode 100644 priv/static/packs/locales/vanilla/bg.js.map delete mode 100644 priv/static/packs/locales/vanilla/bn.js delete mode 100644 priv/static/packs/locales/vanilla/bn.js.map delete mode 100644 priv/static/packs/locales/vanilla/br.js delete mode 100644 priv/static/packs/locales/vanilla/br.js.map delete mode 100644 priv/static/packs/locales/vanilla/ca.js delete mode 100644 priv/static/packs/locales/vanilla/ca.js.map delete mode 100644 priv/static/packs/locales/vanilla/co.js delete mode 100644 priv/static/packs/locales/vanilla/co.js.map delete mode 100644 priv/static/packs/locales/vanilla/cs.js delete mode 100644 priv/static/packs/locales/vanilla/cs.js.map delete mode 100644 priv/static/packs/locales/vanilla/cy.js delete mode 100644 priv/static/packs/locales/vanilla/cy.js.map delete mode 100644 priv/static/packs/locales/vanilla/da.js delete mode 100644 priv/static/packs/locales/vanilla/da.js.map delete mode 100644 priv/static/packs/locales/vanilla/de.js delete mode 100644 priv/static/packs/locales/vanilla/de.js.map delete mode 100644 priv/static/packs/locales/vanilla/el.js delete mode 100644 priv/static/packs/locales/vanilla/el.js.map delete mode 100644 priv/static/packs/locales/vanilla/en.js delete mode 100644 priv/static/packs/locales/vanilla/en.js.map delete mode 100644 priv/static/packs/locales/vanilla/eo.js delete mode 100644 priv/static/packs/locales/vanilla/eo.js.map delete mode 100644 priv/static/packs/locales/vanilla/es-AR.js delete mode 100644 priv/static/packs/locales/vanilla/es-AR.js.map delete mode 100644 priv/static/packs/locales/vanilla/es.js delete mode 100644 priv/static/packs/locales/vanilla/es.js.map delete mode 100644 priv/static/packs/locales/vanilla/et.js delete mode 100644 priv/static/packs/locales/vanilla/et.js.map delete mode 100644 priv/static/packs/locales/vanilla/eu.js delete mode 100644 priv/static/packs/locales/vanilla/eu.js.map delete mode 100644 priv/static/packs/locales/vanilla/fa.js delete mode 100644 priv/static/packs/locales/vanilla/fa.js.map delete mode 100644 priv/static/packs/locales/vanilla/fi.js delete mode 100644 priv/static/packs/locales/vanilla/fi.js.map delete mode 100644 priv/static/packs/locales/vanilla/fr.js delete mode 100644 priv/static/packs/locales/vanilla/fr.js.map delete mode 100644 priv/static/packs/locales/vanilla/ga.js delete mode 100644 priv/static/packs/locales/vanilla/ga.js.map delete mode 100644 priv/static/packs/locales/vanilla/gl.js delete mode 100644 priv/static/packs/locales/vanilla/gl.js.map delete mode 100644 priv/static/packs/locales/vanilla/he.js delete mode 100644 priv/static/packs/locales/vanilla/he.js.map delete mode 100644 priv/static/packs/locales/vanilla/hi.js delete mode 100644 priv/static/packs/locales/vanilla/hi.js.map delete mode 100644 priv/static/packs/locales/vanilla/hr.js delete mode 100644 priv/static/packs/locales/vanilla/hr.js.map delete mode 100644 priv/static/packs/locales/vanilla/hu.js delete mode 100644 priv/static/packs/locales/vanilla/hu.js.map delete mode 100644 priv/static/packs/locales/vanilla/hy.js delete mode 100644 priv/static/packs/locales/vanilla/hy.js.map delete mode 100644 priv/static/packs/locales/vanilla/id.js delete mode 100644 priv/static/packs/locales/vanilla/id.js.map delete mode 100644 priv/static/packs/locales/vanilla/io.js delete mode 100644 priv/static/packs/locales/vanilla/io.js.map delete mode 100644 priv/static/packs/locales/vanilla/is.js delete mode 100644 priv/static/packs/locales/vanilla/is.js.map delete mode 100644 priv/static/packs/locales/vanilla/it.js delete mode 100644 priv/static/packs/locales/vanilla/it.js.map delete mode 100644 priv/static/packs/locales/vanilla/ja.js delete mode 100644 priv/static/packs/locales/vanilla/ja.js.map delete mode 100644 priv/static/packs/locales/vanilla/ka.js delete mode 100644 priv/static/packs/locales/vanilla/ka.js.map delete mode 100644 priv/static/packs/locales/vanilla/kab.js delete mode 100644 priv/static/packs/locales/vanilla/kab.js.map delete mode 100644 priv/static/packs/locales/vanilla/kk.js delete mode 100644 priv/static/packs/locales/vanilla/kk.js.map delete mode 100644 priv/static/packs/locales/vanilla/kn.js delete mode 100644 priv/static/packs/locales/vanilla/kn.js.map delete mode 100644 priv/static/packs/locales/vanilla/ko.js delete mode 100644 priv/static/packs/locales/vanilla/ko.js.map delete mode 100644 priv/static/packs/locales/vanilla/lt.js delete mode 100644 priv/static/packs/locales/vanilla/lt.js.map delete mode 100644 priv/static/packs/locales/vanilla/lv.js delete mode 100644 priv/static/packs/locales/vanilla/lv.js.map delete mode 100644 priv/static/packs/locales/vanilla/mk.js delete mode 100644 priv/static/packs/locales/vanilla/mk.js.map delete mode 100644 priv/static/packs/locales/vanilla/ml.js delete mode 100644 priv/static/packs/locales/vanilla/ml.js.map delete mode 100644 priv/static/packs/locales/vanilla/mr.js delete mode 100644 priv/static/packs/locales/vanilla/mr.js.map delete mode 100644 priv/static/packs/locales/vanilla/ms.js delete mode 100644 priv/static/packs/locales/vanilla/ms.js.map delete mode 100644 priv/static/packs/locales/vanilla/nl.js delete mode 100644 priv/static/packs/locales/vanilla/nl.js.map delete mode 100644 priv/static/packs/locales/vanilla/nn.js delete mode 100644 priv/static/packs/locales/vanilla/nn.js.map delete mode 100644 priv/static/packs/locales/vanilla/no.js delete mode 100644 priv/static/packs/locales/vanilla/no.js.map delete mode 100644 priv/static/packs/locales/vanilla/oc.js delete mode 100644 priv/static/packs/locales/vanilla/oc.js.map delete mode 100644 priv/static/packs/locales/vanilla/pl.js delete mode 100644 priv/static/packs/locales/vanilla/pl.js.map delete mode 100644 priv/static/packs/locales/vanilla/pt-BR.js delete mode 100644 priv/static/packs/locales/vanilla/pt-BR.js.map delete mode 100644 priv/static/packs/locales/vanilla/pt-PT.js delete mode 100644 priv/static/packs/locales/vanilla/pt-PT.js.map delete mode 100644 priv/static/packs/locales/vanilla/ro.js delete mode 100644 priv/static/packs/locales/vanilla/ro.js.map delete mode 100644 priv/static/packs/locales/vanilla/ru.js delete mode 100644 priv/static/packs/locales/vanilla/ru.js.map delete mode 100644 priv/static/packs/locales/vanilla/sk.js delete mode 100644 priv/static/packs/locales/vanilla/sk.js.map delete mode 100644 priv/static/packs/locales/vanilla/sl.js delete mode 100644 priv/static/packs/locales/vanilla/sl.js.map delete mode 100644 priv/static/packs/locales/vanilla/sq.js delete mode 100644 priv/static/packs/locales/vanilla/sq.js.map delete mode 100644 priv/static/packs/locales/vanilla/sr-Latn.js delete mode 100644 priv/static/packs/locales/vanilla/sr-Latn.js.map delete mode 100644 priv/static/packs/locales/vanilla/sr.js delete mode 100644 priv/static/packs/locales/vanilla/sr.js.map delete mode 100644 priv/static/packs/locales/vanilla/sv.js delete mode 100644 priv/static/packs/locales/vanilla/sv.js.map delete mode 100644 priv/static/packs/locales/vanilla/ta.js delete mode 100644 priv/static/packs/locales/vanilla/ta.js.map delete mode 100644 priv/static/packs/locales/vanilla/te.js delete mode 100644 priv/static/packs/locales/vanilla/te.js.map delete mode 100644 priv/static/packs/locales/vanilla/th.js delete mode 100644 priv/static/packs/locales/vanilla/th.js.map delete mode 100644 priv/static/packs/locales/vanilla/tr.js delete mode 100644 priv/static/packs/locales/vanilla/tr.js.map delete mode 100644 priv/static/packs/locales/vanilla/uk.js delete mode 100644 priv/static/packs/locales/vanilla/uk.js.map delete mode 100644 priv/static/packs/locales/vanilla/ur.js delete mode 100644 priv/static/packs/locales/vanilla/ur.js.map delete mode 100644 priv/static/packs/locales/vanilla/vi.js delete mode 100644 priv/static/packs/locales/vanilla/vi.js.map delete mode 100644 priv/static/packs/locales/vanilla/zh-CN.js delete mode 100644 priv/static/packs/locales/vanilla/zh-CN.js.map delete mode 100644 priv/static/packs/locales/vanilla/zh-HK.js delete mode 100644 priv/static/packs/locales/vanilla/zh-HK.js.map delete mode 100644 priv/static/packs/locales/vanilla/zh-TW.js delete mode 100644 priv/static/packs/locales/vanilla/zh-TW.js.map delete mode 100644 priv/static/packs/manifest.json delete mode 100644 priv/static/packs/media/flavours/glitch/images/glitch-preview-bb9cc15a0102bfaf65712e5cff7e58df.jpg delete mode 100644 priv/static/packs/media/flavours/glitch/images/wave-drawer-ee1bfcbe5811ea31771b7187c7507ee6.png delete mode 100644 priv/static/packs/media/flavours/glitch/images/wave-drawer-glitched-33467bf8c8d2b995d6c76d8810aba3db.png delete mode 100644 priv/static/packs/media/fonts/fontawesome-webfont-674f50d2.eot delete mode 100644 priv/static/packs/media/fonts/fontawesome-webfont-912ec66d.svg delete mode 100644 priv/static/packs/media/fonts/fontawesome-webfont-af7ae505.woff2 delete mode 100644 priv/static/packs/media/fonts/fontawesome-webfont-b06871f2.ttf delete mode 100644 priv/static/packs/media/fonts/fontawesome-webfont-fee66e71.woff delete mode 100644 priv/static/packs/media/fonts/premillenium/MSSansSerif-a678e38bb3e20736cbed7a6925f24666.ttf delete mode 100644 priv/static/packs/media/images/clippy_frame-3446d4d28d72aef2f64f7fabae30eb4a.png delete mode 100644 priv/static/packs/media/images/clippy_wave-afb828463da264adbce26a3f17731f6c.gif delete mode 100644 priv/static/packs/media/images/icon_about-ffafc67a2e97ca436da6c1bf61a8ab68.png delete mode 100644 priv/static/packs/media/images/icon_blocks-0b0e54d45ff0177b02e1357ac09c0d51.png delete mode 100644 priv/static/packs/media/images/icon_cached-108e30d96e1d5152be7fe2978bcdfe14.svg delete mode 100644 priv/static/packs/media/images/icon_done-dba357bfbba455428787fefc655ce120.svg delete mode 100644 priv/static/packs/media/images/icon_email-1346985c7aaceb601b0d4257133254f4.svg delete mode 100644 priv/static/packs/media/images/icon_file_download-4b5c054e76b0df3cbbc851854cd10c3c.svg delete mode 100644 priv/static/packs/media/images/icon_flag-6cc7d5ce6f0c35fe10e0f05494b2aba8.svg delete mode 100644 priv/static/packs/media/images/icon_follow_requests-32eaf00987b072b2b12f8015d6a6a250.png delete mode 100644 priv/static/packs/media/images/icon_grade-8e81b8e88c2b5834347a2a226c65d440.svg delete mode 100644 priv/static/packs/media/images/icon_home-433b9d93fc1f035ec09330c2512a4879.png delete mode 100644 priv/static/packs/media/images/icon_keyboard_shortcuts-4b183486762cfcc9f0de7522520a5485.png delete mode 100644 priv/static/packs/media/images/icon_likes-27b8551da2d56d81062818c035ed622e.png delete mode 100644 priv/static/packs/media/images/icon_lists-ae69bf4fb26c40d2c9b056c55c9153e2.png delete mode 100644 priv/static/packs/media/images/icon_local-eade3ebeb7ac50f798cd40ed5fe62232.png delete mode 100644 priv/static/packs/media/images/icon_lock_open-c9627928caaaa505ac7de2a64bd065ec.svg delete mode 100644 priv/static/packs/media/images/icon_logout-3abd28c4fc25290e6e4088c50d3352f4.png delete mode 100644 priv/static/packs/media/images/icon_mutes-5e7612d5c63fedb3fc59558284304cfc.png delete mode 100644 priv/static/packs/media/images/icon_person_add-5c56ef10b9e99e77a44d89041f4b77b5.svg delete mode 100644 priv/static/packs/media/images/icon_pin-79e04b07bcaa1266eee3164e83f574b4.png delete mode 100644 priv/static/packs/media/images/icon_public-2d798a39bb2bd6314e47b00669686556.png delete mode 100644 priv/static/packs/media/images/icon_reply-b5e28e1fe6acd4ec003e643e947f1c4a.svg delete mode 100644 priv/static/packs/media/images/icon_settings-e7c53fb8ee137f93827e2db21f507cb1.png delete mode 100644 priv/static/packs/media/images/logo_transparent_black-24a8608615e64fe9a08a898c25552819.svg delete mode 100644 priv/static/packs/media/images/mailer/icon_cached-26ffa26120a2a16a9be78a75cc603793.png delete mode 100644 priv/static/packs/media/images/mailer/icon_done-e07ea253e82d137816cfb8d77a3b1562.png delete mode 100644 priv/static/packs/media/images/mailer/icon_email-ed5d2a37fa765e4c5fec080a82b0a783.png delete mode 100644 priv/static/packs/media/images/mailer/icon_file_download-0b212ed1bca11e1e02539a20b3821d87.png delete mode 100644 priv/static/packs/media/images/mailer/icon_grade-1f9e039d0f024626ab071d18098b65a0.png delete mode 100644 priv/static/packs/media/images/mailer/icon_lock_open-d377f10d3f005d0d042a1ee1dee8284d.png delete mode 100644 priv/static/packs/media/images/mailer/icon_person_add-44d0a8dfa7dce95be5f6e3cfe0cdd133.png delete mode 100644 priv/static/packs/media/images/mailer/icon_reply-1c00f97d10006dd420bc620b26a79d8a.png delete mode 100644 priv/static/packs/media/images/mailer/icon_warning-af2b38fe580f274ca4c80479bd12141e.png delete mode 100644 priv/static/packs/media/images/proof_providers/keybase-22af312ae5def3706736e6a014fdc761.png delete mode 100644 priv/static/packs/media/images/reticle-6490ecbb61185e86e62dca0845cf2dcf.png delete mode 100644 priv/static/packs/media/images/start-d443e819b6248a54c6eb466c75938306.png delete mode 100644 priv/static/packs/media/images/void-4c8270c17facce6d53726a2ebb9745f2.png delete mode 100644 priv/static/packs/modals/block_modal.js delete mode 100644 priv/static/packs/modals/block_modal.js.map delete mode 100644 priv/static/packs/modals/embed_modal.js delete mode 100644 priv/static/packs/modals/embed_modal.js.map delete mode 100644 priv/static/packs/modals/mute_modal.js delete mode 100644 priv/static/packs/modals/mute_modal.js.map delete mode 100644 priv/static/packs/modals/report_modal.js delete mode 100644 priv/static/packs/modals/report_modal.js.map delete mode 100644 priv/static/packs/ocr/tesseract-core.wasm.js delete mode 100644 priv/static/packs/ocr/worker.min.js delete mode 100644 priv/static/packs/skins/glitch/contrast/common.css delete mode 100644 priv/static/packs/skins/glitch/contrast/common.css.map delete mode 100644 priv/static/packs/skins/glitch/contrast/common.js delete mode 100644 priv/static/packs/skins/glitch/contrast/common.js.map delete mode 100644 priv/static/packs/skins/glitch/mastodon-light/common.css delete mode 100644 priv/static/packs/skins/glitch/mastodon-light/common.css.map delete mode 100644 priv/static/packs/skins/glitch/mastodon-light/common.js delete mode 100644 priv/static/packs/skins/glitch/mastodon-light/common.js.map delete mode 100644 priv/static/packs/skins/vanilla/contrast/common.css delete mode 100644 priv/static/packs/skins/vanilla/contrast/common.css.map delete mode 100644 priv/static/packs/skins/vanilla/contrast/common.js delete mode 100644 priv/static/packs/skins/vanilla/contrast/common.js.map delete mode 100644 priv/static/packs/skins/vanilla/mastodon-light/common.css delete mode 100644 priv/static/packs/skins/vanilla/mastodon-light/common.css.map delete mode 100644 priv/static/packs/skins/vanilla/mastodon-light/common.js delete mode 100644 priv/static/packs/skins/vanilla/mastodon-light/common.js.map delete mode 100644 priv/static/packs/skins/vanilla/win95/common.css delete mode 100644 priv/static/packs/skins/vanilla/win95/common.css.map delete mode 100644 priv/static/packs/skins/vanilla/win95/common.js delete mode 100644 priv/static/packs/skins/vanilla/win95/common.js.map delete mode 100644 priv/static/packs/tesseract.js delete mode 100644 priv/static/packs/tesseract.js.LICENSE.txt delete mode 100644 priv/static/packs/tesseract.js.map delete mode 100644 priv/static/sw.js delete mode 100644 priv/static/sw.js.map diff --git a/lib/pleroma/web/masto_fe_controller.ex b/lib/pleroma/web/masto_fe_controller.ex deleted file mode 100644 index e788ab37a..000000000 --- a/lib/pleroma/web/masto_fe_controller.ex +++ /dev/null @@ -1,65 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.MastoFEController do - use Pleroma.Web, :controller - - alias Pleroma.User - alias Pleroma.Web.MastodonAPI.AuthController - alias Pleroma.Web.OAuth.Token - alias Pleroma.Web.Plugs.EnsurePublicOrAuthenticatedPlug - alias Pleroma.Web.Plugs.OAuthScopesPlug - - plug(OAuthScopesPlug, %{scopes: ["write:accounts"]} when action == :put_settings) - - # Note: :index action handles attempt of unauthenticated access to private instance with redirect - plug(:skip_plug, EnsurePublicOrAuthenticatedPlug when action == :index) - - plug( - OAuthScopesPlug, - %{scopes: ["read"], fallback: :proceed_unauthenticated} - when action == :index - ) - - plug( - :skip_plug, - [OAuthScopesPlug, EnsurePublicOrAuthenticatedPlug] when action == :manifest - ) - - @doc "GET /web/*path" - def index(conn, _params) do - with %{assigns: %{user: %User{} = user, token: %Token{app_id: token_app_id} = token}} <- conn, - {:ok, %{id: ^token_app_id}} <- AuthController.local_mastofe_app() do - conn - |> put_layout(false) - |> render("index.html", - token: token.token, - user: user, - custom_emojis: Pleroma.Emoji.get_all() - ) - else - _ -> - conn - |> put_session(:return_to, conn.request_path) - |> redirect(to: "/web/login") - end - end - - @doc "GET /web/manifest.json" - def manifest(conn, _params) do - render(conn, "manifest.json") - end - - @doc "PUT /api/web/settings: Backend-obscure settings blob for MastoFE, don't parse/reuse elsewhere" - def put_settings(%{assigns: %{user: user}} = conn, %{"data" => settings} = _params) do - with {:ok, _} <- User.mastodon_settings_update(user, settings) do - json(conn, %{}) - else - e -> - conn - |> put_status(:internal_server_error) - |> json(%{error: inspect(e)}) - end - end -end diff --git a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex index dd3b39c77..70edbb085 100644 --- a/lib/pleroma/web/mastodon_api/controllers/app_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/app_controller.ex @@ -26,9 +26,7 @@ defmodule Pleroma.Web.MastodonAPI.AppController do ) plug(Pleroma.Web.ApiSpec.CastAndValidate) - - @local_mastodon_name "Mastodon-Local" - + defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.AppOperation @doc "POST /api/v1/apps" @@ -41,7 +39,6 @@ defmodule Pleroma.Web.MastodonAPI.AppController do |> Map.put(:scopes, scopes) with cs <- App.register_changeset(%App{}, app_attrs), - false <- cs.changes[:client_name] == @local_mastodon_name, {:ok, app} <- Repo.insert(cs) do render(conn, "show.json", app: app) end diff --git a/lib/pleroma/web/mastodon_api/controllers/auth_controller.ex b/lib/pleroma/web/mastodon_api/controllers/auth_controller.ex deleted file mode 100644 index eb6639fc5..000000000 --- a/lib/pleroma/web/mastodon_api/controllers/auth_controller.ex +++ /dev/null @@ -1,108 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.MastodonAPI.AuthController do - use Pleroma.Web, :controller - - import Pleroma.Web.ControllerHelper, only: [json_response: 3] - - alias Pleroma.Helpers.AuthHelper - alias Pleroma.Helpers.UriHelper - alias Pleroma.User - alias Pleroma.Web.OAuth.App - alias Pleroma.Web.OAuth.Authorization - alias Pleroma.Web.OAuth.Token - alias Pleroma.Web.OAuth.Token.Strategy.Revoke, as: RevokeToken - alias Pleroma.Web.TwitterAPI.TwitterAPI - - action_fallback(Pleroma.Web.MastodonAPI.FallbackController) - - plug(Pleroma.Web.Plugs.RateLimiter, [name: :password_reset] when action == :password_reset) - - @local_mastodon_name "Mastodon-Local" - - @doc "GET /web/login" - # Local Mastodon FE login callback action - def login(conn, %{"code" => auth_token} = params) do - with {:ok, app} <- local_mastofe_app(), - {:ok, auth} <- Authorization.get_by_token(app, auth_token), - {:ok, oauth_token} <- Token.exchange_token(app, auth) do - redirect_to = - conn - |> local_mastodon_post_login_path() - |> UriHelper.modify_uri_params(%{"access_token" => oauth_token.token}) - - conn - |> AuthHelper.put_session_token(oauth_token.token) - |> redirect(to: redirect_to) - else - _ -> redirect_to_oauth_form(conn, params) - end - end - - def login(conn, params) do - with %{assigns: %{user: %User{}, token: %Token{app_id: app_id}}} <- conn, - {:ok, %{id: ^app_id}} <- local_mastofe_app() do - redirect(conn, to: local_mastodon_post_login_path(conn)) - else - _ -> redirect_to_oauth_form(conn, params) - end - end - - defp redirect_to_oauth_form(conn, _params) do - with {:ok, app} <- local_mastofe_app() do - path = - o_auth_path(conn, :authorize, - response_type: "code", - client_id: app.client_id, - redirect_uri: ".", - scope: Enum.join(app.scopes, " ") - ) - - redirect(conn, to: path) - end - end - - @doc "DELETE /auth/sign_out" - def logout(conn, _) do - conn = - with %{assigns: %{token: %Token{} = oauth_token}} <- conn, - session_token = AuthHelper.get_session_token(conn), - {:ok, %Token{token: ^session_token}} <- RevokeToken.revoke(oauth_token) do - AuthHelper.delete_session_token(conn) - else - _ -> conn - end - - redirect(conn, to: "/") - end - - @doc "POST /auth/password" - def password_reset(conn, params) do - nickname_or_email = params["email"] || params["nickname"] - - TwitterAPI.password_reset(nickname_or_email) - - json_response(conn, :no_content, "") - end - - defp local_mastodon_post_login_path(conn) do - case get_session(conn, :return_to) do - nil -> - masto_fe_path(conn, :index, ["getting-started"]) - - return_to -> - delete_session(conn, :return_to) - return_to - end - end - - @spec local_mastofe_app() :: {:ok, App.t()} | {:error, Ecto.Changeset.t()} - def local_mastofe_app do - App.get_or_make( - %{client_name: @local_mastodon_name, redirect_uris: "."}, - ["read", "write", "follow", "push", "admin"] - ) - end -end diff --git a/lib/pleroma/web/o_auth/o_auth_controller.ex b/lib/pleroma/web/o_auth/o_auth_controller.ex index 215d97b3a..ae040c6eb 100644 --- a/lib/pleroma/web/o_auth/o_auth_controller.ex +++ b/lib/pleroma/web/o_auth/o_auth_controller.ex @@ -600,9 +600,6 @@ defmodule Pleroma.Web.OAuth.OAuthController do end end - # Special case: Local MastodonFE - defp redirect_uri(%Plug.Conn{} = conn, "."), do: auth_url(conn, :login) - defp redirect_uri(%Plug.Conn{}, redirect_uri), do: redirect_uri defp get_session_registration_id(%Plug.Conn{} = conn), do: get_session(conn, :registration_id) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index de0bd27d7..936053ee2 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -100,12 +100,6 @@ defmodule Pleroma.Web.Router do plug(Pleroma.Web.Plugs.IdempotencyPlug) end - pipeline :mastodon_html do - plug(:browser) - plug(:authenticate) - plug(:after_auth) - end - pipeline :pleroma_html do plug(:browser) plug(:authenticate) @@ -538,13 +532,6 @@ defmodule Pleroma.Web.Router do get("/timelines/list/:list_id", TimelineController, :list) end - scope "/api/web", Pleroma.Web do - pipe_through(:authenticated_api) - - # Backend-obscure settings blob for MastoFE, don't parse/reuse elsewhere - put("/settings", MastoFEController, :put_settings) - end - scope "/api/v1", Pleroma.Web.MastodonAPI do pipe_through(:app_api) @@ -745,25 +732,6 @@ defmodule Pleroma.Web.Router do get("/:version", Nodeinfo.NodeinfoController, :nodeinfo) end - scope "/", Pleroma.Web do - pipe_through(:api) - - get("/web/manifest.json", MastoFEController, :manifest) - end - - scope "/", Pleroma.Web do - pipe_through(:mastodon_html) - - get("/web/login", MastodonAPI.AuthController, :login) - delete("/auth/sign_out", MastodonAPI.AuthController, :logout) - - post("/auth/password", MastodonAPI.AuthController, :password_reset) - - get("/web/*path", MastoFEController, :index) - - get("/embed/:id", EmbedController, :show) - end - scope "/proxy/", Pleroma.Web.MediaProxy do get("/preview/:sig/:url", MediaProxyController, :preview) get("/preview/:sig/:url/:filename", MediaProxyController, :preview) diff --git a/lib/pleroma/web/templates/masto_fe/index.html.eex b/lib/pleroma/web/templates/masto_fe/index.html.eex deleted file mode 100644 index c330960fa..000000000 --- a/lib/pleroma/web/templates/masto_fe/index.html.eex +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - -<%= Config.get([:instance, :name]) %> - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - diff --git a/lib/pleroma/web/views/masto_fe_view.ex b/lib/pleroma/web/views/masto_fe_view.ex deleted file mode 100644 index b9055cb7f..000000000 --- a/lib/pleroma/web/views/masto_fe_view.ex +++ /dev/null @@ -1,91 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.MastoFEView do - use Pleroma.Web, :view - alias Pleroma.Config - alias Pleroma.User - alias Pleroma.Web.MastodonAPI.AccountView - alias Pleroma.Web.MastodonAPI.CustomEmojiView - - def initial_state(token, user, custom_emojis) do - limit = Config.get([:instance, :limit]) - - %{ - meta: %{ - streaming_api_base_url: Pleroma.Web.Endpoint.websocket_url(), - access_token: token, - locale: "en", - domain: Pleroma.Web.Endpoint.host(), - admin: "1", - me: "#{user.id}", - unfollow_modal: false, - boost_modal: false, - delete_modal: true, - auto_play_gif: false, - display_sensitive_media: false, - reduce_motion: false, - max_toot_chars: limit, - mascot: User.get_mascot(user)["url"] - }, - poll_limits: Config.get([:instance, :poll_limits]), - rights: %{ - delete_others_notice: present?(user.is_moderator), - admin: present?(user.is_admin) - }, - compose: %{ - me: "#{user.id}", - default_privacy: user.default_scope, - default_sensitive: false, - allow_content_types: Config.get([:instance, :allowed_post_formats]) - }, - media_attachments: %{ - accept_content_types: [ - ".jpg", - ".jpeg", - ".png", - ".gif", - ".webm", - ".mp4", - ".m4v", - "image\/jpeg", - "image\/png", - "image\/gif", - "video\/webm", - "video\/mp4" - ] - }, - settings: user.mastofe_settings || %{}, - push_subscription: nil, - accounts: %{user.id => render(AccountView, "show.json", user: user, for: user)}, - custom_emojis: render(CustomEmojiView, "index.json", custom_emojis: custom_emojis), - char_limit: limit - } - |> Jason.encode!() - |> Phoenix.HTML.raw() - end - - defp present?(nil), do: false - defp present?(false), do: false - defp present?(_), do: true - - def render("manifest.json", _params) do - %{ - name: Config.get([:instance, :name]), - description: Config.get([:instance, :description]), - icons: Config.get([:manifest, :icons]), - theme_color: Config.get([:manifest, :theme_color]), - background_color: Config.get([:manifest, :background_color]), - display: "standalone", - scope: Pleroma.Web.base_url(), - start_url: masto_fe_path(Pleroma.Web.Endpoint, :index, ["getting-started"]), - categories: [ - "social" - ], - serviceworker: %{ - src: "/sw.js" - } - } - end -end diff --git a/priv/static/packs/arrow-key-navigation.js b/priv/static/packs/arrow-key-navigation.js deleted file mode 100644 index 6f05ce3e1..000000000 --- a/priv/static/packs/arrow-key-navigation.js +++ /dev/null @@ -1,2 +0,0 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[2],{738:function(e,t,n){"use strict";n.r(t),n.d(t,"register",(function(){return s})),n.d(t,"setFocusTrapTest",(function(){return d})),n.d(t,"unregister",(function(){return l}));var r="a[href], area[href], input, select, textarea, button, iframe, object, embed, [contenteditable], [tabindex], video[controls], audio[controls], summary",o=["text","search","url","password","tel"],i=["checkbox","radio"],a=void 0;function c(e){for(var t=[],n=(function(e){if(!a)return;var t=e.parentElement;for(;t;){if(a(t))return t;t=t.parentElement}}(e)||document).querySelectorAll(r),o=n.length,i=0;i0||c.offsetHeight>0))||t.push(c)}return t}function u(e,t){var n=document.activeElement;if(!function(e,t){var n,r,i,a=e.tagName,c="TEXTAREA"===a,u="INPUT"===a&&-1!==o.indexOf(e.getAttribute("type").toLowerCase()),f=e.hasAttribute("contenteditable");if(!c&&!u&&!f)return!1;if(f){var s=getSelection();n=s.anchorOffset,r=s.focusOffset,i=e.textContent.length}else n=e.selectionStart,r=e.selectionEnd,i=e.value.length;return("ArrowLeft"!==t||n!==r||0!==n)&&("ArrowRight"!==t||n!==r||n!==i)}(n,t)){var r=c(n);if(r.length){var i=r.indexOf(n);("ArrowLeft"===t?r[i-1]||r[0]:r[i+1]||r[r.length-1]).focus(),e.preventDefault()}}}function f(e){if(!(e.altKey||e.metaKey||e.ctrlKey)){var t=e.key;switch(t){case"ArrowLeft":case"ArrowRight":u(e,t);break;case"Enter":!function(e){var t=document.activeElement;"INPUT"===t.tagName&&-1!==i.indexOf(t.getAttribute("type").toLowerCase())&&(t.click(),e.preventDefault())}(e)}}}function s(){addEventListener("keydown",f)}function l(){removeEventListener("keydown",f)}function d(e){a=e}}}]); -//# sourceMappingURL=arrow-key-navigation.js.map \ No newline at end of file diff --git a/priv/static/packs/arrow-key-navigation.js.map b/priv/static/packs/arrow-key-navigation.js.map deleted file mode 100644 index d5d0fc0ea..000000000 --- a/priv/static/packs/arrow-key-navigation.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["webpack:///./node_modules/arrow-key-navigation/dist-web/index.js"],"names":["focusablesQuery","textInputTypes","checkboxRadioInputTypes","focusTrapTest","undefined","getFocusableElements","activeElement","res","elements","element","parent","parentElement","getFocusTrapParent","document","querySelectorAll","len","length","i","disabled","test","getAttribute","hasAttribute","offsetWidth","offsetHeight","push","focusNextOrPrevious","event","key","selectionStart","selectionEnd","tagName","isTextarea","isTextInput","indexOf","toLowerCase","isContentEditable","selection","getSelection","anchorOffset","focusOffset","textContent","value","shouldIgnoreEvent","focusableElements","index","focus","preventDefault","keyListener","altKey","metaKey","ctrlKey","click","handleEnter","register","addEventListener","unregister","removeEventListener","setFocusTrapTest"],"mappings":"0FAAA,4IAQA,IAAIA,EAAkB,wJAKlBC,EAAiB,CAAC,OAAQ,SAAU,MAAO,WAAY,OACvDC,EAA0B,CAAC,WAAY,SACvCC,OAAgBC,EAEpB,SAASC,EAAqBC,GAQ5B,IANA,IAEIC,EAAM,GACNC,GAeN,SAA4BC,GAC1B,IAAKN,EACH,OAGF,IAAIO,EAASD,EAAQE,cAErB,KAAOD,GAAQ,CACb,GAAIP,EAAcO,GAChB,OAAOA,EAGTA,EAASA,EAAOC,eA9BCC,CAAmBN,IACXO,UAEPC,iBAAiBd,GACjCe,EAAMP,EAASQ,OAEVC,EAAI,EAAGA,EAAIF,EAAKE,IAAK,CAC5B,IAAIR,EAAUD,EAASS,GAEnBR,IAAYH,IAAkBG,EAAQS,UAAa,KAAKC,KAAKV,EAAQW,aAAa,aAAe,KAAQX,EAAQY,aAAa,YAClIZ,EAAQa,YAAc,GAAKb,EAAQc,aAAe,KAChDhB,EAAIiB,KAAKf,GAIb,OAAOF,EAuDT,SAASkB,EAAoBC,EAAOC,GAClC,IAAIrB,EAAgBO,SAASP,cAE7B,IAvCF,SAA2BA,EAAeqB,GACxC,IASIC,EACAC,EACAd,EAXAe,EAAUxB,EAAcwB,QACxBC,EAAyB,aAAZD,EACbE,EAA0B,UAAZF,IAAqG,IAA9E7B,EAAegC,QAAQ3B,EAAcc,aAAa,QAAQc,eAC/FC,EAAoB7B,EAAce,aAAa,mBAEnD,IAAKU,IAAeC,IAAgBG,EAClC,OAAO,EAOT,GAAIA,EAAmB,CACrB,IAAIC,EAAYC,eAChBT,EAAiBQ,EAAUE,aAC3BT,EAAeO,EAAUG,YACzBxB,EAAMT,EAAckC,YAAYxB,YAEhCY,EAAiBtB,EAAcsB,eAC/BC,EAAevB,EAAcuB,aAC7Bd,EAAMT,EAAcmC,MAAMzB,OAK5B,OAAY,cAARW,GAAuBC,IAAmBC,GAAmC,IAAnBD,KAE3C,eAARD,GAAwBC,IAAmBC,GAAgBD,IAAmBb,GAUrF2B,CAAkBpC,EAAeqB,GAArC,CAIA,IAAIgB,EAAoBtC,EAAqBC,GAE7C,GAAKqC,EAAkB3B,OAAvB,CAIA,IAAI4B,EAAQD,EAAkBV,QAAQ3B,IAG1B,cAARqB,EACQgB,EAAkBC,EAAQ,IAAMD,EAAkB,GAGlDA,EAAkBC,EAAQ,IAAMD,EAAkBA,EAAkB3B,OAAS,IAGjF6B,QACRnB,EAAMoB,mBAaR,SAASC,EAAYrB,GACnB,KAAIA,EAAMsB,QAAUtB,EAAMuB,SAAWvB,EAAMwB,SAA3C,CAIA,IAAIvB,EAAMD,EAAMC,IAEhB,OAAQA,GACN,IAAK,YACL,IAAK,aAEDF,EAAoBC,EAAOC,GAC3B,MAGJ,IAAK,SAzBT,SAAqBD,GACnB,IAAIpB,EAAgBO,SAASP,cAEC,UAA1BA,EAAcwB,UAA8G,IAAvF5B,EAAwB+B,QAAQ3B,EAAcc,aAAa,QAAQc,iBAE1G5B,EAAc6C,QACdzB,EAAMoB,kBAqBFM,CAAY1B,KAUpB,SAAS2B,IACPC,iBAAiB,UAAWP,GAO9B,SAASQ,IACPC,oBAAoB,UAAWT,GAUjC,SAASU,EAAiBtC,GACxBhB,EAAgBgB","file":"arrow-key-navigation.js","sourcesContent":["/**\n * Makes it so the left and right arrows change focus, ala Tab/Shift+Tab. This is mostly designed\n * for KaiOS devices.\n */\n\n/* global document, addEventListener, removeEventListener, getSelection */\n// This query is adapted from a11y-dialog\n// https://github.com/edenspiekermann/a11y-dialog/blob/cf4ed81/a11y-dialog.js#L6-L18\nvar focusablesQuery = 'a[href], area[href], input, select, textarea, ' + 'button, iframe, object, embed, [contenteditable], [tabindex], ' + 'video[controls], audio[controls], summary'; // TODO: email/number types are a special type, in that they return selectionStart/selectionEnd as null\n// As far as I can tell, there is no way to actually get the caret position from these inputs. So we\n// don't do the proper caret handling for those inputs, unfortunately.\n// https://html.spec.whatwg.org/multipage/input.html#do-not-apply\n\nvar textInputTypes = ['text', 'search', 'url', 'password', 'tel'];\nvar checkboxRadioInputTypes = ['checkbox', 'radio'];\nvar focusTrapTest = undefined;\n\nfunction getFocusableElements(activeElement) {\n // Respect focus trap inside of dialogs\n var dialogParent = getFocusTrapParent(activeElement);\n var root = dialogParent || document;\n var res = [];\n var elements = root.querySelectorAll(focusablesQuery);\n var len = elements.length;\n\n for (var i = 0; i < len; i++) {\n var element = elements[i];\n\n if (element === activeElement || !element.disabled && !/^-/.test(element.getAttribute('tabindex') || '') && !element.hasAttribute('inert') && ( // see https://github.com/GoogleChrome/inert-polyfill\n element.offsetWidth > 0 || element.offsetHeight > 0)) {\n res.push(element);\n }\n }\n\n return res;\n}\n\nfunction getFocusTrapParent(element) {\n if (!focusTrapTest) {\n return;\n }\n\n var parent = element.parentElement;\n\n while (parent) {\n if (focusTrapTest(parent)) {\n return parent;\n }\n\n parent = parent.parentElement;\n }\n}\n\nfunction shouldIgnoreEvent(activeElement, key) {\n var tagName = activeElement.tagName;\n var isTextarea = tagName === 'TEXTAREA';\n var isTextInput = tagName === 'INPUT' && textInputTypes.indexOf(activeElement.getAttribute('type').toLowerCase()) !== -1;\n var isContentEditable = activeElement.hasAttribute('contenteditable');\n\n if (!isTextarea && !isTextInput && !isContentEditable) {\n return false;\n }\n\n var selectionStart;\n var selectionEnd;\n var len;\n\n if (isContentEditable) {\n var selection = getSelection();\n selectionStart = selection.anchorOffset;\n selectionEnd = selection.focusOffset;\n len = activeElement.textContent.length;\n } else {\n selectionStart = activeElement.selectionStart;\n selectionEnd = activeElement.selectionEnd;\n len = activeElement.value.length;\n } // if the cursor is inside of a textarea/input, then don't focus to the next/previous element\n // unless the cursor is at the beginning or the end\n\n\n if (key === 'ArrowLeft' && selectionStart === selectionEnd && selectionStart === 0) {\n return false;\n } else if (key === 'ArrowRight' && selectionStart === selectionEnd && selectionStart === len) {\n return false;\n }\n\n return true;\n}\n\nfunction focusNextOrPrevious(event, key) {\n var activeElement = document.activeElement;\n\n if (shouldIgnoreEvent(activeElement, key)) {\n return;\n }\n\n var focusableElements = getFocusableElements(activeElement);\n\n if (!focusableElements.length) {\n return;\n }\n\n var index = focusableElements.indexOf(activeElement);\n var element;\n\n if (key === 'ArrowLeft') {\n element = focusableElements[index - 1] || focusableElements[0];\n } else {\n // ArrowRight\n element = focusableElements[index + 1] || focusableElements[focusableElements.length - 1];\n }\n\n element.focus();\n event.preventDefault();\n}\n\nfunction handleEnter(event) {\n var activeElement = document.activeElement;\n\n if (activeElement.tagName === 'INPUT' && checkboxRadioInputTypes.indexOf(activeElement.getAttribute('type').toLowerCase()) !== -1) {\n // Explicitly override \"enter\" on an input and make it fire the checkbox/radio\n activeElement.click();\n event.preventDefault();\n }\n}\n\nfunction keyListener(event) {\n if (event.altKey || event.metaKey || event.ctrlKey) {\n return; // ignore e.g. Alt-Left and Ctrl-Right, which are used to switch browser tabs or navigate back/forward\n }\n\n var key = event.key;\n\n switch (key) {\n case 'ArrowLeft':\n case 'ArrowRight':\n {\n focusNextOrPrevious(event, key);\n break;\n }\n\n case 'Enter':\n {\n handleEnter(event);\n break;\n }\n }\n}\n/**\n * Start listening for keyboard events. Attaches a listener to the window.\n */\n\n\nfunction register() {\n addEventListener('keydown', keyListener);\n}\n/**\n * Stop listening for keyboard events. Unattaches a listener to the window.\n */\n\n\nfunction unregister() {\n removeEventListener('keydown', keyListener);\n}\n/**\n * Set a focus trap test to identify any focus traps in the DOM, i.e. a top-level DOM node that indicates the root\n * of a focus trap. Once this is set, if focus changes within the focus trap, then will not leave the focus trap.\n * @param test: the test function\n * @see https://w3c.github.io/aria-practices/examples/dialog-modal/dialog.html\n */\n\n\nfunction setFocusTrapTest(test) {\n focusTrapTest = test;\n}\n\nexport { register, setFocusTrapTest, unregister };"],"sourceRoot":""} \ No newline at end of file diff --git a/priv/static/packs/base_polyfills.js b/priv/static/packs/base_polyfills.js deleted file mode 100644 index 04e0f921c..000000000 --- a/priv/static/packs/base_polyfills.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! For license information please see base_polyfills.js.LICENSE.txt */ -(window.webpackJsonp=window.webpackJsonp||[]).push([[3],{1050:function(e,r,t){"use strict";var n=TypeError,o=Object.getOwnPropertyDescriptor;if(o)try{o({},"")}catch(e){o=null}var a=function(){throw new n},i=o?function(){try{return arguments.callee,a}catch(e){try{return o(arguments,"callee").get}catch(e){return a}}}():a,s=t(1087)(),u=Object.getPrototypeOf||function(e){return e.__proto__},l=void 0,c="undefined"==typeof Uint8Array?void 0:u(Uint8Array),y={"%Array%":Array,"%ArrayBuffer%":"undefined"==typeof ArrayBuffer?void 0:ArrayBuffer,"%ArrayBufferPrototype%":"undefined"==typeof ArrayBuffer?void 0:ArrayBuffer.prototype,"%ArrayIteratorPrototype%":s?u([][Symbol.iterator]()):void 0,"%ArrayPrototype%":Array.prototype,"%ArrayProto_entries%":Array.prototype.entries,"%ArrayProto_forEach%":Array.prototype.forEach,"%ArrayProto_keys%":Array.prototype.keys,"%ArrayProto_values%":Array.prototype.values,"%AsyncFromSyncIteratorPrototype%":void 0,"%AsyncFunction%":void 0,"%AsyncFunctionPrototype%":void 0,"%AsyncGenerator%":void 0,"%AsyncGeneratorFunction%":void 0,"%AsyncGeneratorPrototype%":void 0,"%AsyncIteratorPrototype%":l&&s&&Symbol.asyncIterator?l[Symbol.asyncIterator]():void 0,"%Atomics%":"undefined"==typeof Atomics?void 0:Atomics,"%Boolean%":Boolean,"%BooleanPrototype%":Boolean.prototype,"%DataView%":"undefined"==typeof DataView?void 0:DataView,"%DataViewPrototype%":"undefined"==typeof DataView?void 0:DataView.prototype,"%Date%":Date,"%DatePrototype%":Date.prototype,"%decodeURI%":decodeURI,"%decodeURIComponent%":decodeURIComponent,"%encodeURI%":encodeURI,"%encodeURIComponent%":encodeURIComponent,"%Error%":Error,"%ErrorPrototype%":Error.prototype,"%eval%":eval,"%EvalError%":EvalError,"%EvalErrorPrototype%":EvalError.prototype,"%Float32Array%":"undefined"==typeof Float32Array?void 0:Float32Array,"%Float32ArrayPrototype%":"undefined"==typeof Float32Array?void 0:Float32Array.prototype,"%Float64Array%":"undefined"==typeof Float64Array?void 0:Float64Array,"%Float64ArrayPrototype%":"undefined"==typeof Float64Array?void 0:Float64Array.prototype,"%Function%":Function,"%FunctionPrototype%":Function.prototype,"%Generator%":void 0,"%GeneratorFunction%":void 0,"%GeneratorPrototype%":void 0,"%Int8Array%":"undefined"==typeof Int8Array?void 0:Int8Array,"%Int8ArrayPrototype%":"undefined"==typeof Int8Array?void 0:Int8Array.prototype,"%Int16Array%":"undefined"==typeof Int16Array?void 0:Int16Array,"%Int16ArrayPrototype%":"undefined"==typeof Int16Array?void 0:Int8Array.prototype,"%Int32Array%":"undefined"==typeof Int32Array?void 0:Int32Array,"%Int32ArrayPrototype%":"undefined"==typeof Int32Array?void 0:Int32Array.prototype,"%isFinite%":isFinite,"%isNaN%":isNaN,"%IteratorPrototype%":s?u(u([][Symbol.iterator]())):void 0,"%JSON%":"object"==typeof JSON?JSON:void 0,"%JSONParse%":"object"==typeof JSON?JSON.parse:void 0,"%Map%":"undefined"==typeof Map?void 0:Map,"%MapIteratorPrototype%":"undefined"!=typeof Map&&s?u((new Map)[Symbol.iterator]()):void 0,"%MapPrototype%":"undefined"==typeof Map?void 0:Map.prototype,"%Math%":Math,"%Number%":Number,"%NumberPrototype%":Number.prototype,"%Object%":Object,"%ObjectPrototype%":Object.prototype,"%ObjProto_toString%":Object.prototype.toString,"%ObjProto_valueOf%":Object.prototype.valueOf,"%parseFloat%":parseFloat,"%parseInt%":parseInt,"%Promise%":"undefined"==typeof Promise?void 0:Promise,"%PromisePrototype%":"undefined"==typeof Promise?void 0:Promise.prototype,"%PromiseProto_then%":"undefined"==typeof Promise?void 0:Promise.prototype.then,"%Promise_all%":"undefined"==typeof Promise?void 0:Promise.all,"%Promise_reject%":"undefined"==typeof Promise?void 0:Promise.reject,"%Promise_resolve%":"undefined"==typeof Promise?void 0:Promise.resolve,"%Proxy%":"undefined"==typeof Proxy?void 0:Proxy,"%RangeError%":RangeError,"%RangeErrorPrototype%":RangeError.prototype,"%ReferenceError%":ReferenceError,"%ReferenceErrorPrototype%":ReferenceError.prototype,"%Reflect%":"undefined"==typeof Reflect?void 0:Reflect,"%RegExp%":RegExp,"%RegExpPrototype%":RegExp.prototype,"%Set%":"undefined"==typeof Set?void 0:Set,"%SetIteratorPrototype%":"undefined"!=typeof Set&&s?u((new Set)[Symbol.iterator]()):void 0,"%SetPrototype%":"undefined"==typeof Set?void 0:Set.prototype,"%SharedArrayBuffer%":"undefined"==typeof SharedArrayBuffer?void 0:SharedArrayBuffer,"%SharedArrayBufferPrototype%":"undefined"==typeof SharedArrayBuffer?void 0:SharedArrayBuffer.prototype,"%String%":String,"%StringIteratorPrototype%":s?u(""[Symbol.iterator]()):void 0,"%StringPrototype%":String.prototype,"%Symbol%":s?Symbol:void 0,"%SymbolPrototype%":s?Symbol.prototype:void 0,"%SyntaxError%":SyntaxError,"%SyntaxErrorPrototype%":SyntaxError.prototype,"%ThrowTypeError%":i,"%TypedArray%":c,"%TypedArrayPrototype%":c?c.prototype:void 0,"%TypeError%":n,"%TypeErrorPrototype%":n.prototype,"%Uint8Array%":"undefined"==typeof Uint8Array?void 0:Uint8Array,"%Uint8ArrayPrototype%":"undefined"==typeof Uint8Array?void 0:Uint8Array.prototype,"%Uint8ClampedArray%":"undefined"==typeof Uint8ClampedArray?void 0:Uint8ClampedArray,"%Uint8ClampedArrayPrototype%":"undefined"==typeof Uint8ClampedArray?void 0:Uint8ClampedArray.prototype,"%Uint16Array%":"undefined"==typeof Uint16Array?void 0:Uint16Array,"%Uint16ArrayPrototype%":"undefined"==typeof Uint16Array?void 0:Uint16Array.prototype,"%Uint32Array%":"undefined"==typeof Uint32Array?void 0:Uint32Array,"%Uint32ArrayPrototype%":"undefined"==typeof Uint32Array?void 0:Uint32Array.prototype,"%URIError%":URIError,"%URIErrorPrototype%":URIError.prototype,"%WeakMap%":"undefined"==typeof WeakMap?void 0:WeakMap,"%WeakMapPrototype%":"undefined"==typeof WeakMap?void 0:WeakMap.prototype,"%WeakSet%":"undefined"==typeof WeakSet?void 0:WeakSet,"%WeakSetPrototype%":"undefined"==typeof WeakSet?void 0:WeakSet.prototype},p=t(1060).call(Function.call,String.prototype.replace),f=/[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g,d=/\\(\\)?/g,h=function(e){var r=[];return p(e,f,(function(e,t,n,o){r[r.length]=n?p(o,d,"$1"):t||e})),r},m=function(e,r){if(!(e in y))throw new SyntaxError("intrinsic "+e+" does not exist!");if(void 0===y[e]&&!r)throw new n("intrinsic "+e+" exists, but is not available. Please file an issue!");return y[e]};e.exports=function(e,r){if("string"!=typeof e||0===e.length)throw new TypeError("intrinsic name must be a non-empty string");if(arguments.length>1&&"boolean"!=typeof r)throw new TypeError('"allowMissing" argument must be a boolean');for(var t=h(e),n=m("%"+(t.length>0?t[0]:"")+"%",r),a=1;a=t.length){var i=o(n,t[a]);n=i?i.get||i.value:n[t[a]]}else n=n[t[a]];return n}},1051:function(e,r,t){"use strict";var n=t(1205),o="function"==typeof Symbol&&"symbol"==typeof Symbol("foo"),a=Object.prototype.toString,i=Array.prototype.concat,s=Object.defineProperty,u=s&&function(){var e={};try{for(var r in s(e,"x",{enumerable:!1,value:e}),e)return!1;return e.x===e}catch(e){return!1}}(),l=function(e,r,t,n){var o;r in e&&("function"!=typeof(o=n)||"[object Function]"!==a.call(o)||!n())||(u?s(e,r,{configurable:!0,enumerable:!1,value:t,writable:!0}):e[r]=t)},c=function(e,r){var t=arguments.length>2?arguments[2]:{},a=n(r);o&&(a=i.call(a,Object.getOwnPropertySymbols(r)));for(var s=0;s=0&&"[object Function]"===n.call(e.callee)),t}},1115:function(e,r,t){"use strict";e.exports=t(1116)},1116:function(e,r,t){"use strict";var n=t(1050)("%TypeError%");e.exports=function(e,r){if(null==e)throw new n(r||"Cannot call method on "+e);return e}},1117:function(e,r,t){"use strict";var n=t(1060),o=t(1050)("%Function%"),a=o.apply,i=o.call;e.exports=function(){return n.apply(i,arguments)},e.exports.apply=function(){return n.apply(a,arguments)}},1118:function(e,r,t){"use strict";var n=t(1119),o=t(1220),a=t(1222),i=t(1223),s=t(1088),u=t(1120),l=t(1050),c=t(1069),y=t(1224),p=c("String.prototype.charAt"),f=l("%Array.prototype.indexOf%");e.exports=function(e){var r=arguments.length>1?n(arguments[1]):0;if(f&&!s(e)&&u(r)&&void 0!==e)return f.apply(this,arguments)>-1;var t=a(this),l=o(t.length);if(0===l)return!1;for(var c=r>=0?r:Math.max(0,l+r);c1){for(var u=Array(i),l=0;l=0||Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t},possibleConstructorReturn:function(e,r){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!r||"object"!=typeof r&&"function"!=typeof r?e:r},selfGlobal:u,set:function e(r,t,n,o){var a=Object.getOwnPropertyDescriptor(r,t);if(void 0===a){var i=Object.getPrototypeOf(r);null!==i&&e(i,t,n,o)}else if("value"in a&&a.writable)a.value=n;else{var s=a.set;void 0!==s&&s.call(o,n)}return n},slicedToArray:l,slicedToArrayLoose:function(e,r){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e)){for(var t,n=[],o=e[Symbol.iterator]();!(t=o.next()).done&&(n.push(t.value),!r||n.length!==r););return n}throw new TypeError("Invalid attempt to destructure non-iterable instance")},taggedTemplateLiteral:function(e,r){return Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(r)}}))},taggedTemplateLiteralLoose:function(e,r){return e.raw=r,e},temporalRef:function(e,r,t){if(e===t)throw new ReferenceError(r+" is not defined - temporal dead zone");return e},temporalUndefined:{},toArray:function(e){return Array.isArray(e)?e:Array.from(e)},toConsumableArray:function(e){if(Array.isArray(e)){for(var r=0,t=Array(e.length);r="a"&&t<="z"&&(e=e.slice(0,r)+t.toUpperCase()+e.slice(r+1))}return e}function J(e){return!!D.test(e)&&(!I.test(e)&&!R.test(e))}function U(e){for(var r=void 0,t=void 0,n=1,o=(t=(e=e.toLowerCase()).split("-")).length;n1&&(r.sort(),e=e.replace(RegExp("(?:"+z.source+")+","i"),w.call(r,""))),f.call(C.tags,e)&&(e=C.tags[e]);for(var a=1,i=(t=e.split("-")).length;a-1)return t;var n=t.lastIndexOf("-");if(n<0)return;n>=2&&"-"===t.charAt(n-2)&&(n-=2),t=t.substring(0,n)}}function $(e,r){for(var t=0,n=r.length,o=void 0,a=void 0,i=void 0;t2){var M=s[S+1];-1!==w.call(g,M)&&(b="-"+m+"-"+(v=M))}else{-1!==w(g,"true")&&(v="true")}}if(f.call(t,"[["+m+"]]")){var k=t["[["+m+"]]"];-1!==w.call(g,k)&&k!==v&&(v=k,b="")}c["[["+m+"]]"]=v,y+=b,p++}if(y.length>2){var A=i.indexOf("-x-");if(-1===A)i+=y;else{var E=i.substring(0,A),P=i.substring(A);i=E+y+P}i=U(i)}return c["[[locale]]"]=i,c}function Y(e,r){for(var t=r.length,n=new E,o=0;on)throw new RangeError("Value is not a number or outside accepted range");return Math.floor(a)}return o}var X={};Object.defineProperty(X,"getCanonicalLocales",{enumerable:!1,configurable:!0,writable:!0,value:function(e){for(var r=L(e),t=[],n=r.length,o=0;o-1&&ly){var d=s.substring(y,l);b.call(u,{"[[type]]":"literal","[[value]]":d})}var h=s.substring(l+1,c);if("number"===h)if(isNaN(r)){var m=i.nan;b.call(u,{"[[type]]":"nan","[[value]]":m})}else if(isFinite(r)){"percent"===t["[[style]]"]&&isFinite(r)&&(r*=100);var g=void 0;g=f.call(t,"[[minimumSignificantDigits]]")&&f.call(t,"[[maximumSignificantDigits]]")?ae(r,t["[[minimumSignificantDigits]]"],t["[[maximumSignificantDigits]]"]):ie(r,t["[[minimumIntegerDigits]]"],t["[[minimumFractionDigits]]"],t["[[maximumFractionDigits]]"]),se[o]?function(){var e=se[o];g=String(g).replace(/\d/g,(function(r){return e[r]}))}():g=String(g);var v=void 0,w=void 0,M=g.indexOf(".",0);if(M>0?(v=g.substring(0,M),w=g.substring(M+1,M.length)):(v=g,w=void 0),!0===t["[[useGrouping]]"]){var A=i.group,j=[],P=a.patterns.primaryGroupSize||3,T=a.patterns.secondaryGroupSize||P;if(v.length>P){var O=v.length-P,x=O%T,K=v.slice(0,x);for(K.length&&b.call(j,K);xo;o++){n+=t[o]["[[value]]"]}return n}function ae(e,r,t){var n=t,o=void 0,a=void 0;if(0===e)o=w.call(Array(n+1),"0"),a=0;else{a=function(e){if("function"==typeof Math.log10)return Math.floor(Math.log10(e));var r=Math.round(Math.log(e)*Math.LOG10E);return r-(Number("1e"+r)>e)}(Math.abs(e));var i=Math.round(Math.exp(Math.abs(a-n+1)*Math.LN10));o=String(Math.round(a-n+1<0?e*i:e/i))}if(a>=n)return o+w.call(Array(a-n+1+1),"0");if(a===n-1)return o;if(a>=0?o=o.slice(0,a+1)+"."+o.slice(a+1):a<0&&(o="0."+w.call(Array(1-(a+1)),"0")+o),o.indexOf(".")>=0&&t>r){for(var s=t-r;s>0&&"0"===o.charAt(o.length-1);)o=o.slice(0,-1),s--;"."===o.charAt(o.length-1)&&(o=o.slice(0,-1))}return o}function ie(e,r,t,n){var o,a=n,i=Math.pow(10,a)*e,s=0===i?"0":i.toFixed(0),u=(o=s.indexOf("e"))>-1?s.slice(o+1):0;u&&(s=s.slice(0,o).replace(".",""),s+=w.call(Array(u-(s.length-1)+1),"0"));var l=void 0;if(0!==a){var c=s.length;if(c<=a)s=w.call(Array(a+1-c+1),"0")+s,c=a+1;var y=s.substring(0,c-a),p=s.substring(c-a,s.length);s=y+"."+p,l=y.length}else l=s.length;for(var f=n-t;f>0&&"0"===s.slice(-1);)s=s.slice(0,-1),f--;("."===s.slice(-1)&&(s=s.slice(0,-1)),la;a++){var i=t[a],s={};s.type=i["[[type]]"],s.value=i["[[value]]"],n[o]=s,o+=1}return n}(this,Number(e))}});var se={arab:["٠","١","٢","٣","٤","٥","٦","٧","٨","٩"],arabext:["۰","۱","۲","۳","۴","۵","۶","۷","۸","۹"],bali:["᭐","᭑","᭒","᭓","᭔","᭕","᭖","᭗","᭘","᭙"],beng:["০","১","২","৩","৪","৫","৬","৭","৮","৯"],deva:["०","१","२","३","४","५","६","७","८","९"],fullwide:["0","1","2","3","4","5","6","7","8","9"],gujr:["૦","૧","૨","૩","૪","૫","૬","૭","૮","૯"],guru:["੦","੧","੨","੩","੪","੫","੬","੭","੮","੯"],hanidec:["〇","一","二","三","四","五","六","七","八","九"],khmr:["០","១","២","៣","៤","៥","៦","៧","៨","៩"],knda:["೦","೧","೨","೩","೪","೫","೬","೭","೮","೯"],laoo:["໐","໑","໒","໓","໔","໕","໖","໗","໘","໙"],latn:["0","1","2","3","4","5","6","7","8","9"],limb:["᥆","᥇","᥈","᥉","᥊","᥋","᥌","᥍","᥎","᥏"],mlym:["൦","൧","൨","൩","൪","൫","൬","൭","൮","൯"],mong:["᠐","᠑","᠒","᠓","᠔","᠕","᠖","᠗","᠘","᠙"],mymr:["၀","၁","၂","၃","၄","၅","၆","၇","၈","၉"],orya:["୦","୧","୨","୩","୪","୫","୬","୭","୮","୯"],tamldec:["௦","௧","௨","௩","௪","௫","௬","௭","௮","௯"],telu:["౦","౧","౨","౩","౪","౫","౬","౭","౮","౯"],thai:["๐","๑","๒","๓","๔","๕","๖","๗","๘","๙"],tibt:["༠","༡","༢","༣","༤","༥","༦","༧","༨","༩"]};d(X.NumberFormat.prototype,"resolvedOptions",{configurable:!0,writable:!0,value:function(){var e=void 0,r=new j,t=["locale","numberingSystem","style","currency","currencyDisplay","minimumIntegerDigits","minimumFractionDigits","maximumFractionDigits","minimumSignificantDigits","maximumSignificantDigits","useGrouping"],n=null!==this&&"object"===c.typeof(this)&&F(this);if(!n||!n["[[initializedNumberFormat]]"])throw new TypeError("`this` value for resolvedOptions() is not an initialized Intl.NumberFormat object.");for(var o=0,a=t.length;ot&&(t=s,n=i),o++}return n}(s,M);else{var T=V(t,"hour12","boolean");s.hour12=void 0===T?S.hour12:T,w=function(e,r){var t=[];for(var n in ke)f.call(ke,n)&&void 0!==e["[["+n+"]]"]&&t.push(n);if(1===t.length){var o=function(e,r){var t;if(be[e]&&be[e][r])return t={originalPattern:be[e][r],_:i({},e,r),extendedPattern:"{"+e+"}"},i(t,e,r),i(t,"pattern12","{"+e+"}"),i(t,"pattern","{"+e+"}"),t}(t[0],e["[["+t[0]+"]]"]);if(o)return o}var a=-1/0,s=void 0,u=0,l=r.length;for(;u=2||w>=2&&b<=1?S>0?y-=6:S<0&&(y-=8):S>1?y-=3:S<-1&&(y-=6)}}c._.hour12!==e.hour12&&(y-=1),y>a&&(a=y,s=c),u++}return s}(s,M)}for(var O in ke)if(f.call(ke,O)&&f.call(w,O)){var x=w[O];x=w._&&f.call(w._,O)?w._[O]:x,n["[["+O+"]]"]=x}var K=void 0,N=V(t,"hour12","boolean");if(n["[[hour]]"])if(N=void 0===N?S.hour12:N,n["[[hour12]]"]=N,!0===N){var D=S.hourNo0;n["[[hourNo0]]"]=D,K=w.pattern12}else K=w.pattern;else K=w.pattern;n["[[pattern]]"]=K,n["[[boundFormat]]"]=void 0,n["[[initializedDateTimeFormat]]"]=!0,p&&(e.format=je.call(e));return o(),e}(T(this),e,r):new X.DateTimeFormat(e,r)}d(X,"DateTimeFormat",{configurable:!0,writable:!0,value:Me}),d(Me,"prototype",{writable:!1});var ke={weekday:["narrow","short","long"],era:["narrow","short","long"],year:["2-digit","numeric"],month:["2-digit","numeric","narrow","short","long"],day:["2-digit","numeric"],hour:["2-digit","numeric"],minute:["2-digit","numeric"],second:["2-digit","numeric"],timeZoneName:["short","long"]};function Ae(e,r,t){if(void 0===e)e=null;else{var n=T(e);for(var o in e=new j,n)e[o]=n[o]}e=m(e);var a=!0;return"date"!==r&&"any"!==r||void 0===e.weekday&&void 0===e.year&&void 0===e.month&&void 0===e.day||(a=!1),"time"!==r&&"any"!==r||void 0===e.hour&&void 0===e.minute&&void 0===e.second||(a=!1),!a||"date"!==t&&"all"!==t||(e.year=e.month=e.day="numeric"),!a||"time"!==t&&"all"!==t||(e.hour=e.minute=e.second="numeric"),e}function je(){var e=null!==this&&"object"===c.typeof(this)&&F(this);if(!e||!e["[[initializedDateTimeFormat]]"])throw new TypeError("`this` value for format() is not an initialized Intl.DateTimeFormat object.");if(void 0===e["[[boundFormat]]"]){var r=M.call((function(){var e=arguments.length<=0||void 0===arguments[0]?void 0:arguments[0],r=void 0===e?Date.now():O(e);return Pe(this,r)}),this);e["[[boundFormat]]"]=r}return e["[[boundFormat]]"]}function Ee(e,r){if(!isFinite(r))throw new RangeError("Invalid valid date passed to format");var t=e.__getInternalProperties(A);P();for(var n,o,a,i,s=t["[[locale]]"],u=new X.NumberFormat([s],{useGrouping:!1}),l=new X.NumberFormat([s],{minimumIntegerDigits:2,useGrouping:!1}),c=(n=r,t["[[calendar]]"],o=t["[[timeZone]]"],new j({"[[weekday]]":(a=new Date(n))[(i="get"+(o||""))+"Day"](),"[[era]]":+(a[i+"FullYear"]()>=0),"[[year]]":a[i+"FullYear"](),"[[month]]":a[i+"Month"](),"[[day]]":a[i+"Date"](),"[[hour]]":a[i+"Hours"](),"[[minute]]":a[i+"Minutes"](),"[[second]]":a[i+"Seconds"](),"[[inDST]]":!1})),y=t["[[pattern]]"],p=new E,f=0,d=y.indexOf("{"),h=0,m=t["[[dataLocale]]"],g=k.DateTimeFormat["[[localeData]]"][m].calendars,v=t["[[calendar]]"];-1!==d;){var w=void 0;if(-1===(h=y.indexOf("}",d)))throw new Error("Unclosed pattern");d>f&&b.call(p,{type:"literal",value:y.substring(f,d)});var S=y.substring(d+1,h);if(ke.hasOwnProperty(S)){var M=t["[["+S+"]]"],T=c["[["+S+"]]"];if("year"===S&&T<=0?T=1-T:"month"===S?T++:"hour"===S&&!0===t["[[hour12]]"]&&0===(T%=12)&&!0===t["[[hourNo0]]"]&&(T=12),"numeric"===M)w=oe(u,T);else if("2-digit"===M)(w=oe(l,T)).length>2&&(w=w.slice(-2));else if(M in we)switch(S){case"month":w=Se(g,v,"months",M,c["[["+S+"]]"]);break;case"weekday":try{w=Se(g,v,"days",M,c["[["+S+"]]"])}catch(e){throw new Error("Could not find weekday data for locale "+s)}break;case"timeZoneName":w="";break;case"era":try{w=Se(g,v,"eras",M,c["[["+S+"]]"])}catch(e){throw new Error("Could not find era data for locale "+s)}break;default:w=c["[["+S+"]]"]}b.call(p,{type:S,value:w})}else if("ampm"===S){w=Se(g,v,"dayPeriods",c["[[hour]]"]>11?"pm":"am",null),b.call(p,{type:"dayPeriod",value:w})}else b.call(p,{type:"literal",value:y.substring(d,h+1)});f=h+1,d=y.indexOf("{",f)}return ho;o++){n+=t[o].value}return n}k.DateTimeFormat={"[[availableLocales]]":[],"[[relevantExtensionKeys]]":["ca","nu"],"[[localeData]]":{}},d(X.DateTimeFormat,"supportedLocalesOf",{configurable:!0,writable:!0,value:M.call((function(e){if(!f.call(this,"[[availableLocales]]"))throw new TypeError("supportedLocalesOf() is not a constructor");var r=P(),t=arguments[1],n=this["[[availableLocales]]"],o=L(e);return r(),Q(n,o,t)}),k.NumberFormat)}),d(X.DateTimeFormat.prototype,"format",{configurable:!0,get:je}),Object.defineProperty(X.DateTimeFormat.prototype,"formatToParts",{enumerable:!1,writable:!0,configurable:!0,value:function(){var e=arguments.length<=0||void 0===arguments[0]?void 0:arguments[0],r=null!==this&&"object"===c.typeof(this)&&F(this);if(!r||!r["[[initializedDateTimeFormat]]"])throw new TypeError("`this` value for formatToParts() is not an initialized Intl.DateTimeFormat object.");return function(e,r){for(var t=Ee(e,r),n=[],o=0;t.length>o;o++){var a=t[o];n.push({type:a.type,value:a.value})}return n}(this,void 0===e?Date.now():O(e))}}),d(X.DateTimeFormat.prototype,"resolvedOptions",{writable:!0,configurable:!0,value:function(){var e=void 0,r=new j,t=["locale","calendar","numberingSystem","timeZone","hour12","weekday","era","year","month","day","hour","minute","second","timeZoneName"],n=null!==this&&"object"===c.typeof(this)&&F(this);if(!n||!n["[[initializedDateTimeFormat]]"])throw new TypeError("`this` value for resolvedOptions() is not an initialized Intl.DateTimeFormat object.");for(var o=0,a=t.length;o2&&4===o[1].length&&b.call(n,o[0]+"-"+o[2]);for(;t=S.call(n);)b.call(k.NumberFormat["[[availableLocales]]"],t),k.NumberFormat["[[localeData]]"][t]=e.number,e.date&&(e.date.nu=e.number.nu,b.call(k.DateTimeFormat["[[availableLocales]]"],t),k.DateTimeFormat["[[localeData]]"][t]=e.date);void 0===B&&function(e){B=e}(r)}(e,e.locale)}}),d(X,"__disableRegExpRestore",{value:function(){k.disableRegExpRestore=!0}}),e.exports=X}).call(this,t(75))},1180:function(e,r){},1181:function(e,r,t){"use strict";var n=t(1067),o={object:!0,symbol:!0};e.exports=function(){var e,r=n.Symbol;if("function"!=typeof r)return!1;e=r("test symbol");try{String(e)}catch(e){return!1}return!!o[typeof r.iterator]&&(!!o[typeof r.toPrimitive]&&!!o[typeof r.toStringTag])}},1182:function(e,r,t){"use strict";e.exports=function(){return"object"==typeof globalThis&&(!!globalThis&&globalThis.Array===Array)}},1183:function(e,r){var t=function(){if("object"==typeof self&&self)return self;if("object"==typeof window&&window)return window;throw new Error("Unable to resolve global `this`")};e.exports=function(){if(this)return this;try{Object.defineProperty(Object.prototype,"__global__",{get:function(){return this},configurable:!0})}catch(e){return t()}try{return __global__||t()}finally{delete Object.prototype.__global__}}()},1184:function(e,r,t){"use strict";var n,o,a,i=t(1068),s=t(1112),u=t(1067).Symbol,l=t(1202),c=t(1203),y=t(1204),p=Object.create,f=Object.defineProperties,d=Object.defineProperty;if("function"==typeof u)try{String(u()),a=!0}catch(e){}else u=null;o=function(e){if(this instanceof o)throw new TypeError("Symbol is not a constructor");return n(e)},e.exports=n=function e(r){var t;if(this instanceof e)throw new TypeError("Symbol is not a constructor");return a?u(r):(t=p(o.prototype),r=void 0===r?"":String(r),f(t,{__description__:i("",r),__name__:i("",l(r))}))},c(n),y(n),f(o.prototype,{constructor:i(n),toString:i("",(function(){return this.__name__}))}),f(n.prototype,{toString:i((function(){return"Symbol ("+s(this).__description__+")"})),valueOf:i((function(){return s(this)}))}),d(n.prototype,n.toPrimitive,i("",(function(){var e=s(this);return"symbol"==typeof e?e:e.toString()}))),d(n.prototype,n.toStringTag,i("c","Symbol")),d(o.prototype,n.toStringTag,i("c",n.prototype[n.toStringTag])),d(o.prototype,n.toPrimitive,i("c",n.prototype[n.toPrimitive]))},1185:function(e,r,t){"use strict";var n=t(1186),o=/^\s*class[\s{/}]/,a=Function.prototype.toString;e.exports=function(e){return!!n(e)&&!o.test(a.call(e))}},1186:function(e,r,t){"use strict";var n=t(1187);e.exports=function(e){if("function"!=typeof e)return!1;if(!hasOwnProperty.call(e,"length"))return!1;try{if("number"!=typeof e.length)return!1;if("function"!=typeof e.call)return!1;if("function"!=typeof e.apply)return!1}catch(e){return!1}return!n(e)}},1187:function(e,r,t){"use strict";var n=t(1188);e.exports=function(e){if(!n(e))return!1;try{return!!e.constructor&&e.constructor.prototype===e}catch(e){return!1}}},1188:function(e,r,t){"use strict";var n=t(1111),o={object:!0,function:!0,undefined:!0};e.exports=function(e){return!!n(e)&&hasOwnProperty.call(o,typeof e)}},1189:function(e,r,t){"use strict";e.exports=t(1190)()?Object.assign:t(1191)},1190:function(e,r,t){"use strict";e.exports=function(){var e,r=Object.assign;return"function"==typeof r&&(r(e={foo:"raz"},{bar:"dwa"},{trzy:"trzy"}),e.foo+e.bar+e.trzy==="razdwatrzy")}},1191:function(e,r,t){"use strict";var n=t(1192),o=t(1196),a=Math.max;e.exports=function(e,r){var t,i,s,u=a(arguments.length,2);for(e=Object(o(e)),s=function(n){try{e[n]=r[n]}catch(e){t||(t=e)}},i=1;i-1}},1201:function(e,r,t){"use strict";e.exports=function(e){return!!e&&("symbol"==typeof e||!!e.constructor&&("Symbol"===e.constructor.name&&"Symbol"===e[e.constructor.toStringTag]))}},1202:function(e,r,t){"use strict";var n=t(1068),o=Object.create,a=Object.defineProperty,i=Object.prototype,s=o(null);e.exports=function(e){for(var r,t,o=0;s[e+(o||"")];)++o;return s[e+=o||""]=!0,a(i,r="@@"+e,n.gs(null,(function(e){t||(t=!0,a(this,r,n(e)),t=!1)}))),r}},1203:function(e,r,t){"use strict";var n=t(1068),o=t(1067).Symbol;e.exports=function(e){return Object.defineProperties(e,{hasInstance:n("",o&&o.hasInstance||e("hasInstance")),isConcatSpreadable:n("",o&&o.isConcatSpreadable||e("isConcatSpreadable")),iterator:n("",o&&o.iterator||e("iterator")),match:n("",o&&o.match||e("match")),replace:n("",o&&o.replace||e("replace")),search:n("",o&&o.search||e("search")),species:n("",o&&o.species||e("species")),split:n("",o&&o.split||e("split")),toPrimitive:n("",o&&o.toPrimitive||e("toPrimitive")),toStringTag:n("",o&&o.toStringTag||e("toStringTag")),unscopables:n("",o&&o.unscopables||e("unscopables"))})}},1204:function(e,r,t){"use strict";var n=t(1068),o=t(1112),a=Object.create(null);e.exports=function(e){return Object.defineProperties(e,{for:n((function(r){return a[r]?a[r]:a[r]=e(String(r))})),keyFor:n((function(e){var r;for(r in o(e),a)if(a[r]===e)return r}))})}},1205:function(e,r,t){"use strict";var n=Array.prototype.slice,o=t(1114),a=Object.keys,i=a?function(e){return a(e)}:t(1206),s=Object.keys;i.shim=function(){Object.keys?function(){var e=Object.keys(arguments);return e&&e.length===arguments.length}(1,2)||(Object.keys=function(e){return o(e)?s(n.call(e)):s(e)}):Object.keys=i;return Object.keys||i},e.exports=i},1206:function(e,r,t){"use strict";var n;if(!Object.keys){var o=Object.prototype.hasOwnProperty,a=Object.prototype.toString,i=t(1114),s=Object.prototype.propertyIsEnumerable,u=!s.call({toString:null},"toString"),l=s.call((function(){}),"prototype"),c=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],y=function(e){var r=e.constructor;return r&&r.prototype===e},p={$applicationCache:!0,$console:!0,$external:!0,$frame:!0,$frameElement:!0,$frames:!0,$innerHeight:!0,$innerWidth:!0,$onmozfullscreenchange:!0,$onmozfullscreenerror:!0,$outerHeight:!0,$outerWidth:!0,$pageXOffset:!0,$pageYOffset:!0,$parent:!0,$scrollLeft:!0,$scrollTop:!0,$scrollX:!0,$scrollY:!0,$self:!0,$webkitIndexedDB:!0,$webkitStorageInfo:!0,$window:!0},f=function(){if("undefined"==typeof window)return!1;for(var e in window)try{if(!p["$"+e]&&o.call(window,e)&&null!==window[e]&&"object"==typeof window[e])try{y(window[e])}catch(e){return!0}}catch(e){return!0}return!1}();n=function(e){var r=null!==e&&"object"==typeof e,t="[object Function]"===a.call(e),n=i(e),s=r&&"[object String]"===a.call(e),p=[];if(!r&&!t&&!n)throw new TypeError("Object.keys called on a non-object");var d=l&&t;if(s&&e.length>0&&!o.call(e,0))for(var h=0;h0)for(var m=0;m=0?1:-1}},1212:function(e,r,t){"use strict";var n=t(1050),o=n("%TypeError%"),a=n("%Number%"),i=n("%RegExp%"),s=n("%parseInt%"),u=t(1069),l=t(1213),c=t(1214),y=u("String.prototype.slice"),p=l(/^0b[01]+$/i),f=l(/^0o[0-7]+$/i),d=l(/^[-+]0x[0-9a-f]+$/i),h=l(new i("["+["…","​","￾"].join("")+"]","g")),m=["\t\n\v\f\r   ᠎    ","          \u2028","\u2029\ufeff"].join(""),g=new RegExp("(^["+m+"]+)|(["+m+"]+$)","g"),v=u("String.prototype.replace"),b=t(1215);e.exports=function e(r){var t=c(r)?r:b(r,a);if("symbol"==typeof t)throw new o("Cannot convert a Symbol value to a number");if("string"==typeof t){if(p(t))return e(s(y(t,2),2));if(f(t))return e(s(y(t,2),8));if(h(t)||d(t))return NaN;var n=function(e){return v(e,g,"")}(t);if(n!==t)return e(n)}return a(t)}},1213:function(e,r,t){"use strict";var n=t(1050)("RegExp.prototype.test"),o=t(1117);e.exports=function(e){return o(n,e)}},1214:function(e,r,t){"use strict";e.exports=function(e){return null===e||"function"!=typeof e&&"object"!=typeof e}},1215:function(e,r,t){"use strict";var n=t(1216);e.exports=function(e){return arguments.length>1?n(e,arguments[1]):n(e)}},1216:function(e,r,t){"use strict";var n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator,o=t(1217),a=t(1121),i=t(1218),s=t(1219),u=function(e,r){if(null==e)throw new TypeError("Cannot call method on "+e);if("string"!=typeof r||"number"!==r&&"string"!==r)throw new TypeError('hint must be "string" or "number"');var t,n,i,s="string"===r?["toString","valueOf"]:["valueOf","toString"];for(i=0;i1&&(arguments[1]===String?t="string":arguments[1]===Number&&(t="number")),n&&(Symbol.toPrimitive?r=l(e,Symbol.toPrimitive):s(e)&&(r=Symbol.prototype.valueOf)),void 0!==r){var a=r.call(e,t);if(o(a))return a;throw new TypeError("unable to convert exotic object to primitive")}return"default"===t&&(i(e)||s(e))&&(t="string"),u(e,"default"===t?"number":t)}},1217:function(e,r,t){"use strict";e.exports=function(e){return null===e||"function"!=typeof e&&"object"!=typeof e}},1218:function(e,r,t){"use strict";var n=Date.prototype.getDay,o=Object.prototype.toString,a="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;e.exports=function(e){return"object"==typeof e&&null!==e&&(a?function(e){try{return n.call(e),!0}catch(e){return!1}}(e):"[object Date]"===o.call(e))}},1219:function(e,r,t){"use strict";var n=Object.prototype.toString;if(t(1087)()){var o=Symbol.prototype.toString,a=/^Symbol\(.*\)$/;e.exports=function(e){if("symbol"==typeof e)return!0;if("[object Symbol]"!==n.call(e))return!1;try{return function(e){return"symbol"==typeof e.valueOf()&&a.test(o.call(e))}(e)}catch(e){return!1}}}else e.exports=function(e){return!1}},1220:function(e,r,t){"use strict";var n=t(1221),o=t(1119);e.exports=function(e){var r=o(e);return r<=0?0:r>n?n:r}},1221:function(e,r,t){"use strict";var n=t(1050),o=n("%Math%"),a=n("%Number%");e.exports=a.MAX_SAFE_INTEGER||o.pow(2,53)-1},1222:function(e,r,t){"use strict";var n=t(1050)("%Object%"),o=t(1115);e.exports=function(e){return o(e),n(e)}},1223:function(e,r,t){"use strict";var n=t(1088);e.exports=function(e,r){return e===r||n(e)&&n(r)}},1224:function(e,r,t){"use strict";var n=String.prototype.valueOf,o=Object.prototype.toString,a="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;e.exports=function(e){return"string"==typeof e||"object"==typeof e&&(a?function(e){try{return n.call(e),!0}catch(e){return!1}}(e):"[object String]"===o.call(e))}},1225:function(e,r,t){"use strict";var n=t(1051),o=t(1122);e.exports=function(){var e=o();return n(Array.prototype,{includes:e},{includes:function(){return Array.prototype.includes!==e}}),e}},1226:function(e,r,t){"use strict";var n=t(1060);e.exports=n.call(Function.call,Object.prototype.hasOwnProperty)},1227:function(e,r,t){"use strict";e.exports=t(1116)},1228:function(e,r,t){"use strict";var n=t(1125),o=t(1051);e.exports=function(){var e=n();return o(Object,{values:e},{values:function(){return Object.values!==e}}),e}},1229:function(e,r,t){"use strict";var n=t(1051),o=t(1128);e.exports=function(){var e=o();return n(Number,{isNaN:e},{isNaN:function(){return Number.isNaN!==e}}),e}},1230:function(e,r,t){"use strict";e.exports=t(1121)},1231:function(e,r,t){"use strict";var n=t(1232),o=n("%Symbol.species%",!0),a=n("%TypeError%"),i=t(1233),s=t(1131);e.exports=function(e,r){if("Object"!==s(e))throw new a("Assertion failed: Type(O) is not Object");var t=e.constructor;if(void 0===t)return r;if("Object"!==s(t))throw new a("O.constructor is not an Object");var n=o?t[o]:void 0;if(null==n)return r;if(i(n))return n;throw new a("no constructor found")}},1232:function(e,r,t){"use strict";var n=TypeError,o=Object.getOwnPropertyDescriptor;if(o)try{o({},"")}catch(e){o=null}var a=function(){throw new n},i=o?function(){try{return arguments.callee,a}catch(e){try{return o(arguments,"callee").get}catch(e){return a}}}():a,s=t(1087)(),u=Object.getPrototypeOf||function(e){return e.__proto__},l=void 0,c="undefined"==typeof Uint8Array?void 0:u(Uint8Array),y={"%Array%":Array,"%ArrayBuffer%":"undefined"==typeof ArrayBuffer?void 0:ArrayBuffer,"%ArrayBufferPrototype%":"undefined"==typeof ArrayBuffer?void 0:ArrayBuffer.prototype,"%ArrayIteratorPrototype%":s?u([][Symbol.iterator]()):void 0,"%ArrayPrototype%":Array.prototype,"%ArrayProto_entries%":Array.prototype.entries,"%ArrayProto_forEach%":Array.prototype.forEach,"%ArrayProto_keys%":Array.prototype.keys,"%ArrayProto_values%":Array.prototype.values,"%AsyncFromSyncIteratorPrototype%":void 0,"%AsyncFunction%":void 0,"%AsyncFunctionPrototype%":void 0,"%AsyncGenerator%":void 0,"%AsyncGeneratorFunction%":void 0,"%AsyncGeneratorPrototype%":void 0,"%AsyncIteratorPrototype%":l&&s&&Symbol.asyncIterator?l[Symbol.asyncIterator]():void 0,"%Atomics%":"undefined"==typeof Atomics?void 0:Atomics,"%Boolean%":Boolean,"%BooleanPrototype%":Boolean.prototype,"%DataView%":"undefined"==typeof DataView?void 0:DataView,"%DataViewPrototype%":"undefined"==typeof DataView?void 0:DataView.prototype,"%Date%":Date,"%DatePrototype%":Date.prototype,"%decodeURI%":decodeURI,"%decodeURIComponent%":decodeURIComponent,"%encodeURI%":encodeURI,"%encodeURIComponent%":encodeURIComponent,"%Error%":Error,"%ErrorPrototype%":Error.prototype,"%eval%":eval,"%EvalError%":EvalError,"%EvalErrorPrototype%":EvalError.prototype,"%Float32Array%":"undefined"==typeof Float32Array?void 0:Float32Array,"%Float32ArrayPrototype%":"undefined"==typeof Float32Array?void 0:Float32Array.prototype,"%Float64Array%":"undefined"==typeof Float64Array?void 0:Float64Array,"%Float64ArrayPrototype%":"undefined"==typeof Float64Array?void 0:Float64Array.prototype,"%Function%":Function,"%FunctionPrototype%":Function.prototype,"%Generator%":void 0,"%GeneratorFunction%":void 0,"%GeneratorPrototype%":void 0,"%Int8Array%":"undefined"==typeof Int8Array?void 0:Int8Array,"%Int8ArrayPrototype%":"undefined"==typeof Int8Array?void 0:Int8Array.prototype,"%Int16Array%":"undefined"==typeof Int16Array?void 0:Int16Array,"%Int16ArrayPrototype%":"undefined"==typeof Int16Array?void 0:Int8Array.prototype,"%Int32Array%":"undefined"==typeof Int32Array?void 0:Int32Array,"%Int32ArrayPrototype%":"undefined"==typeof Int32Array?void 0:Int32Array.prototype,"%isFinite%":isFinite,"%isNaN%":isNaN,"%IteratorPrototype%":s?u(u([][Symbol.iterator]())):void 0,"%JSON%":"object"==typeof JSON?JSON:void 0,"%JSONParse%":"object"==typeof JSON?JSON.parse:void 0,"%Map%":"undefined"==typeof Map?void 0:Map,"%MapIteratorPrototype%":"undefined"!=typeof Map&&s?u((new Map)[Symbol.iterator]()):void 0,"%MapPrototype%":"undefined"==typeof Map?void 0:Map.prototype,"%Math%":Math,"%Number%":Number,"%NumberPrototype%":Number.prototype,"%Object%":Object,"%ObjectPrototype%":Object.prototype,"%ObjProto_toString%":Object.prototype.toString,"%ObjProto_valueOf%":Object.prototype.valueOf,"%parseFloat%":parseFloat,"%parseInt%":parseInt,"%Promise%":"undefined"==typeof Promise?void 0:Promise,"%PromisePrototype%":"undefined"==typeof Promise?void 0:Promise.prototype,"%PromiseProto_then%":"undefined"==typeof Promise?void 0:Promise.prototype.then,"%Promise_all%":"undefined"==typeof Promise?void 0:Promise.all,"%Promise_reject%":"undefined"==typeof Promise?void 0:Promise.reject,"%Promise_resolve%":"undefined"==typeof Promise?void 0:Promise.resolve,"%Proxy%":"undefined"==typeof Proxy?void 0:Proxy,"%RangeError%":RangeError,"%RangeErrorPrototype%":RangeError.prototype,"%ReferenceError%":ReferenceError,"%ReferenceErrorPrototype%":ReferenceError.prototype,"%Reflect%":"undefined"==typeof Reflect?void 0:Reflect,"%RegExp%":RegExp,"%RegExpPrototype%":RegExp.prototype,"%Set%":"undefined"==typeof Set?void 0:Set,"%SetIteratorPrototype%":"undefined"!=typeof Set&&s?u((new Set)[Symbol.iterator]()):void 0,"%SetPrototype%":"undefined"==typeof Set?void 0:Set.prototype,"%SharedArrayBuffer%":"undefined"==typeof SharedArrayBuffer?void 0:SharedArrayBuffer,"%SharedArrayBufferPrototype%":"undefined"==typeof SharedArrayBuffer?void 0:SharedArrayBuffer.prototype,"%String%":String,"%StringIteratorPrototype%":s?u(""[Symbol.iterator]()):void 0,"%StringPrototype%":String.prototype,"%Symbol%":s?Symbol:void 0,"%SymbolPrototype%":s?Symbol.prototype:void 0,"%SyntaxError%":SyntaxError,"%SyntaxErrorPrototype%":SyntaxError.prototype,"%ThrowTypeError%":i,"%TypedArray%":c,"%TypedArrayPrototype%":c?c.prototype:void 0,"%TypeError%":n,"%TypeErrorPrototype%":n.prototype,"%Uint8Array%":"undefined"==typeof Uint8Array?void 0:Uint8Array,"%Uint8ArrayPrototype%":"undefined"==typeof Uint8Array?void 0:Uint8Array.prototype,"%Uint8ClampedArray%":"undefined"==typeof Uint8ClampedArray?void 0:Uint8ClampedArray,"%Uint8ClampedArrayPrototype%":"undefined"==typeof Uint8ClampedArray?void 0:Uint8ClampedArray.prototype,"%Uint16Array%":"undefined"==typeof Uint16Array?void 0:Uint16Array,"%Uint16ArrayPrototype%":"undefined"==typeof Uint16Array?void 0:Uint16Array.prototype,"%Uint32Array%":"undefined"==typeof Uint32Array?void 0:Uint32Array,"%Uint32ArrayPrototype%":"undefined"==typeof Uint32Array?void 0:Uint32Array.prototype,"%URIError%":URIError,"%URIErrorPrototype%":URIError.prototype,"%WeakMap%":"undefined"==typeof WeakMap?void 0:WeakMap,"%WeakMapPrototype%":"undefined"==typeof WeakMap?void 0:WeakMap.prototype,"%WeakSet%":"undefined"==typeof WeakSet?void 0:WeakSet,"%WeakSetPrototype%":"undefined"==typeof WeakSet?void 0:WeakSet.prototype},p=t(1060).call(Function.call,String.prototype.replace),f=/[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g,d=/\\(\\)?/g,h=function(e){var r=[];return p(e,f,(function(e,t,n,o){r[r.length]=n?p(o,d,"$1"):t||e})),r},m=function(e,r){if(!(e in y))throw new SyntaxError("intrinsic "+e+" does not exist!");if(void 0===y[e]&&!r)throw new n("intrinsic "+e+" exists, but is not available. Please file an issue!");return y[e]};e.exports=function(e,r){if("string"!=typeof e||0===e.length)throw new TypeError("intrinsic name must be a non-empty string");if(arguments.length>1&&"boolean"!=typeof r)throw new TypeError('"allowMissing" argument must be a boolean');for(var t=h(e),a=m("%"+(t.length>0?t[0]:"")+"%",r),i=1;i=t.length){var s=o(a,t[i]);if(!(r||t[i]in a))throw new n("base intrinsic for "+e+" exists, but the property is not available.");a=s?s.get||s.value:a[t[i]]}else a=a[t[i]];return a}},1233:function(e,r,t){"use strict";e.exports=function(e){return"function"==typeof e&&!!e.prototype}},1234:function(e,r,t){"use strict";e.exports=function(e){return null===e?"Null":void 0===e?"Undefined":"function"==typeof e||"object"==typeof e?"Object":"number"==typeof e?"Number":"boolean"==typeof e?"Boolean":"string"==typeof e?"String":void 0}},1235:function(e,r,t){"use strict";var n=t(1089),o=t(1132),a=t(1051);e.exports=function(){n();var e=o();return a(Promise.prototype,{finally:e},{finally:function(){return Promise.prototype.finally!==e}}),e}},428:function(e,r,t){"use strict";t.d(r,"a",(function(){return n}));var n=function(e){for(var r=window.atob(e),t=new Uint8Array(r.length),n=0;n=0){var a=o.split(";base64,")[1];n=Object(y.a)(a)}else{n=o.split(",")[1]}e(new Blob([n],{type:r}))}})}},470:function(e,r,t){"use strict";t.r(r);t(1108),t(1109),t(1110);var n=t(1113),o=t.n(n),a=t(90),i=t.n(a),s=t(1123),u=t.n(s),l=t(1126),c=t.n(l),y=t(1129),p=t.n(y);if(Array.prototype.includes||o.a.shim(),Object.assign||(Object.assign=i.a),Object.values||u.a.shim(),Number.isNaN||(Number.isNaN=c.a),p.a.shim(),!HTMLCanvasElement.prototype.toBlob){Object.defineProperty(HTMLCanvasElement.prototype,"toBlob",{value:function(e,r,t){void 0===r&&(r="image/png");var n,o=this.toDataURL(r,t);o.indexOf(";base64,")>=0?n=function(e){for(var r=window.atob(e),t=new Uint8Array(r.length),n=0;n 1 && typeof allowMissing !== 'boolean') {\n throw new TypeError('\"allowMissing\" argument must be a boolean');\n }\n\n var parts = stringToPath(name);\n var value = getBaseIntrinsic('%' + (parts.length > 0 ? parts[0] : '') + '%', allowMissing);\n\n for (var i = 1; i < parts.length; i += 1) {\n if (value != null) {\n if ($gOPD && i + 1 >= parts.length) {\n var desc = $gOPD(value, parts[i]);\n value = desc ? desc.get || desc.value : value[parts[i]];\n } else {\n value = value[parts[i]];\n }\n }\n }\n\n return value;\n};","'use strict';\n\nvar keys = require('object-keys');\n\nvar hasSymbols = typeof Symbol === 'function' && typeof Symbol('foo') === 'symbol';\nvar toStr = Object.prototype.toString;\nvar concat = Array.prototype.concat;\nvar origDefineProperty = Object.defineProperty;\n\nvar isFunction = function isFunction(fn) {\n return typeof fn === 'function' && toStr.call(fn) === '[object Function]';\n};\n\nvar arePropertyDescriptorsSupported = function arePropertyDescriptorsSupported() {\n var obj = {};\n\n try {\n origDefineProperty(obj, 'x', {\n enumerable: false,\n value: obj\n }); // eslint-disable-next-line no-unused-vars, no-restricted-syntax\n\n for (var _ in obj) {\n // jscs:ignore disallowUnusedVariables\n return false;\n }\n\n return obj.x === obj;\n } catch (e) {\n /* this is IE 8. */\n return false;\n }\n};\n\nvar supportsDescriptors = origDefineProperty && arePropertyDescriptorsSupported();\n\nvar defineProperty = function defineProperty(object, name, value, predicate) {\n if (name in object && (!isFunction(predicate) || !predicate())) {\n return;\n }\n\n if (supportsDescriptors) {\n origDefineProperty(object, name, {\n configurable: true,\n enumerable: false,\n value: value,\n writable: true\n });\n } else {\n object[name] = value;\n }\n};\n\nvar defineProperties = function defineProperties(object, map) {\n var predicates = arguments.length > 2 ? arguments[2] : {};\n var props = keys(map);\n\n if (hasSymbols) {\n props = concat.call(props, Object.getOwnPropertySymbols(map));\n }\n\n for (var i = 0; i < props.length; i += 1) {\n defineProperty(object, props[i], map[props[i]], predicates[props[i]]);\n }\n};\n\ndefineProperties.supportsDescriptors = !!supportsDescriptors;\nmodule.exports = defineProperties;","'use strict';\n\nvar implementation = require('./implementation');\n\nmodule.exports = Function.prototype.bind || implementation;","\"use strict\";\n\nmodule.exports = require(\"./is-implemented\")() ? globalThis : require(\"./implementation\");","\"use strict\";\n\nvar isValue = require(\"type/value/is\"),\n isPlainFunction = require(\"type/plain-function/is\"),\n assign = require(\"es5-ext/object/assign\"),\n normalizeOpts = require(\"es5-ext/object/normalize-options\"),\n contains = require(\"es5-ext/string/#/contains\");\n\nvar d = module.exports = function (dscr, value\n/*, options*/\n) {\n var c, e, w, options, desc;\n\n if (arguments.length < 2 || typeof dscr !== \"string\") {\n options = value;\n value = dscr;\n dscr = null;\n } else {\n options = arguments[2];\n }\n\n if (isValue(dscr)) {\n c = contains.call(dscr, \"c\");\n e = contains.call(dscr, \"e\");\n w = contains.call(dscr, \"w\");\n } else {\n c = w = true;\n e = false;\n }\n\n desc = {\n value: value,\n configurable: c,\n enumerable: e,\n writable: w\n };\n return !options ? desc : assign(normalizeOpts(options), desc);\n};\n\nd.gs = function (dscr, get, set\n/*, options*/\n) {\n var c, e, options, desc;\n\n if (typeof dscr !== \"string\") {\n options = set;\n set = get;\n get = dscr;\n dscr = null;\n } else {\n options = arguments[3];\n }\n\n if (!isValue(get)) {\n get = undefined;\n } else if (!isPlainFunction(get)) {\n options = get;\n get = set = undefined;\n } else if (!isValue(set)) {\n set = undefined;\n } else if (!isPlainFunction(set)) {\n options = set;\n set = undefined;\n }\n\n if (isValue(dscr)) {\n c = contains.call(dscr, \"c\");\n e = contains.call(dscr, \"e\");\n } else {\n c = true;\n e = false;\n }\n\n desc = {\n get: get,\n set: set,\n configurable: c,\n enumerable: e\n };\n return !options ? desc : assign(normalizeOpts(options), desc);\n};","'use strict';\n\nvar GetIntrinsic = require('../GetIntrinsic');\n\nvar callBind = require('./callBind');\n\nvar $indexOf = callBind(GetIntrinsic('String.prototype.indexOf'));\n\nmodule.exports = function callBoundIntrinsic(name, allowMissing) {\n var intrinsic = GetIntrinsic(name, !!allowMissing);\n\n if (typeof intrinsic === 'function' && $indexOf(name, '.prototype.')) {\n return callBind(intrinsic);\n }\n\n return intrinsic;\n};","\"use strict\";\n\nvar _undefined = require(\"../function/noop\")(); // Support ES3 engines\n\n\nmodule.exports = function (val) {\n return val !== _undefined && val !== null;\n};","'use strict';\n\nvar origSymbol = global.Symbol;\n\nvar hasSymbolSham = require('./shams');\n\nmodule.exports = function hasNativeSymbols() {\n if (typeof origSymbol !== 'function') {\n return false;\n }\n\n if (typeof Symbol !== 'function') {\n return false;\n }\n\n if (typeof origSymbol('foo') !== 'symbol') {\n return false;\n }\n\n if (typeof Symbol('bar') !== 'symbol') {\n return false;\n }\n\n return hasSymbolSham();\n};","'use strict';\n\nmodule.exports = Number.isNaN || function isNaN(a) {\n return a !== a;\n};","'use strict';\n\nmodule.exports = function requirePromise() {\n if (typeof Promise !== 'function') {\n throw new TypeError('`Promise.prototype.finally` requires a global `Promise` be available.');\n }\n};","// Expose `IntlPolyfill` as global to add locale data into runtime later on.\nglobal.IntlPolyfill = require('./lib/core.js'); // Require all locale data for `Intl`. This module will be\n// ignored when bundling for the browser with Browserify/Webpack.\n\nrequire('./locale-data/complete.js'); // hack to export the polyfill as global Intl if needed\n\n\nif (!global.Intl) {\n global.Intl = global.IntlPolyfill;\n\n global.IntlPolyfill.__applyLocaleSensitivePrototypes();\n} // providing an idiomatic api for the nodejs version of this module\n\n\nmodule.exports = global.IntlPolyfill;","IntlPolyfill.__addLocaleData({\n locale: \"en\",\n date: {\n ca: [\"gregory\", \"buddhist\", \"chinese\", \"coptic\", \"dangi\", \"ethioaa\", \"ethiopic\", \"generic\", \"hebrew\", \"indian\", \"islamic\", \"islamicc\", \"japanese\", \"persian\", \"roc\"],\n hourNo0: true,\n hour12: true,\n formats: {\n short: \"{1}, {0}\",\n medium: \"{1}, {0}\",\n full: \"{1} 'at' {0}\",\n long: \"{1} 'at' {0}\",\n availableFormats: {\n \"d\": \"d\",\n \"E\": \"ccc\",\n Ed: \"d E\",\n Ehm: \"E h:mm a\",\n EHm: \"E HH:mm\",\n Ehms: \"E h:mm:ss a\",\n EHms: \"E HH:mm:ss\",\n Gy: \"y G\",\n GyMMM: \"MMM y G\",\n GyMMMd: \"MMM d, y G\",\n GyMMMEd: \"E, MMM d, y G\",\n \"h\": \"h a\",\n \"H\": \"HH\",\n hm: \"h:mm a\",\n Hm: \"HH:mm\",\n hms: \"h:mm:ss a\",\n Hms: \"HH:mm:ss\",\n hmsv: \"h:mm:ss a v\",\n Hmsv: \"HH:mm:ss v\",\n hmv: \"h:mm a v\",\n Hmv: \"HH:mm v\",\n \"M\": \"L\",\n Md: \"M/d\",\n MEd: \"E, M/d\",\n MMM: \"LLL\",\n MMMd: \"MMM d\",\n MMMEd: \"E, MMM d\",\n MMMMd: \"MMMM d\",\n ms: \"mm:ss\",\n \"y\": \"y\",\n yM: \"M/y\",\n yMd: \"M/d/y\",\n yMEd: \"E, M/d/y\",\n yMMM: \"MMM y\",\n yMMMd: \"MMM d, y\",\n yMMMEd: \"E, MMM d, y\",\n yMMMM: \"MMMM y\",\n yQQQ: \"QQQ y\",\n yQQQQ: \"QQQQ y\"\n },\n dateFormats: {\n yMMMMEEEEd: \"EEEE, MMMM d, y\",\n yMMMMd: \"MMMM d, y\",\n yMMMd: \"MMM d, y\",\n yMd: \"M/d/yy\"\n },\n timeFormats: {\n hmmsszzzz: \"h:mm:ss a zzzz\",\n hmsz: \"h:mm:ss a z\",\n hms: \"h:mm:ss a\",\n hm: \"h:mm a\"\n }\n },\n calendars: {\n buddhist: {\n months: {\n narrow: [\"J\", \"F\", \"M\", \"A\", \"M\", \"J\", \"J\", \"A\", \"S\", \"O\", \"N\", \"D\"],\n short: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"],\n long: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"]\n },\n days: {\n narrow: [\"S\", \"M\", \"T\", \"W\", \"T\", \"F\", \"S\"],\n short: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n long: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]\n },\n eras: {\n narrow: [\"BE\"],\n short: [\"BE\"],\n long: [\"BE\"]\n },\n dayPeriods: {\n am: \"AM\",\n pm: \"PM\"\n }\n },\n chinese: {\n months: {\n narrow: [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\"],\n short: [\"Mo1\", \"Mo2\", \"Mo3\", \"Mo4\", \"Mo5\", \"Mo6\", \"Mo7\", \"Mo8\", \"Mo9\", \"Mo10\", \"Mo11\", \"Mo12\"],\n long: [\"Month1\", \"Month2\", \"Month3\", \"Month4\", \"Month5\", \"Month6\", \"Month7\", \"Month8\", \"Month9\", \"Month10\", \"Month11\", \"Month12\"]\n },\n days: {\n narrow: [\"S\", \"M\", \"T\", \"W\", \"T\", \"F\", \"S\"],\n short: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n long: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]\n },\n dayPeriods: {\n am: \"AM\",\n pm: \"PM\"\n }\n },\n coptic: {\n months: {\n narrow: [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\", \"13\"],\n short: [\"Tout\", \"Baba\", \"Hator\", \"Kiahk\", \"Toba\", \"Amshir\", \"Baramhat\", \"Baramouda\", \"Bashans\", \"Paona\", \"Epep\", \"Mesra\", \"Nasie\"],\n long: [\"Tout\", \"Baba\", \"Hator\", \"Kiahk\", \"Toba\", \"Amshir\", \"Baramhat\", \"Baramouda\", \"Bashans\", \"Paona\", \"Epep\", \"Mesra\", \"Nasie\"]\n },\n days: {\n narrow: [\"S\", \"M\", \"T\", \"W\", \"T\", \"F\", \"S\"],\n short: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n long: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]\n },\n eras: {\n narrow: [\"ERA0\", \"ERA1\"],\n short: [\"ERA0\", \"ERA1\"],\n long: [\"ERA0\", \"ERA1\"]\n },\n dayPeriods: {\n am: \"AM\",\n pm: \"PM\"\n }\n },\n dangi: {\n months: {\n narrow: [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\"],\n short: [\"Mo1\", \"Mo2\", \"Mo3\", \"Mo4\", \"Mo5\", \"Mo6\", \"Mo7\", \"Mo8\", \"Mo9\", \"Mo10\", \"Mo11\", \"Mo12\"],\n long: [\"Month1\", \"Month2\", \"Month3\", \"Month4\", \"Month5\", \"Month6\", \"Month7\", \"Month8\", \"Month9\", \"Month10\", \"Month11\", \"Month12\"]\n },\n days: {\n narrow: [\"S\", \"M\", \"T\", \"W\", \"T\", \"F\", \"S\"],\n short: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n long: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]\n },\n dayPeriods: {\n am: \"AM\",\n pm: \"PM\"\n }\n },\n ethiopic: {\n months: {\n narrow: [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\", \"13\"],\n short: [\"Meskerem\", \"Tekemt\", \"Hedar\", \"Tahsas\", \"Ter\", \"Yekatit\", \"Megabit\", \"Miazia\", \"Genbot\", \"Sene\", \"Hamle\", \"Nehasse\", \"Pagumen\"],\n long: [\"Meskerem\", \"Tekemt\", \"Hedar\", \"Tahsas\", \"Ter\", \"Yekatit\", \"Megabit\", \"Miazia\", \"Genbot\", \"Sene\", \"Hamle\", \"Nehasse\", \"Pagumen\"]\n },\n days: {\n narrow: [\"S\", \"M\", \"T\", \"W\", \"T\", \"F\", \"S\"],\n short: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n long: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]\n },\n eras: {\n narrow: [\"ERA0\", \"ERA1\"],\n short: [\"ERA0\", \"ERA1\"],\n long: [\"ERA0\", \"ERA1\"]\n },\n dayPeriods: {\n am: \"AM\",\n pm: \"PM\"\n }\n },\n ethioaa: {\n months: {\n narrow: [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\", \"13\"],\n short: [\"Meskerem\", \"Tekemt\", \"Hedar\", \"Tahsas\", \"Ter\", \"Yekatit\", \"Megabit\", \"Miazia\", \"Genbot\", \"Sene\", \"Hamle\", \"Nehasse\", \"Pagumen\"],\n long: [\"Meskerem\", \"Tekemt\", \"Hedar\", \"Tahsas\", \"Ter\", \"Yekatit\", \"Megabit\", \"Miazia\", \"Genbot\", \"Sene\", \"Hamle\", \"Nehasse\", \"Pagumen\"]\n },\n days: {\n narrow: [\"S\", \"M\", \"T\", \"W\", \"T\", \"F\", \"S\"],\n short: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n long: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]\n },\n eras: {\n narrow: [\"ERA0\"],\n short: [\"ERA0\"],\n long: [\"ERA0\"]\n },\n dayPeriods: {\n am: \"AM\",\n pm: \"PM\"\n }\n },\n generic: {\n months: {\n narrow: [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\"],\n short: [\"M01\", \"M02\", \"M03\", \"M04\", \"M05\", \"M06\", \"M07\", \"M08\", \"M09\", \"M10\", \"M11\", \"M12\"],\n long: [\"M01\", \"M02\", \"M03\", \"M04\", \"M05\", \"M06\", \"M07\", \"M08\", \"M09\", \"M10\", \"M11\", \"M12\"]\n },\n days: {\n narrow: [\"S\", \"M\", \"T\", \"W\", \"T\", \"F\", \"S\"],\n short: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n long: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]\n },\n eras: {\n narrow: [\"ERA0\", \"ERA1\"],\n short: [\"ERA0\", \"ERA1\"],\n long: [\"ERA0\", \"ERA1\"]\n },\n dayPeriods: {\n am: \"AM\",\n pm: \"PM\"\n }\n },\n gregory: {\n months: {\n narrow: [\"J\", \"F\", \"M\", \"A\", \"M\", \"J\", \"J\", \"A\", \"S\", \"O\", \"N\", \"D\"],\n short: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"],\n long: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"]\n },\n days: {\n narrow: [\"S\", \"M\", \"T\", \"W\", \"T\", \"F\", \"S\"],\n short: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n long: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]\n },\n eras: {\n narrow: [\"B\", \"A\", \"BCE\", \"CE\"],\n short: [\"BC\", \"AD\", \"BCE\", \"CE\"],\n long: [\"Before Christ\", \"Anno Domini\", \"Before Common Era\", \"Common Era\"]\n },\n dayPeriods: {\n am: \"AM\",\n pm: \"PM\"\n }\n },\n hebrew: {\n months: {\n narrow: [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\", \"13\", \"7\"],\n short: [\"Tishri\", \"Heshvan\", \"Kislev\", \"Tevet\", \"Shevat\", \"Adar I\", \"Adar\", \"Nisan\", \"Iyar\", \"Sivan\", \"Tamuz\", \"Av\", \"Elul\", \"Adar II\"],\n long: [\"Tishri\", \"Heshvan\", \"Kislev\", \"Tevet\", \"Shevat\", \"Adar I\", \"Adar\", \"Nisan\", \"Iyar\", \"Sivan\", \"Tamuz\", \"Av\", \"Elul\", \"Adar II\"]\n },\n days: {\n narrow: [\"S\", \"M\", \"T\", \"W\", \"T\", \"F\", \"S\"],\n short: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n long: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]\n },\n eras: {\n narrow: [\"AM\"],\n short: [\"AM\"],\n long: [\"AM\"]\n },\n dayPeriods: {\n am: \"AM\",\n pm: \"PM\"\n }\n },\n indian: {\n months: {\n narrow: [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\"],\n short: [\"Chaitra\", \"Vaisakha\", \"Jyaistha\", \"Asadha\", \"Sravana\", \"Bhadra\", \"Asvina\", \"Kartika\", \"Agrahayana\", \"Pausa\", \"Magha\", \"Phalguna\"],\n long: [\"Chaitra\", \"Vaisakha\", \"Jyaistha\", \"Asadha\", \"Sravana\", \"Bhadra\", \"Asvina\", \"Kartika\", \"Agrahayana\", \"Pausa\", \"Magha\", \"Phalguna\"]\n },\n days: {\n narrow: [\"S\", \"M\", \"T\", \"W\", \"T\", \"F\", \"S\"],\n short: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n long: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]\n },\n eras: {\n narrow: [\"Saka\"],\n short: [\"Saka\"],\n long: [\"Saka\"]\n },\n dayPeriods: {\n am: \"AM\",\n pm: \"PM\"\n }\n },\n islamic: {\n months: {\n narrow: [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\"],\n short: [\"Muh.\", \"Saf.\", \"Rab. I\", \"Rab. II\", \"Jum. I\", \"Jum. II\", \"Raj.\", \"Sha.\", \"Ram.\", \"Shaw.\", \"Dhuʻl-Q.\", \"Dhuʻl-H.\"],\n long: [\"Muharram\", \"Safar\", \"Rabiʻ I\", \"Rabiʻ II\", \"Jumada I\", \"Jumada II\", \"Rajab\", \"Shaʻban\", \"Ramadan\", \"Shawwal\", \"Dhuʻl-Qiʻdah\", \"Dhuʻl-Hijjah\"]\n },\n days: {\n narrow: [\"S\", \"M\", \"T\", \"W\", \"T\", \"F\", \"S\"],\n short: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n long: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]\n },\n eras: {\n narrow: [\"AH\"],\n short: [\"AH\"],\n long: [\"AH\"]\n },\n dayPeriods: {\n am: \"AM\",\n pm: \"PM\"\n }\n },\n islamicc: {\n months: {\n narrow: [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\"],\n short: [\"Muh.\", \"Saf.\", \"Rab. I\", \"Rab. II\", \"Jum. I\", \"Jum. II\", \"Raj.\", \"Sha.\", \"Ram.\", \"Shaw.\", \"Dhuʻl-Q.\", \"Dhuʻl-H.\"],\n long: [\"Muharram\", \"Safar\", \"Rabiʻ I\", \"Rabiʻ II\", \"Jumada I\", \"Jumada II\", \"Rajab\", \"Shaʻban\", \"Ramadan\", \"Shawwal\", \"Dhuʻl-Qiʻdah\", \"Dhuʻl-Hijjah\"]\n },\n days: {\n narrow: [\"S\", \"M\", \"T\", \"W\", \"T\", \"F\", \"S\"],\n short: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n long: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]\n },\n eras: {\n narrow: [\"AH\"],\n short: [\"AH\"],\n long: [\"AH\"]\n },\n dayPeriods: {\n am: \"AM\",\n pm: \"PM\"\n }\n },\n japanese: {\n months: {\n narrow: [\"J\", \"F\", \"M\", \"A\", \"M\", \"J\", \"J\", \"A\", \"S\", \"O\", \"N\", \"D\"],\n short: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"],\n long: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"]\n },\n days: {\n narrow: [\"S\", \"M\", \"T\", \"W\", \"T\", \"F\", \"S\"],\n short: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n long: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]\n },\n eras: {\n narrow: [\"Taika (645–650)\", \"Hakuchi (650–671)\", \"Hakuhō (672–686)\", \"Shuchō (686–701)\", \"Taihō (701–704)\", \"Keiun (704–708)\", \"Wadō (708–715)\", \"Reiki (715–717)\", \"Yōrō (717–724)\", \"Jinki (724–729)\", \"Tenpyō (729–749)\", \"Tenpyō-kampō (749-749)\", \"Tenpyō-shōhō (749-757)\", \"Tenpyō-hōji (757-765)\", \"Tenpyō-jingo (765-767)\", \"Jingo-keiun (767-770)\", \"Hōki (770–780)\", \"Ten-ō (781-782)\", \"Enryaku (782–806)\", \"Daidō (806–810)\", \"Kōnin (810–824)\", \"Tenchō (824–834)\", \"Jōwa (834–848)\", \"Kajō (848–851)\", \"Ninju (851–854)\", \"Saikō (854–857)\", \"Ten-an (857-859)\", \"Jōgan (859–877)\", \"Gangyō (877–885)\", \"Ninna (885–889)\", \"Kanpyō (889–898)\", \"Shōtai (898–901)\", \"Engi (901–923)\", \"Enchō (923–931)\", \"Jōhei (931–938)\", \"Tengyō (938–947)\", \"Tenryaku (947–957)\", \"Tentoku (957–961)\", \"Ōwa (961–964)\", \"Kōhō (964–968)\", \"Anna (968–970)\", \"Tenroku (970–973)\", \"Ten’en (973–976)\", \"Jōgen (976–978)\", \"Tengen (978–983)\", \"Eikan (983–985)\", \"Kanna (985–987)\", \"Eien (987–989)\", \"Eiso (989–990)\", \"Shōryaku (990–995)\", \"Chōtoku (995–999)\", \"Chōhō (999–1004)\", \"Kankō (1004–1012)\", \"Chōwa (1012–1017)\", \"Kannin (1017–1021)\", \"Jian (1021–1024)\", \"Manju (1024–1028)\", \"Chōgen (1028–1037)\", \"Chōryaku (1037–1040)\", \"Chōkyū (1040–1044)\", \"Kantoku (1044–1046)\", \"Eishō (1046–1053)\", \"Tengi (1053–1058)\", \"Kōhei (1058–1065)\", \"Jiryaku (1065–1069)\", \"Enkyū (1069–1074)\", \"Shōho (1074–1077)\", \"Shōryaku (1077–1081)\", \"Eihō (1081–1084)\", \"Ōtoku (1084–1087)\", \"Kanji (1087–1094)\", \"Kahō (1094–1096)\", \"Eichō (1096–1097)\", \"Jōtoku (1097–1099)\", \"Kōwa (1099–1104)\", \"Chōji (1104–1106)\", \"Kashō (1106–1108)\", \"Tennin (1108–1110)\", \"Ten-ei (1110-1113)\", \"Eikyū (1113–1118)\", \"Gen’ei (1118–1120)\", \"Hōan (1120–1124)\", \"Tenji (1124–1126)\", \"Daiji (1126–1131)\", \"Tenshō (1131–1132)\", \"Chōshō (1132–1135)\", \"Hōen (1135–1141)\", \"Eiji (1141–1142)\", \"Kōji (1142–1144)\", \"Ten’yō (1144–1145)\", \"Kyūan (1145–1151)\", \"Ninpei (1151–1154)\", \"Kyūju (1154–1156)\", \"Hōgen (1156–1159)\", \"Heiji (1159–1160)\", \"Eiryaku (1160–1161)\", \"Ōho (1161–1163)\", \"Chōkan (1163–1165)\", \"Eiman (1165–1166)\", \"Nin’an (1166–1169)\", \"Kaō (1169–1171)\", \"Shōan (1171–1175)\", \"Angen (1175–1177)\", \"Jishō (1177–1181)\", \"Yōwa (1181–1182)\", \"Juei (1182–1184)\", \"Genryaku (1184–1185)\", \"Bunji (1185–1190)\", \"Kenkyū (1190–1199)\", \"Shōji (1199–1201)\", \"Kennin (1201–1204)\", \"Genkyū (1204–1206)\", \"Ken’ei (1206–1207)\", \"Jōgen (1207–1211)\", \"Kenryaku (1211–1213)\", \"Kenpō (1213–1219)\", \"Jōkyū (1219–1222)\", \"Jōō (1222–1224)\", \"Gennin (1224–1225)\", \"Karoku (1225–1227)\", \"Antei (1227–1229)\", \"Kanki (1229–1232)\", \"Jōei (1232–1233)\", \"Tenpuku (1233–1234)\", \"Bunryaku (1234–1235)\", \"Katei (1235–1238)\", \"Ryakunin (1238–1239)\", \"En’ō (1239–1240)\", \"Ninji (1240–1243)\", \"Kangen (1243–1247)\", \"Hōji (1247–1249)\", \"Kenchō (1249–1256)\", \"Kōgen (1256–1257)\", \"Shōka (1257–1259)\", \"Shōgen (1259–1260)\", \"Bun’ō (1260–1261)\", \"Kōchō (1261–1264)\", \"Bun’ei (1264–1275)\", \"Kenji (1275–1278)\", \"Kōan (1278–1288)\", \"Shōō (1288–1293)\", \"Einin (1293–1299)\", \"Shōan (1299–1302)\", \"Kengen (1302–1303)\", \"Kagen (1303–1306)\", \"Tokuji (1306–1308)\", \"Enkyō (1308–1311)\", \"Ōchō (1311–1312)\", \"Shōwa (1312–1317)\", \"Bunpō (1317–1319)\", \"Genō (1319–1321)\", \"Genkō (1321–1324)\", \"Shōchū (1324–1326)\", \"Karyaku (1326–1329)\", \"Gentoku (1329–1331)\", \"Genkō (1331–1334)\", \"Kenmu (1334–1336)\", \"Engen (1336–1340)\", \"Kōkoku (1340–1346)\", \"Shōhei (1346–1370)\", \"Kentoku (1370–1372)\", \"Bunchū (1372–1375)\", \"Tenju (1375–1379)\", \"Kōryaku (1379–1381)\", \"Kōwa (1381–1384)\", \"Genchū (1384–1392)\", \"Meitoku (1384–1387)\", \"Kakei (1387–1389)\", \"Kōō (1389–1390)\", \"Meitoku (1390–1394)\", \"Ōei (1394–1428)\", \"Shōchō (1428–1429)\", \"Eikyō (1429–1441)\", \"Kakitsu (1441–1444)\", \"Bun’an (1444–1449)\", \"Hōtoku (1449–1452)\", \"Kyōtoku (1452–1455)\", \"Kōshō (1455–1457)\", \"Chōroku (1457–1460)\", \"Kanshō (1460–1466)\", \"Bunshō (1466–1467)\", \"Ōnin (1467–1469)\", \"Bunmei (1469–1487)\", \"Chōkyō (1487–1489)\", \"Entoku (1489–1492)\", \"Meiō (1492–1501)\", \"Bunki (1501–1504)\", \"Eishō (1504–1521)\", \"Taiei (1521–1528)\", \"Kyōroku (1528–1532)\", \"Tenbun (1532–1555)\", \"Kōji (1555–1558)\", \"Eiroku (1558–1570)\", \"Genki (1570–1573)\", \"Tenshō (1573–1592)\", \"Bunroku (1592–1596)\", \"Keichō (1596–1615)\", \"Genna (1615–1624)\", \"Kan’ei (1624–1644)\", \"Shōho (1644–1648)\", \"Keian (1648–1652)\", \"Jōō (1652–1655)\", \"Meireki (1655–1658)\", \"Manji (1658–1661)\", \"Kanbun (1661–1673)\", \"Enpō (1673–1681)\", \"Tenna (1681–1684)\", \"Jōkyō (1684–1688)\", \"Genroku (1688–1704)\", \"Hōei (1704–1711)\", \"Shōtoku (1711–1716)\", \"Kyōhō (1716–1736)\", \"Genbun (1736–1741)\", \"Kanpō (1741–1744)\", \"Enkyō (1744–1748)\", \"Kan’en (1748–1751)\", \"Hōreki (1751–1764)\", \"Meiwa (1764–1772)\", \"An’ei (1772–1781)\", \"Tenmei (1781–1789)\", \"Kansei (1789–1801)\", \"Kyōwa (1801–1804)\", \"Bunka (1804–1818)\", \"Bunsei (1818–1830)\", \"Tenpō (1830–1844)\", \"Kōka (1844–1848)\", \"Kaei (1848–1854)\", \"Ansei (1854–1860)\", \"Man’en (1860–1861)\", \"Bunkyū (1861–1864)\", \"Genji (1864–1865)\", \"Keiō (1865–1868)\", \"M\", \"T\", \"S\", \"H\"],\n short: [\"Taika (645–650)\", \"Hakuchi (650–671)\", \"Hakuhō (672–686)\", \"Shuchō (686–701)\", \"Taihō (701–704)\", \"Keiun (704–708)\", \"Wadō (708–715)\", \"Reiki (715–717)\", \"Yōrō (717–724)\", \"Jinki (724–729)\", \"Tenpyō (729–749)\", \"Tenpyō-kampō (749-749)\", \"Tenpyō-shōhō (749-757)\", \"Tenpyō-hōji (757-765)\", \"Tenpyō-jingo (765-767)\", \"Jingo-keiun (767-770)\", \"Hōki (770–780)\", \"Ten-ō (781-782)\", \"Enryaku (782–806)\", \"Daidō (806–810)\", \"Kōnin (810–824)\", \"Tenchō (824–834)\", \"Jōwa (834–848)\", \"Kajō (848–851)\", \"Ninju (851–854)\", \"Saikō (854–857)\", \"Ten-an (857-859)\", \"Jōgan (859–877)\", \"Gangyō (877–885)\", \"Ninna (885–889)\", \"Kanpyō (889–898)\", \"Shōtai (898–901)\", \"Engi (901–923)\", \"Enchō (923–931)\", \"Jōhei (931–938)\", \"Tengyō (938–947)\", \"Tenryaku (947–957)\", \"Tentoku (957–961)\", \"Ōwa (961–964)\", \"Kōhō (964–968)\", \"Anna (968–970)\", \"Tenroku (970–973)\", \"Ten’en (973–976)\", \"Jōgen (976–978)\", \"Tengen (978–983)\", \"Eikan (983–985)\", \"Kanna (985–987)\", \"Eien (987–989)\", \"Eiso (989–990)\", \"Shōryaku (990–995)\", \"Chōtoku (995–999)\", \"Chōhō (999–1004)\", \"Kankō (1004–1012)\", \"Chōwa (1012–1017)\", \"Kannin (1017–1021)\", \"Jian (1021–1024)\", \"Manju (1024–1028)\", \"Chōgen (1028–1037)\", \"Chōryaku (1037–1040)\", \"Chōkyū (1040–1044)\", \"Kantoku (1044–1046)\", \"Eishō (1046–1053)\", \"Tengi (1053–1058)\", \"Kōhei (1058–1065)\", \"Jiryaku (1065–1069)\", \"Enkyū (1069–1074)\", \"Shōho (1074–1077)\", \"Shōryaku (1077–1081)\", \"Eihō (1081–1084)\", \"Ōtoku (1084–1087)\", \"Kanji (1087–1094)\", \"Kahō (1094–1096)\", \"Eichō (1096–1097)\", \"Jōtoku (1097–1099)\", \"Kōwa (1099–1104)\", \"Chōji (1104–1106)\", \"Kashō (1106–1108)\", \"Tennin (1108–1110)\", \"Ten-ei (1110-1113)\", \"Eikyū (1113–1118)\", \"Gen’ei (1118–1120)\", \"Hōan (1120–1124)\", \"Tenji (1124–1126)\", \"Daiji (1126–1131)\", \"Tenshō (1131–1132)\", \"Chōshō (1132–1135)\", \"Hōen (1135–1141)\", \"Eiji (1141–1142)\", \"Kōji (1142–1144)\", \"Ten’yō (1144–1145)\", \"Kyūan (1145–1151)\", \"Ninpei (1151–1154)\", \"Kyūju (1154–1156)\", \"Hōgen (1156–1159)\", \"Heiji (1159–1160)\", \"Eiryaku (1160–1161)\", \"Ōho (1161–1163)\", \"Chōkan (1163–1165)\", \"Eiman (1165–1166)\", \"Nin’an (1166–1169)\", \"Kaō (1169–1171)\", \"Shōan (1171–1175)\", \"Angen (1175–1177)\", \"Jishō (1177–1181)\", \"Yōwa (1181–1182)\", \"Juei (1182–1184)\", \"Genryaku (1184–1185)\", \"Bunji (1185–1190)\", \"Kenkyū (1190–1199)\", \"Shōji (1199–1201)\", \"Kennin (1201–1204)\", \"Genkyū (1204–1206)\", \"Ken’ei (1206–1207)\", \"Jōgen (1207–1211)\", \"Kenryaku (1211–1213)\", \"Kenpō (1213–1219)\", \"Jōkyū (1219–1222)\", \"Jōō (1222–1224)\", \"Gennin (1224–1225)\", \"Karoku (1225–1227)\", \"Antei (1227–1229)\", \"Kanki (1229–1232)\", \"Jōei (1232–1233)\", \"Tenpuku (1233–1234)\", \"Bunryaku (1234–1235)\", \"Katei (1235–1238)\", \"Ryakunin (1238–1239)\", \"En’ō (1239–1240)\", \"Ninji (1240–1243)\", \"Kangen (1243–1247)\", \"Hōji (1247–1249)\", \"Kenchō (1249–1256)\", \"Kōgen (1256–1257)\", \"Shōka (1257–1259)\", \"Shōgen (1259–1260)\", \"Bun’ō (1260–1261)\", \"Kōchō (1261–1264)\", \"Bun’ei (1264–1275)\", \"Kenji (1275–1278)\", \"Kōan (1278–1288)\", \"Shōō (1288–1293)\", \"Einin (1293–1299)\", \"Shōan (1299–1302)\", \"Kengen (1302–1303)\", \"Kagen (1303–1306)\", \"Tokuji (1306–1308)\", \"Enkyō (1308–1311)\", \"Ōchō (1311–1312)\", \"Shōwa (1312–1317)\", \"Bunpō (1317–1319)\", \"Genō (1319–1321)\", \"Genkō (1321–1324)\", \"Shōchū (1324–1326)\", \"Karyaku (1326–1329)\", \"Gentoku (1329–1331)\", \"Genkō (1331–1334)\", \"Kenmu (1334–1336)\", \"Engen (1336–1340)\", \"Kōkoku (1340–1346)\", \"Shōhei (1346–1370)\", \"Kentoku (1370–1372)\", \"Bunchū (1372–1375)\", \"Tenju (1375–1379)\", \"Kōryaku (1379–1381)\", \"Kōwa (1381–1384)\", \"Genchū (1384–1392)\", \"Meitoku (1384–1387)\", \"Kakei (1387–1389)\", \"Kōō (1389–1390)\", \"Meitoku (1390–1394)\", \"Ōei (1394–1428)\", \"Shōchō (1428–1429)\", \"Eikyō (1429–1441)\", \"Kakitsu (1441–1444)\", \"Bun’an (1444–1449)\", \"Hōtoku (1449–1452)\", \"Kyōtoku (1452–1455)\", \"Kōshō (1455–1457)\", \"Chōroku (1457–1460)\", \"Kanshō (1460–1466)\", \"Bunshō (1466–1467)\", \"Ōnin (1467–1469)\", \"Bunmei (1469–1487)\", \"Chōkyō (1487–1489)\", \"Entoku (1489–1492)\", \"Meiō (1492–1501)\", \"Bunki (1501–1504)\", \"Eishō (1504–1521)\", \"Taiei (1521–1528)\", \"Kyōroku (1528–1532)\", \"Tenbun (1532–1555)\", \"Kōji (1555–1558)\", \"Eiroku (1558–1570)\", \"Genki (1570–1573)\", \"Tenshō (1573–1592)\", \"Bunroku (1592–1596)\", \"Keichō (1596–1615)\", \"Genna (1615–1624)\", \"Kan’ei (1624–1644)\", \"Shōho (1644–1648)\", \"Keian (1648–1652)\", \"Jōō (1652–1655)\", \"Meireki (1655–1658)\", \"Manji (1658–1661)\", \"Kanbun (1661–1673)\", \"Enpō (1673–1681)\", \"Tenna (1681–1684)\", \"Jōkyō (1684–1688)\", \"Genroku (1688–1704)\", \"Hōei (1704–1711)\", \"Shōtoku (1711–1716)\", \"Kyōhō (1716–1736)\", \"Genbun (1736–1741)\", \"Kanpō (1741–1744)\", \"Enkyō (1744–1748)\", \"Kan’en (1748–1751)\", \"Hōreki (1751–1764)\", \"Meiwa (1764–1772)\", \"An’ei (1772–1781)\", \"Tenmei (1781–1789)\", \"Kansei (1789–1801)\", \"Kyōwa (1801–1804)\", \"Bunka (1804–1818)\", \"Bunsei (1818–1830)\", \"Tenpō (1830–1844)\", \"Kōka (1844–1848)\", \"Kaei (1848–1854)\", \"Ansei (1854–1860)\", \"Man’en (1860–1861)\", \"Bunkyū (1861–1864)\", \"Genji (1864–1865)\", \"Keiō (1865–1868)\", \"Meiji\", \"Taishō\", \"Shōwa\", \"Heisei\"],\n long: [\"Taika (645–650)\", \"Hakuchi (650–671)\", \"Hakuhō (672–686)\", \"Shuchō (686–701)\", \"Taihō (701–704)\", \"Keiun (704–708)\", \"Wadō (708–715)\", \"Reiki (715–717)\", \"Yōrō (717–724)\", \"Jinki (724–729)\", \"Tenpyō (729–749)\", \"Tenpyō-kampō (749-749)\", \"Tenpyō-shōhō (749-757)\", \"Tenpyō-hōji (757-765)\", \"Tenpyō-jingo (765-767)\", \"Jingo-keiun (767-770)\", \"Hōki (770–780)\", \"Ten-ō (781-782)\", \"Enryaku (782–806)\", \"Daidō (806–810)\", \"Kōnin (810–824)\", \"Tenchō (824–834)\", \"Jōwa (834–848)\", \"Kajō (848–851)\", \"Ninju (851–854)\", \"Saikō (854–857)\", \"Ten-an (857-859)\", \"Jōgan (859–877)\", \"Gangyō (877–885)\", \"Ninna (885–889)\", \"Kanpyō (889–898)\", \"Shōtai (898–901)\", \"Engi (901–923)\", \"Enchō (923–931)\", \"Jōhei (931–938)\", \"Tengyō (938–947)\", \"Tenryaku (947–957)\", \"Tentoku (957–961)\", \"Ōwa (961–964)\", \"Kōhō (964–968)\", \"Anna (968–970)\", \"Tenroku (970–973)\", \"Ten’en (973–976)\", \"Jōgen (976–978)\", \"Tengen (978–983)\", \"Eikan (983–985)\", \"Kanna (985–987)\", \"Eien (987–989)\", \"Eiso (989–990)\", \"Shōryaku (990–995)\", \"Chōtoku (995–999)\", \"Chōhō (999–1004)\", \"Kankō (1004–1012)\", \"Chōwa (1012–1017)\", \"Kannin (1017–1021)\", \"Jian (1021–1024)\", \"Manju (1024–1028)\", \"Chōgen (1028–1037)\", \"Chōryaku (1037–1040)\", \"Chōkyū (1040–1044)\", \"Kantoku (1044–1046)\", \"Eishō (1046–1053)\", \"Tengi (1053–1058)\", \"Kōhei (1058–1065)\", \"Jiryaku (1065–1069)\", \"Enkyū (1069–1074)\", \"Shōho (1074–1077)\", \"Shōryaku (1077–1081)\", \"Eihō (1081–1084)\", \"Ōtoku (1084–1087)\", \"Kanji (1087–1094)\", \"Kahō (1094–1096)\", \"Eichō (1096–1097)\", \"Jōtoku (1097–1099)\", \"Kōwa (1099–1104)\", \"Chōji (1104–1106)\", \"Kashō (1106–1108)\", \"Tennin (1108–1110)\", \"Ten-ei (1110-1113)\", \"Eikyū (1113–1118)\", \"Gen’ei (1118–1120)\", \"Hōan (1120–1124)\", \"Tenji (1124–1126)\", \"Daiji (1126–1131)\", \"Tenshō (1131–1132)\", \"Chōshō (1132–1135)\", \"Hōen (1135–1141)\", \"Eiji (1141–1142)\", \"Kōji (1142–1144)\", \"Ten’yō (1144–1145)\", \"Kyūan (1145–1151)\", \"Ninpei (1151–1154)\", \"Kyūju (1154–1156)\", \"Hōgen (1156–1159)\", \"Heiji (1159–1160)\", \"Eiryaku (1160–1161)\", \"Ōho (1161–1163)\", \"Chōkan (1163–1165)\", \"Eiman (1165–1166)\", \"Nin’an (1166–1169)\", \"Kaō (1169–1171)\", \"Shōan (1171–1175)\", \"Angen (1175–1177)\", \"Jishō (1177–1181)\", \"Yōwa (1181–1182)\", \"Juei (1182–1184)\", \"Genryaku (1184–1185)\", \"Bunji (1185–1190)\", \"Kenkyū (1190–1199)\", \"Shōji (1199–1201)\", \"Kennin (1201–1204)\", \"Genkyū (1204–1206)\", \"Ken’ei (1206–1207)\", \"Jōgen (1207–1211)\", \"Kenryaku (1211–1213)\", \"Kenpō (1213–1219)\", \"Jōkyū (1219–1222)\", \"Jōō (1222–1224)\", \"Gennin (1224–1225)\", \"Karoku (1225–1227)\", \"Antei (1227–1229)\", \"Kanki (1229–1232)\", \"Jōei (1232–1233)\", \"Tenpuku (1233–1234)\", \"Bunryaku (1234–1235)\", \"Katei (1235–1238)\", \"Ryakunin (1238–1239)\", \"En’ō (1239–1240)\", \"Ninji (1240–1243)\", \"Kangen (1243–1247)\", \"Hōji (1247–1249)\", \"Kenchō (1249–1256)\", \"Kōgen (1256–1257)\", \"Shōka (1257–1259)\", \"Shōgen (1259–1260)\", \"Bun’ō (1260–1261)\", \"Kōchō (1261–1264)\", \"Bun’ei (1264–1275)\", \"Kenji (1275–1278)\", \"Kōan (1278–1288)\", \"Shōō (1288–1293)\", \"Einin (1293–1299)\", \"Shōan (1299–1302)\", \"Kengen (1302–1303)\", \"Kagen (1303–1306)\", \"Tokuji (1306–1308)\", \"Enkyō (1308–1311)\", \"Ōchō (1311–1312)\", \"Shōwa (1312–1317)\", \"Bunpō (1317–1319)\", \"Genō (1319–1321)\", \"Genkō (1321–1324)\", \"Shōchū (1324–1326)\", \"Karyaku (1326–1329)\", \"Gentoku (1329–1331)\", \"Genkō (1331–1334)\", \"Kenmu (1334–1336)\", \"Engen (1336–1340)\", \"Kōkoku (1340–1346)\", \"Shōhei (1346–1370)\", \"Kentoku (1370–1372)\", \"Bunchū (1372–1375)\", \"Tenju (1375–1379)\", \"Kōryaku (1379–1381)\", \"Kōwa (1381–1384)\", \"Genchū (1384–1392)\", \"Meitoku (1384–1387)\", \"Kakei (1387–1389)\", \"Kōō (1389–1390)\", \"Meitoku (1390–1394)\", \"Ōei (1394–1428)\", \"Shōchō (1428–1429)\", \"Eikyō (1429–1441)\", \"Kakitsu (1441–1444)\", \"Bun’an (1444–1449)\", \"Hōtoku (1449–1452)\", \"Kyōtoku (1452–1455)\", \"Kōshō (1455–1457)\", \"Chōroku (1457–1460)\", \"Kanshō (1460–1466)\", \"Bunshō (1466–1467)\", \"Ōnin (1467–1469)\", \"Bunmei (1469–1487)\", \"Chōkyō (1487–1489)\", \"Entoku (1489–1492)\", \"Meiō (1492–1501)\", \"Bunki (1501–1504)\", \"Eishō (1504–1521)\", \"Taiei (1521–1528)\", \"Kyōroku (1528–1532)\", \"Tenbun (1532–1555)\", \"Kōji (1555–1558)\", \"Eiroku (1558–1570)\", \"Genki (1570–1573)\", \"Tenshō (1573–1592)\", \"Bunroku (1592–1596)\", \"Keichō (1596–1615)\", \"Genna (1615–1624)\", \"Kan’ei (1624–1644)\", \"Shōho (1644–1648)\", \"Keian (1648–1652)\", \"Jōō (1652–1655)\", \"Meireki (1655–1658)\", \"Manji (1658–1661)\", \"Kanbun (1661–1673)\", \"Enpō (1673–1681)\", \"Tenna (1681–1684)\", \"Jōkyō (1684–1688)\", \"Genroku (1688–1704)\", \"Hōei (1704–1711)\", \"Shōtoku (1711–1716)\", \"Kyōhō (1716–1736)\", \"Genbun (1736–1741)\", \"Kanpō (1741–1744)\", \"Enkyō (1744–1748)\", \"Kan’en (1748–1751)\", \"Hōreki (1751–1764)\", \"Meiwa (1764–1772)\", \"An’ei (1772–1781)\", \"Tenmei (1781–1789)\", \"Kansei (1789–1801)\", \"Kyōwa (1801–1804)\", \"Bunka (1804–1818)\", \"Bunsei (1818–1830)\", \"Tenpō (1830–1844)\", \"Kōka (1844–1848)\", \"Kaei (1848–1854)\", \"Ansei (1854–1860)\", \"Man’en (1860–1861)\", \"Bunkyū (1861–1864)\", \"Genji (1864–1865)\", \"Keiō (1865–1868)\", \"Meiji\", \"Taishō\", \"Shōwa\", \"Heisei\"]\n },\n dayPeriods: {\n am: \"AM\",\n pm: \"PM\"\n }\n },\n persian: {\n months: {\n narrow: [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\"],\n short: [\"Farvardin\", \"Ordibehesht\", \"Khordad\", \"Tir\", \"Mordad\", \"Shahrivar\", \"Mehr\", \"Aban\", \"Azar\", \"Dey\", \"Bahman\", \"Esfand\"],\n long: [\"Farvardin\", \"Ordibehesht\", \"Khordad\", \"Tir\", \"Mordad\", \"Shahrivar\", \"Mehr\", \"Aban\", \"Azar\", \"Dey\", \"Bahman\", \"Esfand\"]\n },\n days: {\n narrow: [\"S\", \"M\", \"T\", \"W\", \"T\", \"F\", \"S\"],\n short: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n long: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]\n },\n eras: {\n narrow: [\"AP\"],\n short: [\"AP\"],\n long: [\"AP\"]\n },\n dayPeriods: {\n am: \"AM\",\n pm: \"PM\"\n }\n },\n roc: {\n months: {\n narrow: [\"J\", \"F\", \"M\", \"A\", \"M\", \"J\", \"J\", \"A\", \"S\", \"O\", \"N\", \"D\"],\n short: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"],\n long: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"]\n },\n days: {\n narrow: [\"S\", \"M\", \"T\", \"W\", \"T\", \"F\", \"S\"],\n short: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n long: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]\n },\n eras: {\n narrow: [\"Before R.O.C.\", \"Minguo\"],\n short: [\"Before R.O.C.\", \"Minguo\"],\n long: [\"Before R.O.C.\", \"Minguo\"]\n },\n dayPeriods: {\n am: \"AM\",\n pm: \"PM\"\n }\n }\n }\n },\n number: {\n nu: [\"latn\"],\n patterns: {\n decimal: {\n positivePattern: \"{number}\",\n negativePattern: \"{minusSign}{number}\"\n },\n currency: {\n positivePattern: \"{currency}{number}\",\n negativePattern: \"{minusSign}{currency}{number}\"\n },\n percent: {\n positivePattern: \"{number}{percentSign}\",\n negativePattern: \"{minusSign}{number}{percentSign}\"\n }\n },\n symbols: {\n latn: {\n decimal: \".\",\n group: \",\",\n nan: \"NaN\",\n plusSign: \"+\",\n minusSign: \"-\",\n percentSign: \"%\",\n infinity: \"∞\"\n }\n },\n currencies: {\n AUD: \"A$\",\n BRL: \"R$\",\n CAD: \"CA$\",\n CNY: \"CN¥\",\n EUR: \"€\",\n GBP: \"£\",\n HKD: \"HK$\",\n ILS: \"₪\",\n INR: \"₹\",\n JPY: \"¥\",\n KRW: \"₩\",\n MXN: \"MX$\",\n NZD: \"NZ$\",\n TWD: \"NT$\",\n USD: \"$\",\n VND: \"₫\",\n XAF: \"FCFA\",\n XCD: \"EC$\",\n XOF: \"CFA\",\n XPF: \"CFPF\"\n }\n }\n});","\"use strict\";\n\nif (!require(\"./is-implemented\")()) {\n Object.defineProperty(require(\"ext/global-this\"), \"Symbol\", {\n value: require(\"./polyfill\"),\n configurable: true,\n enumerable: false,\n writable: true\n });\n}","\"use strict\"; // ES3 safe\n\nvar _undefined = void 0;\n\nmodule.exports = function (value) {\n return value !== _undefined && value !== null;\n};","\"use strict\";\n\nvar isSymbol = require(\"./is-symbol\");\n\nmodule.exports = function (value) {\n if (!isSymbol(value)) throw new TypeError(value + \" is not a symbol\");\n return value;\n};","'use strict';\n\nvar define = require('define-properties');\n\nvar RequireObjectCoercible = require('es-abstract/2018/RequireObjectCoercible');\n\nvar callBound = require('es-abstract/helpers/callBound');\n\nvar implementation = require('./implementation');\n\nvar getPolyfill = require('./polyfill');\n\nvar polyfill = getPolyfill();\n\nvar shim = require('./shim');\n\nvar $slice = callBound('Array.prototype.slice');\n/* eslint-disable no-unused-vars */\n\nvar boundIncludesShim = function includes(array, searchElement) {\n /* eslint-enable no-unused-vars */\n RequireObjectCoercible(array);\n return polyfill.apply(array, $slice(arguments, 1));\n};\n\ndefine(boundIncludesShim, {\n getPolyfill: getPolyfill,\n implementation: implementation,\n shim: shim\n});\nmodule.exports = boundIncludesShim;","'use strict';\n\nvar toStr = Object.prototype.toString;\n\nmodule.exports = function isArguments(value) {\n var str = toStr.call(value);\n var isArgs = str === '[object Arguments]';\n\n if (!isArgs) {\n isArgs = str !== '[object Array]' && value !== null && typeof value === 'object' && typeof value.length === 'number' && value.length >= 0 && toStr.call(value.callee) === '[object Function]';\n }\n\n return isArgs;\n};","'use strict';\n\nmodule.exports = require('../5/CheckObjectCoercible');","'use strict';\n\nvar GetIntrinsic = require('../GetIntrinsic');\n\nvar $TypeError = GetIntrinsic('%TypeError%'); // http://www.ecma-international.org/ecma-262/5.1/#sec-9.10\n\nmodule.exports = function CheckObjectCoercible(value, optMessage) {\n if (value == null) {\n throw new $TypeError(optMessage || 'Cannot call method on ' + value);\n }\n\n return value;\n};","'use strict';\n\nvar bind = require('function-bind');\n\nvar GetIntrinsic = require('../GetIntrinsic');\n\nvar $Function = GetIntrinsic('%Function%');\nvar $apply = $Function.apply;\nvar $call = $Function.call;\n\nmodule.exports = function callBind() {\n return bind.apply($call, arguments);\n};\n\nmodule.exports.apply = function applyBind() {\n return bind.apply($apply, arguments);\n};","'use strict';\n\nvar ToInteger = require('es-abstract/2018/ToInteger');\n\nvar ToLength = require('es-abstract/2018/ToLength');\n\nvar ToObject = require('es-abstract/2018/ToObject');\n\nvar SameValueZero = require('es-abstract/2018/SameValueZero');\n\nvar $isNaN = require('es-abstract/helpers/isNaN');\n\nvar $isFinite = require('es-abstract/helpers/isFinite');\n\nvar GetIntrinsic = require('es-abstract/GetIntrinsic');\n\nvar callBound = require('es-abstract/helpers/callBound');\n\nvar isString = require('is-string');\n\nvar $charAt = callBound('String.prototype.charAt');\nvar $indexOf = GetIntrinsic('%Array.prototype.indexOf%'); // TODO: use callBind.apply without breaking IE 8\n\nmodule.exports = function includes(searchElement) {\n var fromIndex = arguments.length > 1 ? ToInteger(arguments[1]) : 0;\n\n if ($indexOf && !$isNaN(searchElement) && $isFinite(fromIndex) && typeof searchElement !== 'undefined') {\n return $indexOf.apply(this, arguments) > -1;\n }\n\n var O = ToObject(this);\n var length = ToLength(O.length);\n\n if (length === 0) {\n return false;\n }\n\n var k = fromIndex >= 0 ? fromIndex : Math.max(0, length + fromIndex);\n\n while (k < length) {\n if (SameValueZero(searchElement, isString(O) ? $charAt(O, k) : O[k])) {\n return true;\n }\n\n k += 1;\n }\n\n return false;\n};","'use strict';\n\nvar ES5ToInteger = require('../5/ToInteger');\n\nvar ToNumber = require('./ToNumber'); // https://www.ecma-international.org/ecma-262/6.0/#sec-tointeger\n\n\nmodule.exports = function ToInteger(value) {\n var number = ToNumber(value);\n return ES5ToInteger(number);\n};","'use strict';\n\nvar $isNaN = Number.isNaN || function (a) {\n return a !== a;\n};\n\nmodule.exports = Number.isFinite || function (x) {\n return typeof x === 'number' && !$isNaN(x) && x !== Infinity && x !== -Infinity;\n};","'use strict';\n\nvar fnToStr = Function.prototype.toString;\nvar constructorRegex = /^\\s*class\\b/;\n\nvar isES6ClassFn = function isES6ClassFunction(value) {\n try {\n var fnStr = fnToStr.call(value);\n return constructorRegex.test(fnStr);\n } catch (e) {\n return false; // not a function\n }\n};\n\nvar tryFunctionObject = function tryFunctionToStr(value) {\n try {\n if (isES6ClassFn(value)) {\n return false;\n }\n\n fnToStr.call(value);\n return true;\n } catch (e) {\n return false;\n }\n};\n\nvar toStr = Object.prototype.toString;\nvar fnClass = '[object Function]';\nvar genClass = '[object GeneratorFunction]';\nvar hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';\n\nmodule.exports = function isCallable(value) {\n if (!value) {\n return false;\n }\n\n if (typeof value !== 'function' && typeof value !== 'object') {\n return false;\n }\n\n if (typeof value === 'function' && !value.prototype) {\n return true;\n }\n\n if (hasToStringTag) {\n return tryFunctionObject(value);\n }\n\n if (isES6ClassFn(value)) {\n return false;\n }\n\n var strClass = toStr.call(value);\n return strClass === fnClass || strClass === genClass;\n};","'use strict';\n\nvar implementation = require('./implementation');\n\nmodule.exports = function getPolyfill() {\n return Array.prototype.includes || implementation;\n};","'use strict';\n\nvar define = require('define-properties');\n\nvar implementation = require('./implementation');\n\nvar getPolyfill = require('./polyfill');\n\nvar shim = require('./shim');\n\nvar polyfill = getPolyfill();\ndefine(polyfill, {\n getPolyfill: getPolyfill,\n implementation: implementation,\n shim: shim\n});\nmodule.exports = polyfill;","'use strict';\n\nvar has = require('has');\n\nvar RequireObjectCoercible = require('es-abstract/2019/RequireObjectCoercible');\n\nvar callBound = require('es-abstract/helpers/callBound');\n\nvar $isEnumerable = callBound('Object.prototype.propertyIsEnumerable');\n\nmodule.exports = function values(O) {\n var obj = RequireObjectCoercible(O);\n var vals = [];\n\n for (var key in obj) {\n if (has(obj, key) && $isEnumerable(obj, key)) {\n vals.push(obj[key]);\n }\n }\n\n return vals;\n};","'use strict';\n\nvar implementation = require('./implementation');\n\nmodule.exports = function getPolyfill() {\n return typeof Object.values === 'function' ? Object.values : implementation;\n};","'use strict';\n\nvar define = require('define-properties');\n\nvar implementation = require('./implementation');\n\nvar getPolyfill = require('./polyfill');\n\nvar shim = require('./shim');\n\nvar polyfill = getPolyfill();\n/* http://www.ecma-international.org/ecma-262/6.0/#sec-number.isnan */\n\ndefine(polyfill, {\n getPolyfill: getPolyfill,\n implementation: implementation,\n shim: shim\n});\nmodule.exports = polyfill;","'use strict';\n/* http://www.ecma-international.org/ecma-262/6.0/#sec-number.isnan */\n\nmodule.exports = function isNaN(value) {\n return value !== value;\n};","'use strict';\n\nvar implementation = require('./implementation');\n\nmodule.exports = function getPolyfill() {\n if (Number.isNaN && Number.isNaN(NaN) && !Number.isNaN('a')) {\n return Number.isNaN;\n }\n\n return implementation;\n};","'use strict';\n\nvar bind = require('function-bind');\n\nvar define = require('define-properties');\n\nvar implementation = require('./implementation');\n\nvar getPolyfill = require('./polyfill');\n\nvar shim = require('./shim');\n\nvar bound = bind.call(Function.call, getPolyfill());\ndefine(bound, {\n getPolyfill: getPolyfill,\n implementation: implementation,\n shim: shim\n});\nmodule.exports = bound;","'use strict';\n\nvar requirePromise = require('./requirePromise');\n\nrequirePromise();\n\nvar IsCallable = require('es-abstract/2018/IsCallable');\n\nvar SpeciesConstructor = require('es-abstract/2018/SpeciesConstructor');\n\nvar Type = require('es-abstract/2018/Type');\n\nvar promiseResolve = function PromiseResolve(C, value) {\n return new C(function (resolve) {\n resolve(value);\n });\n};\n\nvar OriginalPromise = Promise;\n\nvar createThenFinally = function CreateThenFinally(C, onFinally) {\n return function (value) {\n var result = onFinally();\n var promise = promiseResolve(C, result);\n\n var valueThunk = function valueThunk() {\n return value;\n };\n\n return promise.then(valueThunk);\n };\n};\n\nvar createCatchFinally = function CreateCatchFinally(C, onFinally) {\n return function (reason) {\n var result = onFinally();\n var promise = promiseResolve(C, result);\n\n var thrower = function thrower() {\n throw reason;\n };\n\n return promise.then(thrower);\n };\n};\n\nvar promiseFinally = function finally_(onFinally) {\n /* eslint no-invalid-this: 0 */\n var promise = this;\n\n if (Type(promise) !== 'Object') {\n throw new TypeError('receiver is not an Object');\n }\n\n var C = SpeciesConstructor(promise, OriginalPromise); // may throw\n\n var thenFinally = onFinally;\n var catchFinally = onFinally;\n\n if (IsCallable(onFinally)) {\n thenFinally = createThenFinally(C, onFinally);\n catchFinally = createCatchFinally(C, onFinally);\n }\n\n return promise.then(thenFinally, catchFinally);\n};\n\nif (Object.getOwnPropertyDescriptor) {\n var descriptor = Object.getOwnPropertyDescriptor(promiseFinally, 'name');\n\n if (descriptor && descriptor.configurable) {\n Object.defineProperty(promiseFinally, 'name', {\n configurable: true,\n value: 'finally'\n });\n }\n}\n\nmodule.exports = promiseFinally;","'use strict';\n\nvar ES5Type = require('../5/Type'); // https://www.ecma-international.org/ecma-262/6.0/#sec-tostring\n\n\nmodule.exports = function Type(x) {\n if (typeof x === 'symbol') {\n return 'Symbol';\n }\n\n return ES5Type(x);\n};","'use strict';\n\nvar requirePromise = require('./requirePromise');\n\nvar implementation = require('./implementation');\n\nmodule.exports = function getPolyfill() {\n requirePromise();\n return typeof Promise.prototype['finally'] === 'function' ? Promise.prototype['finally'] : implementation;\n};","'use strict';\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) {\n return typeof obj;\n} : function (obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol ? \"symbol\" : typeof obj;\n};\n\nvar jsx = function () {\n var REACT_ELEMENT_TYPE = typeof Symbol === \"function\" && Symbol.for && Symbol.for(\"react.element\") || 0xeac7;\n return function createRawReactElement(type, props, key, children) {\n var defaultProps = type && type.defaultProps;\n var childrenLength = arguments.length - 3;\n\n if (!props && childrenLength !== 0) {\n props = {};\n }\n\n if (props && defaultProps) {\n for (var propName in defaultProps) {\n if (props[propName] === void 0) {\n props[propName] = defaultProps[propName];\n }\n }\n } else if (!props) {\n props = defaultProps || {};\n }\n\n if (childrenLength === 1) {\n props.children = children;\n } else if (childrenLength > 1) {\n var childArray = Array(childrenLength);\n\n for (var i = 0; i < childrenLength; i++) {\n childArray[i] = arguments[i + 3];\n }\n\n props.children = childArray;\n }\n\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key === undefined ? null : '' + key,\n ref: null,\n props: props,\n _owner: null\n };\n };\n}();\n\nvar asyncToGenerator = function asyncToGenerator(fn) {\n return function () {\n var gen = fn.apply(this, arguments);\n return new Promise(function (resolve, reject) {\n function step(key, arg) {\n try {\n var info = gen[key](arg);\n var value = info.value;\n } catch (error) {\n reject(error);\n return;\n }\n\n if (info.done) {\n resolve(value);\n } else {\n return Promise.resolve(value).then(function (value) {\n return step(\"next\", value);\n }, function (err) {\n return step(\"throw\", err);\n });\n }\n }\n\n return step(\"next\");\n });\n };\n};\n\nvar classCallCheck = function classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n};\n\nvar createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n}();\n\nvar defineEnumerableProperties = function defineEnumerableProperties(obj, descs) {\n for (var key in descs) {\n var desc = descs[key];\n desc.configurable = desc.enumerable = true;\n if (\"value\" in desc) desc.writable = true;\n Object.defineProperty(obj, key, desc);\n }\n\n return obj;\n};\n\nvar defaults = function defaults(obj, _defaults) {\n var keys = Object.getOwnPropertyNames(_defaults);\n\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n var value = Object.getOwnPropertyDescriptor(_defaults, key);\n\n if (value && value.configurable && obj[key] === undefined) {\n Object.defineProperty(obj, key, value);\n }\n }\n\n return obj;\n};\n\nvar defineProperty$1 = function defineProperty$1(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n};\n\nvar _extends = Object.assign || function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n};\n\nvar get = function get(object, property, receiver) {\n if (object === null) object = Function.prototype;\n var desc = Object.getOwnPropertyDescriptor(object, property);\n\n if (desc === undefined) {\n var parent = Object.getPrototypeOf(object);\n\n if (parent === null) {\n return undefined;\n } else {\n return get(parent, property, receiver);\n }\n } else if (\"value\" in desc) {\n return desc.value;\n } else {\n var getter = desc.get;\n\n if (getter === undefined) {\n return undefined;\n }\n\n return getter.call(receiver);\n }\n};\n\nvar inherits = function inherits(subClass, superClass) {\n if (typeof superClass !== \"function\" && superClass !== null) {\n throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass);\n }\n\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;\n};\n\nvar _instanceof = function _instanceof(left, right) {\n if (right != null && typeof Symbol !== \"undefined\" && right[Symbol.hasInstance]) {\n return right[Symbol.hasInstance](left);\n } else {\n return left instanceof right;\n }\n};\n\nvar interopRequireDefault = function interopRequireDefault(obj) {\n return obj && obj.__esModule ? obj : {\n default: obj\n };\n};\n\nvar interopRequireWildcard = function interopRequireWildcard(obj) {\n if (obj && obj.__esModule) {\n return obj;\n } else {\n var newObj = {};\n\n if (obj != null) {\n for (var key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];\n }\n }\n\n newObj.default = obj;\n return newObj;\n }\n};\n\nvar newArrowCheck = function newArrowCheck(innerThis, boundThis) {\n if (innerThis !== boundThis) {\n throw new TypeError(\"Cannot instantiate an arrow function\");\n }\n};\n\nvar objectDestructuringEmpty = function objectDestructuringEmpty(obj) {\n if (obj == null) throw new TypeError(\"Cannot destructure undefined\");\n};\n\nvar objectWithoutProperties = function objectWithoutProperties(obj, keys) {\n var target = {};\n\n for (var i in obj) {\n if (keys.indexOf(i) >= 0) continue;\n if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;\n target[i] = obj[i];\n }\n\n return target;\n};\n\nvar possibleConstructorReturn = function possibleConstructorReturn(self, call) {\n if (!self) {\n throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n }\n\n return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self;\n};\n\nvar selfGlobal = typeof global === \"undefined\" ? self : global;\n\nvar set = function set(object, property, value, receiver) {\n var desc = Object.getOwnPropertyDescriptor(object, property);\n\n if (desc === undefined) {\n var parent = Object.getPrototypeOf(object);\n\n if (parent !== null) {\n set(parent, property, value, receiver);\n }\n } else if (\"value\" in desc && desc.writable) {\n desc.value = value;\n } else {\n var setter = desc.set;\n\n if (setter !== undefined) {\n setter.call(receiver, value);\n }\n }\n\n return value;\n};\n\nvar slicedToArray = function () {\n function sliceIterator(arr, i) {\n var _arr = [];\n var _n = true;\n var _d = false;\n var _e = undefined;\n\n try {\n for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"]) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n }\n\n return function (arr, i) {\n if (Array.isArray(arr)) {\n return arr;\n } else if (Symbol.iterator in Object(arr)) {\n return sliceIterator(arr, i);\n } else {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance\");\n }\n };\n}();\n\nvar slicedToArrayLoose = function slicedToArrayLoose(arr, i) {\n if (Array.isArray(arr)) {\n return arr;\n } else if (Symbol.iterator in Object(arr)) {\n var _arr = [];\n\n for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) {\n _arr.push(_step.value);\n\n if (i && _arr.length === i) break;\n }\n\n return _arr;\n } else {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance\");\n }\n};\n\nvar taggedTemplateLiteral = function taggedTemplateLiteral(strings, raw) {\n return Object.freeze(Object.defineProperties(strings, {\n raw: {\n value: Object.freeze(raw)\n }\n }));\n};\n\nvar taggedTemplateLiteralLoose = function taggedTemplateLiteralLoose(strings, raw) {\n strings.raw = raw;\n return strings;\n};\n\nvar temporalRef = function temporalRef(val, name, undef) {\n if (val === undef) {\n throw new ReferenceError(name + \" is not defined - temporal dead zone\");\n } else {\n return val;\n }\n};\n\nvar temporalUndefined = {};\n\nvar toArray = function toArray(arr) {\n return Array.isArray(arr) ? arr : Array.from(arr);\n};\n\nvar toConsumableArray = function toConsumableArray(arr) {\n if (Array.isArray(arr)) {\n for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {\n arr2[i] = arr[i];\n }\n\n return arr2;\n } else {\n return Array.from(arr);\n }\n};\n\nvar babelHelpers$1 = Object.freeze({\n jsx: jsx,\n asyncToGenerator: asyncToGenerator,\n classCallCheck: classCallCheck,\n createClass: createClass,\n defineEnumerableProperties: defineEnumerableProperties,\n defaults: defaults,\n defineProperty: defineProperty$1,\n get: get,\n inherits: inherits,\n interopRequireDefault: interopRequireDefault,\n interopRequireWildcard: interopRequireWildcard,\n newArrowCheck: newArrowCheck,\n objectDestructuringEmpty: objectDestructuringEmpty,\n objectWithoutProperties: objectWithoutProperties,\n possibleConstructorReturn: possibleConstructorReturn,\n selfGlobal: selfGlobal,\n set: set,\n slicedToArray: slicedToArray,\n slicedToArrayLoose: slicedToArrayLoose,\n taggedTemplateLiteral: taggedTemplateLiteral,\n taggedTemplateLiteralLoose: taggedTemplateLiteralLoose,\n temporalRef: temporalRef,\n temporalUndefined: temporalUndefined,\n toArray: toArray,\n toConsumableArray: toConsumableArray,\n typeof: _typeof,\n extends: _extends,\n instanceof: _instanceof\n});\n\nvar realDefineProp = function () {\n var sentinel = function sentinel() {};\n\n try {\n Object.defineProperty(sentinel, 'a', {\n get: function get() {\n return 1;\n }\n });\n Object.defineProperty(sentinel, 'prototype', {\n writable: false\n });\n return sentinel.a === 1 && sentinel.prototype instanceof Object;\n } catch (e) {\n return false;\n }\n}(); // Need a workaround for getters in ES3\n\n\nvar es3 = !realDefineProp && !Object.prototype.__defineGetter__; // We use this a lot (and need it for proto-less objects)\n\nvar hop = Object.prototype.hasOwnProperty; // Naive defineProperty for compatibility\n\nvar defineProperty = realDefineProp ? Object.defineProperty : function (obj, name, desc) {\n if ('get' in desc && obj.__defineGetter__) obj.__defineGetter__(name, desc.get);else if (!hop.call(obj, name) || 'value' in desc) obj[name] = desc.value;\n}; // Array.prototype.indexOf, as good as we need it to be\n\nvar arrIndexOf = Array.prototype.indexOf || function (search) {\n /*jshint validthis:true */\n var t = this;\n if (!t.length) return -1;\n\n for (var i = arguments[1] || 0, max = t.length; i < max; i++) {\n if (t[i] === search) return i;\n }\n\n return -1;\n}; // Create an object with the specified prototype (2nd arg required for Record)\n\n\nvar objCreate = Object.create || function (proto, props) {\n var obj = void 0;\n\n function F() {}\n\n F.prototype = proto;\n obj = new F();\n\n for (var k in props) {\n if (hop.call(props, k)) defineProperty(obj, k, props[k]);\n }\n\n return obj;\n}; // Snapshot some (hopefully still) native built-ins\n\n\nvar arrSlice = Array.prototype.slice;\nvar arrConcat = Array.prototype.concat;\nvar arrPush = Array.prototype.push;\nvar arrJoin = Array.prototype.join;\nvar arrShift = Array.prototype.shift; // Naive Function.prototype.bind for compatibility\n\nvar fnBind = Function.prototype.bind || function (thisObj) {\n var fn = this,\n args = arrSlice.call(arguments, 1); // All our (presently) bound functions have either 1 or 0 arguments. By returning\n // different function signatures, we can pass some tests in ES3 environments\n\n if (fn.length === 1) {\n return function () {\n return fn.apply(thisObj, arrConcat.call(args, arrSlice.call(arguments)));\n };\n }\n\n return function () {\n return fn.apply(thisObj, arrConcat.call(args, arrSlice.call(arguments)));\n };\n}; // Object housing internal properties for constructors\n\n\nvar internals = objCreate(null); // Keep internal properties internal\n\nvar secret = Math.random(); // Helper functions\n// ================\n\n/**\n * A function to deal with the inaccuracy of calculating log10 in pre-ES6\n * JavaScript environments. Math.log(num) / Math.LN10 was responsible for\n * causing issue #62.\n */\n\nfunction log10Floor(n) {\n // ES6 provides the more accurate Math.log10\n if (typeof Math.log10 === 'function') return Math.floor(Math.log10(n));\n var x = Math.round(Math.log(n) * Math.LOG10E);\n return x - (Number('1e' + x) > n);\n}\n/**\n * A map that doesn't contain Object in its prototype chain\n */\n\n\nfunction Record(obj) {\n // Copy only own properties over unless this object is already a Record instance\n for (var k in obj) {\n if (obj instanceof Record || hop.call(obj, k)) defineProperty(this, k, {\n value: obj[k],\n enumerable: true,\n writable: true,\n configurable: true\n });\n }\n}\n\nRecord.prototype = objCreate(null);\n/**\n * An ordered list\n */\n\nfunction List() {\n defineProperty(this, 'length', {\n writable: true,\n value: 0\n });\n if (arguments.length) arrPush.apply(this, arrSlice.call(arguments));\n}\n\nList.prototype = objCreate(null);\n/**\n * Constructs a regular expression to restore tainted RegExp properties\n */\n\nfunction createRegExpRestore() {\n if (internals.disableRegExpRestore) {\n return function () {\n /* no-op */\n };\n }\n\n var regExpCache = {\n lastMatch: RegExp.lastMatch || '',\n leftContext: RegExp.leftContext,\n multiline: RegExp.multiline,\n input: RegExp.input\n },\n has = false; // Create a snapshot of all the 'captured' properties\n\n for (var i = 1; i <= 9; i++) {\n has = (regExpCache['$' + i] = RegExp['$' + i]) || has;\n }\n\n return function () {\n // Now we've snapshotted some properties, escape the lastMatch string\n var esc = /[.?*+^$[\\]\\\\(){}|-]/g,\n lm = regExpCache.lastMatch.replace(esc, '\\\\$&'),\n reg = new List(); // If any of the captured strings were non-empty, iterate over them all\n\n if (has) {\n for (var _i = 1; _i <= 9; _i++) {\n var m = regExpCache['$' + _i]; // If it's empty, add an empty capturing group\n\n if (!m) lm = '()' + lm; // Else find the string in lm and escape & wrap it to capture it\n else {\n m = m.replace(esc, '\\\\$&');\n lm = lm.replace(m, '(' + m + ')');\n } // Push it to the reg and chop lm to make sure further groups come after\n\n arrPush.call(reg, lm.slice(0, lm.indexOf('(') + 1));\n lm = lm.slice(lm.indexOf('(') + 1);\n }\n }\n\n var exprStr = arrJoin.call(reg, '') + lm; // Shorten the regex by replacing each part of the expression with a match\n // for a string of that exact length. This is safe for the type of\n // expressions generated above, because the expression matches the whole\n // match string, so we know each group and each segment between capturing\n // groups can be matched by its length alone.\n\n exprStr = exprStr.replace(/(\\\\\\(|\\\\\\)|[^()])+/g, function (match) {\n return '[\\\\s\\\\S]{' + match.replace('\\\\', '').length + '}';\n }); // Create the regular expression that will reconstruct the RegExp properties\n\n var expr = new RegExp(exprStr, regExpCache.multiline ? 'gm' : 'g'); // Set the lastIndex of the generated expression to ensure that the match\n // is found in the correct index.\n\n expr.lastIndex = regExpCache.leftContext.length;\n expr.exec(regExpCache.input);\n };\n}\n/**\n * Mimics ES5's abstract ToObject() function\n */\n\n\nfunction toObject(arg) {\n if (arg === null) throw new TypeError('Cannot convert null or undefined to object');\n if ((typeof arg === 'undefined' ? 'undefined' : babelHelpers$1['typeof'](arg)) === 'object') return arg;\n return Object(arg);\n}\n\nfunction toNumber(arg) {\n if (typeof arg === 'number') return arg;\n return Number(arg);\n}\n\nfunction toInteger(arg) {\n var number = toNumber(arg);\n if (isNaN(number)) return 0;\n if (number === +0 || number === -0 || number === +Infinity || number === -Infinity) return number;\n if (number < 0) return Math.floor(Math.abs(number)) * -1;\n return Math.floor(Math.abs(number));\n}\n\nfunction toLength(arg) {\n var len = toInteger(arg);\n if (len <= 0) return 0;\n if (len === Infinity) return Math.pow(2, 53) - 1;\n return Math.min(len, Math.pow(2, 53) - 1);\n}\n/**\n * Returns \"internal\" properties for an object\n */\n\n\nfunction getInternalProperties(obj) {\n if (hop.call(obj, '__getInternalProperties')) return obj.__getInternalProperties(secret);\n return objCreate(null);\n}\n/**\n* Defines regular expressions for various operations related to the BCP 47 syntax,\n* as defined at http://tools.ietf.org/html/bcp47#section-2.1\n*/\n// extlang = 3ALPHA ; selected ISO 639 codes\n// *2(\"-\" 3ALPHA) ; permanently reserved\n\n\nvar extlang = '[a-z]{3}(?:-[a-z]{3}){0,2}'; // language = 2*3ALPHA ; shortest ISO 639 code\n// [\"-\" extlang] ; sometimes followed by\n// ; extended language subtags\n// / 4ALPHA ; or reserved for future use\n// / 5*8ALPHA ; or registered language subtag\n\nvar language = '(?:[a-z]{2,3}(?:-' + extlang + ')?|[a-z]{4}|[a-z]{5,8})'; // script = 4ALPHA ; ISO 15924 code\n\nvar script = '[a-z]{4}'; // region = 2ALPHA ; ISO 3166-1 code\n// / 3DIGIT ; UN M.49 code\n\nvar region = '(?:[a-z]{2}|\\\\d{3})'; // variant = 5*8alphanum ; registered variants\n// / (DIGIT 3alphanum)\n\nvar variant = '(?:[a-z0-9]{5,8}|\\\\d[a-z0-9]{3})'; // ; Single alphanumerics\n// ; \"x\" reserved for private use\n// singleton = DIGIT ; 0 - 9\n// / %x41-57 ; A - W\n// / %x59-5A ; Y - Z\n// / %x61-77 ; a - w\n// / %x79-7A ; y - z\n\nvar singleton = '[0-9a-wy-z]'; // extension = singleton 1*(\"-\" (2*8alphanum))\n\nvar extension = singleton + '(?:-[a-z0-9]{2,8})+'; // privateuse = \"x\" 1*(\"-\" (1*8alphanum))\n\nvar privateuse = 'x(?:-[a-z0-9]{1,8})+'; // irregular = \"en-GB-oed\" ; irregular tags do not match\n// / \"i-ami\" ; the 'langtag' production and\n// / \"i-bnn\" ; would not otherwise be\n// / \"i-default\" ; considered 'well-formed'\n// / \"i-enochian\" ; These tags are all valid,\n// / \"i-hak\" ; but most are deprecated\n// / \"i-klingon\" ; in favor of more modern\n// / \"i-lux\" ; subtags or subtag\n// / \"i-mingo\" ; combination\n// / \"i-navajo\"\n// / \"i-pwn\"\n// / \"i-tao\"\n// / \"i-tay\"\n// / \"i-tsu\"\n// / \"sgn-BE-FR\"\n// / \"sgn-BE-NL\"\n// / \"sgn-CH-DE\"\n\nvar irregular = '(?:en-GB-oed' + '|i-(?:ami|bnn|default|enochian|hak|klingon|lux|mingo|navajo|pwn|tao|tay|tsu)' + '|sgn-(?:BE-FR|BE-NL|CH-DE))'; // regular = \"art-lojban\" ; these tags match the 'langtag'\n// / \"cel-gaulish\" ; production, but their subtags\n// / \"no-bok\" ; are not extended language\n// / \"no-nyn\" ; or variant subtags: their meaning\n// / \"zh-guoyu\" ; is defined by their registration\n// / \"zh-hakka\" ; and all of these are deprecated\n// / \"zh-min\" ; in favor of a more modern\n// / \"zh-min-nan\" ; subtag or sequence of subtags\n// / \"zh-xiang\"\n\nvar regular = '(?:art-lojban|cel-gaulish|no-bok|no-nyn' + '|zh-(?:guoyu|hakka|min|min-nan|xiang))'; // grandfathered = irregular ; non-redundant tags registered\n// / regular ; during the RFC 3066 era\n\nvar grandfathered = '(?:' + irregular + '|' + regular + ')'; // langtag = language\n// [\"-\" script]\n// [\"-\" region]\n// *(\"-\" variant)\n// *(\"-\" extension)\n// [\"-\" privateuse]\n\nvar langtag = language + '(?:-' + script + ')?(?:-' + region + ')?(?:-' + variant + ')*(?:-' + extension + ')*(?:-' + privateuse + ')?'; // Language-Tag = langtag ; normal language tags\n// / privateuse ; private use tag\n// / grandfathered ; grandfathered tags\n\nvar expBCP47Syntax = RegExp('^(?:' + langtag + '|' + privateuse + '|' + grandfathered + ')$', 'i'); // Match duplicate variants in a language tag\n\nvar expVariantDupes = RegExp('^(?!x).*?-(' + variant + ')-(?:\\\\w{4,8}-(?!x-))*\\\\1\\\\b', 'i'); // Match duplicate singletons in a language tag (except in private use)\n\nvar expSingletonDupes = RegExp('^(?!x).*?-(' + singleton + ')-(?:\\\\w+-(?!x-))*\\\\1\\\\b', 'i'); // Match all extension sequences\n\nvar expExtSequences = RegExp('-' + extension, 'ig'); // Default locale is the first-added locale data for us\n\nvar defaultLocale = void 0;\n\nfunction setDefaultLocale(locale) {\n defaultLocale = locale;\n} // IANA Subtag Registry redundant tag and subtag maps\n\n\nvar redundantTags = {\n tags: {\n \"art-lojban\": \"jbo\",\n \"i-ami\": \"ami\",\n \"i-bnn\": \"bnn\",\n \"i-hak\": \"hak\",\n \"i-klingon\": \"tlh\",\n \"i-lux\": \"lb\",\n \"i-navajo\": \"nv\",\n \"i-pwn\": \"pwn\",\n \"i-tao\": \"tao\",\n \"i-tay\": \"tay\",\n \"i-tsu\": \"tsu\",\n \"no-bok\": \"nb\",\n \"no-nyn\": \"nn\",\n \"sgn-BE-FR\": \"sfb\",\n \"sgn-BE-NL\": \"vgt\",\n \"sgn-CH-DE\": \"sgg\",\n \"zh-guoyu\": \"cmn\",\n \"zh-hakka\": \"hak\",\n \"zh-min-nan\": \"nan\",\n \"zh-xiang\": \"hsn\",\n \"sgn-BR\": \"bzs\",\n \"sgn-CO\": \"csn\",\n \"sgn-DE\": \"gsg\",\n \"sgn-DK\": \"dsl\",\n \"sgn-ES\": \"ssp\",\n \"sgn-FR\": \"fsl\",\n \"sgn-GB\": \"bfi\",\n \"sgn-GR\": \"gss\",\n \"sgn-IE\": \"isg\",\n \"sgn-IT\": \"ise\",\n \"sgn-JP\": \"jsl\",\n \"sgn-MX\": \"mfs\",\n \"sgn-NI\": \"ncs\",\n \"sgn-NL\": \"dse\",\n \"sgn-NO\": \"nsl\",\n \"sgn-PT\": \"psr\",\n \"sgn-SE\": \"swl\",\n \"sgn-US\": \"ase\",\n \"sgn-ZA\": \"sfs\",\n \"zh-cmn\": \"cmn\",\n \"zh-cmn-Hans\": \"cmn-Hans\",\n \"zh-cmn-Hant\": \"cmn-Hant\",\n \"zh-gan\": \"gan\",\n \"zh-wuu\": \"wuu\",\n \"zh-yue\": \"yue\"\n },\n subtags: {\n BU: \"MM\",\n DD: \"DE\",\n FX: \"FR\",\n TP: \"TL\",\n YD: \"YE\",\n ZR: \"CD\",\n heploc: \"alalc97\",\n 'in': \"id\",\n iw: \"he\",\n ji: \"yi\",\n jw: \"jv\",\n mo: \"ro\",\n ayx: \"nun\",\n bjd: \"drl\",\n ccq: \"rki\",\n cjr: \"mom\",\n cka: \"cmr\",\n cmk: \"xch\",\n drh: \"khk\",\n drw: \"prs\",\n gav: \"dev\",\n hrr: \"jal\",\n ibi: \"opa\",\n kgh: \"kml\",\n lcq: \"ppr\",\n mst: \"mry\",\n myt: \"mry\",\n sca: \"hle\",\n tie: \"ras\",\n tkk: \"twm\",\n tlw: \"weo\",\n tnf: \"prs\",\n ybd: \"rki\",\n yma: \"lrr\"\n },\n extLang: {\n aao: [\"aao\", \"ar\"],\n abh: [\"abh\", \"ar\"],\n abv: [\"abv\", \"ar\"],\n acm: [\"acm\", \"ar\"],\n acq: [\"acq\", \"ar\"],\n acw: [\"acw\", \"ar\"],\n acx: [\"acx\", \"ar\"],\n acy: [\"acy\", \"ar\"],\n adf: [\"adf\", \"ar\"],\n ads: [\"ads\", \"sgn\"],\n aeb: [\"aeb\", \"ar\"],\n aec: [\"aec\", \"ar\"],\n aed: [\"aed\", \"sgn\"],\n aen: [\"aen\", \"sgn\"],\n afb: [\"afb\", \"ar\"],\n afg: [\"afg\", \"sgn\"],\n ajp: [\"ajp\", \"ar\"],\n apc: [\"apc\", \"ar\"],\n apd: [\"apd\", \"ar\"],\n arb: [\"arb\", \"ar\"],\n arq: [\"arq\", \"ar\"],\n ars: [\"ars\", \"ar\"],\n ary: [\"ary\", \"ar\"],\n arz: [\"arz\", \"ar\"],\n ase: [\"ase\", \"sgn\"],\n asf: [\"asf\", \"sgn\"],\n asp: [\"asp\", \"sgn\"],\n asq: [\"asq\", \"sgn\"],\n asw: [\"asw\", \"sgn\"],\n auz: [\"auz\", \"ar\"],\n avl: [\"avl\", \"ar\"],\n ayh: [\"ayh\", \"ar\"],\n ayl: [\"ayl\", \"ar\"],\n ayn: [\"ayn\", \"ar\"],\n ayp: [\"ayp\", \"ar\"],\n bbz: [\"bbz\", \"ar\"],\n bfi: [\"bfi\", \"sgn\"],\n bfk: [\"bfk\", \"sgn\"],\n bjn: [\"bjn\", \"ms\"],\n bog: [\"bog\", \"sgn\"],\n bqn: [\"bqn\", \"sgn\"],\n bqy: [\"bqy\", \"sgn\"],\n btj: [\"btj\", \"ms\"],\n bve: [\"bve\", \"ms\"],\n bvl: [\"bvl\", \"sgn\"],\n bvu: [\"bvu\", \"ms\"],\n bzs: [\"bzs\", \"sgn\"],\n cdo: [\"cdo\", \"zh\"],\n cds: [\"cds\", \"sgn\"],\n cjy: [\"cjy\", \"zh\"],\n cmn: [\"cmn\", \"zh\"],\n coa: [\"coa\", \"ms\"],\n cpx: [\"cpx\", \"zh\"],\n csc: [\"csc\", \"sgn\"],\n csd: [\"csd\", \"sgn\"],\n cse: [\"cse\", \"sgn\"],\n csf: [\"csf\", \"sgn\"],\n csg: [\"csg\", \"sgn\"],\n csl: [\"csl\", \"sgn\"],\n csn: [\"csn\", \"sgn\"],\n csq: [\"csq\", \"sgn\"],\n csr: [\"csr\", \"sgn\"],\n czh: [\"czh\", \"zh\"],\n czo: [\"czo\", \"zh\"],\n doq: [\"doq\", \"sgn\"],\n dse: [\"dse\", \"sgn\"],\n dsl: [\"dsl\", \"sgn\"],\n dup: [\"dup\", \"ms\"],\n ecs: [\"ecs\", \"sgn\"],\n esl: [\"esl\", \"sgn\"],\n esn: [\"esn\", \"sgn\"],\n eso: [\"eso\", \"sgn\"],\n eth: [\"eth\", \"sgn\"],\n fcs: [\"fcs\", \"sgn\"],\n fse: [\"fse\", \"sgn\"],\n fsl: [\"fsl\", \"sgn\"],\n fss: [\"fss\", \"sgn\"],\n gan: [\"gan\", \"zh\"],\n gds: [\"gds\", \"sgn\"],\n gom: [\"gom\", \"kok\"],\n gse: [\"gse\", \"sgn\"],\n gsg: [\"gsg\", \"sgn\"],\n gsm: [\"gsm\", \"sgn\"],\n gss: [\"gss\", \"sgn\"],\n gus: [\"gus\", \"sgn\"],\n hab: [\"hab\", \"sgn\"],\n haf: [\"haf\", \"sgn\"],\n hak: [\"hak\", \"zh\"],\n hds: [\"hds\", \"sgn\"],\n hji: [\"hji\", \"ms\"],\n hks: [\"hks\", \"sgn\"],\n hos: [\"hos\", \"sgn\"],\n hps: [\"hps\", \"sgn\"],\n hsh: [\"hsh\", \"sgn\"],\n hsl: [\"hsl\", \"sgn\"],\n hsn: [\"hsn\", \"zh\"],\n icl: [\"icl\", \"sgn\"],\n ils: [\"ils\", \"sgn\"],\n inl: [\"inl\", \"sgn\"],\n ins: [\"ins\", \"sgn\"],\n ise: [\"ise\", \"sgn\"],\n isg: [\"isg\", \"sgn\"],\n isr: [\"isr\", \"sgn\"],\n jak: [\"jak\", \"ms\"],\n jax: [\"jax\", \"ms\"],\n jcs: [\"jcs\", \"sgn\"],\n jhs: [\"jhs\", \"sgn\"],\n jls: [\"jls\", \"sgn\"],\n jos: [\"jos\", \"sgn\"],\n jsl: [\"jsl\", \"sgn\"],\n jus: [\"jus\", \"sgn\"],\n kgi: [\"kgi\", \"sgn\"],\n knn: [\"knn\", \"kok\"],\n kvb: [\"kvb\", \"ms\"],\n kvk: [\"kvk\", \"sgn\"],\n kvr: [\"kvr\", \"ms\"],\n kxd: [\"kxd\", \"ms\"],\n lbs: [\"lbs\", \"sgn\"],\n lce: [\"lce\", \"ms\"],\n lcf: [\"lcf\", \"ms\"],\n liw: [\"liw\", \"ms\"],\n lls: [\"lls\", \"sgn\"],\n lsg: [\"lsg\", \"sgn\"],\n lsl: [\"lsl\", \"sgn\"],\n lso: [\"lso\", \"sgn\"],\n lsp: [\"lsp\", \"sgn\"],\n lst: [\"lst\", \"sgn\"],\n lsy: [\"lsy\", \"sgn\"],\n ltg: [\"ltg\", \"lv\"],\n lvs: [\"lvs\", \"lv\"],\n lzh: [\"lzh\", \"zh\"],\n max: [\"max\", \"ms\"],\n mdl: [\"mdl\", \"sgn\"],\n meo: [\"meo\", \"ms\"],\n mfa: [\"mfa\", \"ms\"],\n mfb: [\"mfb\", \"ms\"],\n mfs: [\"mfs\", \"sgn\"],\n min: [\"min\", \"ms\"],\n mnp: [\"mnp\", \"zh\"],\n mqg: [\"mqg\", \"ms\"],\n mre: [\"mre\", \"sgn\"],\n msd: [\"msd\", \"sgn\"],\n msi: [\"msi\", \"ms\"],\n msr: [\"msr\", \"sgn\"],\n mui: [\"mui\", \"ms\"],\n mzc: [\"mzc\", \"sgn\"],\n mzg: [\"mzg\", \"sgn\"],\n mzy: [\"mzy\", \"sgn\"],\n nan: [\"nan\", \"zh\"],\n nbs: [\"nbs\", \"sgn\"],\n ncs: [\"ncs\", \"sgn\"],\n nsi: [\"nsi\", \"sgn\"],\n nsl: [\"nsl\", \"sgn\"],\n nsp: [\"nsp\", \"sgn\"],\n nsr: [\"nsr\", \"sgn\"],\n nzs: [\"nzs\", \"sgn\"],\n okl: [\"okl\", \"sgn\"],\n orn: [\"orn\", \"ms\"],\n ors: [\"ors\", \"ms\"],\n pel: [\"pel\", \"ms\"],\n pga: [\"pga\", \"ar\"],\n pks: [\"pks\", \"sgn\"],\n prl: [\"prl\", \"sgn\"],\n prz: [\"prz\", \"sgn\"],\n psc: [\"psc\", \"sgn\"],\n psd: [\"psd\", \"sgn\"],\n pse: [\"pse\", \"ms\"],\n psg: [\"psg\", \"sgn\"],\n psl: [\"psl\", \"sgn\"],\n pso: [\"pso\", \"sgn\"],\n psp: [\"psp\", \"sgn\"],\n psr: [\"psr\", \"sgn\"],\n pys: [\"pys\", \"sgn\"],\n rms: [\"rms\", \"sgn\"],\n rsi: [\"rsi\", \"sgn\"],\n rsl: [\"rsl\", \"sgn\"],\n sdl: [\"sdl\", \"sgn\"],\n sfb: [\"sfb\", \"sgn\"],\n sfs: [\"sfs\", \"sgn\"],\n sgg: [\"sgg\", \"sgn\"],\n sgx: [\"sgx\", \"sgn\"],\n shu: [\"shu\", \"ar\"],\n slf: [\"slf\", \"sgn\"],\n sls: [\"sls\", \"sgn\"],\n sqk: [\"sqk\", \"sgn\"],\n sqs: [\"sqs\", \"sgn\"],\n ssh: [\"ssh\", \"ar\"],\n ssp: [\"ssp\", \"sgn\"],\n ssr: [\"ssr\", \"sgn\"],\n svk: [\"svk\", \"sgn\"],\n swc: [\"swc\", \"sw\"],\n swh: [\"swh\", \"sw\"],\n swl: [\"swl\", \"sgn\"],\n syy: [\"syy\", \"sgn\"],\n tmw: [\"tmw\", \"ms\"],\n tse: [\"tse\", \"sgn\"],\n tsm: [\"tsm\", \"sgn\"],\n tsq: [\"tsq\", \"sgn\"],\n tss: [\"tss\", \"sgn\"],\n tsy: [\"tsy\", \"sgn\"],\n tza: [\"tza\", \"sgn\"],\n ugn: [\"ugn\", \"sgn\"],\n ugy: [\"ugy\", \"sgn\"],\n ukl: [\"ukl\", \"sgn\"],\n uks: [\"uks\", \"sgn\"],\n urk: [\"urk\", \"ms\"],\n uzn: [\"uzn\", \"uz\"],\n uzs: [\"uzs\", \"uz\"],\n vgt: [\"vgt\", \"sgn\"],\n vkk: [\"vkk\", \"ms\"],\n vkt: [\"vkt\", \"ms\"],\n vsi: [\"vsi\", \"sgn\"],\n vsl: [\"vsl\", \"sgn\"],\n vsv: [\"vsv\", \"sgn\"],\n wuu: [\"wuu\", \"zh\"],\n xki: [\"xki\", \"sgn\"],\n xml: [\"xml\", \"sgn\"],\n xmm: [\"xmm\", \"ms\"],\n xms: [\"xms\", \"sgn\"],\n yds: [\"yds\", \"sgn\"],\n ysl: [\"ysl\", \"sgn\"],\n yue: [\"yue\", \"zh\"],\n zib: [\"zib\", \"sgn\"],\n zlm: [\"zlm\", \"ms\"],\n zmi: [\"zmi\", \"ms\"],\n zsl: [\"zsl\", \"sgn\"],\n zsm: [\"zsm\", \"ms\"]\n }\n};\n/**\n * Convert only a-z to uppercase as per section 6.1 of the spec\n */\n\nfunction toLatinUpperCase(str) {\n var i = str.length;\n\n while (i--) {\n var ch = str.charAt(i);\n if (ch >= \"a\" && ch <= \"z\") str = str.slice(0, i) + ch.toUpperCase() + str.slice(i + 1);\n }\n\n return str;\n}\n/**\n * The IsStructurallyValidLanguageTag abstract operation verifies that the locale\n * argument (which must be a String value)\n *\n * - represents a well-formed BCP 47 language tag as specified in RFC 5646 section\n * 2.1, or successor,\n * - does not include duplicate variant subtags, and\n * - does not include duplicate singleton subtags.\n *\n * The abstract operation returns true if locale can be generated from the ABNF\n * grammar in section 2.1 of the RFC, starting with Language-Tag, and does not\n * contain duplicate variant or singleton subtags (other than as a private use\n * subtag). It returns false otherwise. Terminal value characters in the grammar are\n * interpreted as the Unicode equivalents of the ASCII octet values given.\n */\n\n\nfunction\n/* 6.2.2 */\nIsStructurallyValidLanguageTag(locale) {\n // represents a well-formed BCP 47 language tag as specified in RFC 5646\n if (!expBCP47Syntax.test(locale)) return false; // does not include duplicate variant subtags, and\n\n if (expVariantDupes.test(locale)) return false; // does not include duplicate singleton subtags.\n\n if (expSingletonDupes.test(locale)) return false;\n return true;\n}\n/**\n * The CanonicalizeLanguageTag abstract operation returns the canonical and case-\n * regularized form of the locale argument (which must be a String value that is\n * a structurally valid BCP 47 language tag as verified by the\n * IsStructurallyValidLanguageTag abstract operation). It takes the steps\n * specified in RFC 5646 section 4.5, or successor, to bring the language tag\n * into canonical form, and to regularize the case of the subtags, but does not\n * take the steps to bring a language tag into “extlang form” and to reorder\n * variant subtags.\n\n * The specifications for extensions to BCP 47 language tags, such as RFC 6067,\n * may include canonicalization rules for the extension subtag sequences they\n * define that go beyond the canonicalization rules of RFC 5646 section 4.5.\n * Implementations are allowed, but not required, to apply these additional rules.\n */\n\n\nfunction\n/* 6.2.3 */\nCanonicalizeLanguageTag(locale) {\n var match = void 0,\n parts = void 0; // A language tag is in 'canonical form' when the tag is well-formed\n // according to the rules in Sections 2.1 and 2.2\n // Section 2.1 says all subtags use lowercase...\n\n locale = locale.toLowerCase(); // ...with 2 exceptions: 'two-letter and four-letter subtags that neither\n // appear at the start of the tag nor occur after singletons. Such two-letter\n // subtags are all uppercase (as in the tags \"en-CA-x-ca\" or \"sgn-BE-FR\") and\n // four-letter subtags are titlecase (as in the tag \"az-Latn-x-latn\").\n\n parts = locale.split('-');\n\n for (var i = 1, max = parts.length; i < max; i++) {\n // Two-letter subtags are all uppercase\n if (parts[i].length === 2) parts[i] = parts[i].toUpperCase(); // Four-letter subtags are titlecase\n else if (parts[i].length === 4) parts[i] = parts[i].charAt(0).toUpperCase() + parts[i].slice(1); // Is it a singleton?\n else if (parts[i].length === 1 && parts[i] !== 'x') break;\n }\n\n locale = arrJoin.call(parts, '-'); // The steps laid out in RFC 5646 section 4.5 are as follows:\n // 1. Extension sequences are ordered into case-insensitive ASCII order\n // by singleton subtag.\n\n if ((match = locale.match(expExtSequences)) && match.length > 1) {\n // The built-in sort() sorts by ASCII order, so use that\n match.sort(); // Replace all extensions with the joined, sorted array\n\n locale = locale.replace(RegExp('(?:' + expExtSequences.source + ')+', 'i'), arrJoin.call(match, ''));\n } // 2. Redundant or grandfathered tags are replaced by their 'Preferred-\n // Value', if there is one.\n\n\n if (hop.call(redundantTags.tags, locale)) locale = redundantTags.tags[locale]; // 3. Subtags are replaced by their 'Preferred-Value', if there is one.\n // For extlangs, the original primary language subtag is also\n // replaced if there is a primary language subtag in the 'Preferred-\n // Value'.\n\n parts = locale.split('-');\n\n for (var _i = 1, _max = parts.length; _i < _max; _i++) {\n if (hop.call(redundantTags.subtags, parts[_i])) parts[_i] = redundantTags.subtags[parts[_i]];else if (hop.call(redundantTags.extLang, parts[_i])) {\n parts[_i] = redundantTags.extLang[parts[_i]][0]; // For extlang tags, the prefix needs to be removed if it is redundant\n\n if (_i === 1 && redundantTags.extLang[parts[1]][1] === parts[0]) {\n parts = arrSlice.call(parts, _i++);\n _max -= 1;\n }\n }\n }\n\n return arrJoin.call(parts, '-');\n}\n/**\n * The DefaultLocale abstract operation returns a String value representing the\n * structurally valid (6.2.2) and canonicalized (6.2.3) BCP 47 language tag for the\n * host environment’s current locale.\n */\n\n\nfunction\n/* 6.2.4 */\nDefaultLocale() {\n return defaultLocale;\n} // Sect 6.3 Currency Codes\n// =======================\n\n\nvar expCurrencyCode = /^[A-Z]{3}$/;\n/**\n * The IsWellFormedCurrencyCode abstract operation verifies that the currency argument\n * (after conversion to a String value) represents a well-formed 3-letter ISO currency\n * code. The following steps are taken:\n */\n\nfunction\n/* 6.3.1 */\nIsWellFormedCurrencyCode(currency) {\n // 1. Let `c` be ToString(currency)\n var c = String(currency); // 2. Let `normalized` be the result of mapping c to upper case as described\n // in 6.1.\n\n var normalized = toLatinUpperCase(c); // 3. If the string length of normalized is not 3, return false.\n // 4. If normalized contains any character that is not in the range \"A\" to \"Z\"\n // (U+0041 to U+005A), return false.\n\n if (expCurrencyCode.test(normalized) === false) return false; // 5. Return true\n\n return true;\n}\n\nvar expUnicodeExSeq = /-u(?:-[0-9a-z]{2,8})+/gi; // See `extension` below\n\nfunction\n/* 9.2.1 */\nCanonicalizeLocaleList(locales) {\n // The abstract operation CanonicalizeLocaleList takes the following steps:\n // 1. If locales is undefined, then a. Return a new empty List\n if (locales === undefined) return new List(); // 2. Let seen be a new empty List.\n\n var seen = new List(); // 3. If locales is a String value, then\n // a. Let locales be a new array created as if by the expression new\n // Array(locales) where Array is the standard built-in constructor with\n // that name and locales is the value of locales.\n\n locales = typeof locales === 'string' ? [locales] : locales; // 4. Let O be ToObject(locales).\n\n var O = toObject(locales); // 5. Let lenValue be the result of calling the [[Get]] internal method of\n // O with the argument \"length\".\n // 6. Let len be ToUint32(lenValue).\n\n var len = toLength(O.length); // 7. Let k be 0.\n\n var k = 0; // 8. Repeat, while k < len\n\n while (k < len) {\n // a. Let Pk be ToString(k).\n var Pk = String(k); // b. Let kPresent be the result of calling the [[HasProperty]] internal\n // method of O with argument Pk.\n\n var kPresent = (Pk in O); // c. If kPresent is true, then\n\n if (kPresent) {\n // i. Let kValue be the result of calling the [[Get]] internal\n // method of O with argument Pk.\n var kValue = O[Pk]; // ii. If the type of kValue is not String or Object, then throw a\n // TypeError exception.\n\n if (kValue === null || typeof kValue !== 'string' && (typeof kValue === \"undefined\" ? \"undefined\" : babelHelpers$1[\"typeof\"](kValue)) !== 'object') throw new TypeError('String or Object type expected'); // iii. Let tag be ToString(kValue).\n\n var tag = String(kValue); // iv. If the result of calling the abstract operation\n // IsStructurallyValidLanguageTag (defined in 6.2.2), passing tag as\n // the argument, is false, then throw a RangeError exception.\n\n if (!IsStructurallyValidLanguageTag(tag)) throw new RangeError(\"'\" + tag + \"' is not a structurally valid language tag\"); // v. Let tag be the result of calling the abstract operation\n // CanonicalizeLanguageTag (defined in 6.2.3), passing tag as the\n // argument.\n\n tag = CanonicalizeLanguageTag(tag); // vi. If tag is not an element of seen, then append tag as the last\n // element of seen.\n\n if (arrIndexOf.call(seen, tag) === -1) arrPush.call(seen, tag);\n } // d. Increase k by 1.\n\n\n k++;\n } // 9. Return seen.\n\n\n return seen;\n}\n/**\n * The BestAvailableLocale abstract operation compares the provided argument\n * locale, which must be a String value with a structurally valid and\n * canonicalized BCP 47 language tag, against the locales in availableLocales and\n * returns either the longest non-empty prefix of locale that is an element of\n * availableLocales, or undefined if there is no such element. It uses the\n * fallback mechanism of RFC 4647, section 3.4. The following steps are taken:\n */\n\n\nfunction\n/* 9.2.2 */\nBestAvailableLocale(availableLocales, locale) {\n // 1. Let candidate be locale\n var candidate = locale; // 2. Repeat\n\n while (candidate) {\n // a. If availableLocales contains an element equal to candidate, then return\n // candidate.\n if (arrIndexOf.call(availableLocales, candidate) > -1) return candidate; // b. Let pos be the character index of the last occurrence of \"-\"\n // (U+002D) within candidate. If that character does not occur, return\n // undefined.\n\n var pos = candidate.lastIndexOf('-');\n if (pos < 0) return; // c. If pos ≥ 2 and the character \"-\" occurs at index pos-2 of candidate,\n // then decrease pos by 2.\n\n if (pos >= 2 && candidate.charAt(pos - 2) === '-') pos -= 2; // d. Let candidate be the substring of candidate from position 0, inclusive,\n // to position pos, exclusive.\n\n candidate = candidate.substring(0, pos);\n }\n}\n/**\n * The LookupMatcher abstract operation compares requestedLocales, which must be\n * a List as returned by CanonicalizeLocaleList, against the locales in\n * availableLocales and determines the best available language to meet the\n * request. The following steps are taken:\n */\n\n\nfunction\n/* 9.2.3 */\nLookupMatcher(availableLocales, requestedLocales) {\n // 1. Let i be 0.\n var i = 0; // 2. Let len be the number of elements in requestedLocales.\n\n var len = requestedLocales.length; // 3. Let availableLocale be undefined.\n\n var availableLocale = void 0;\n var locale = void 0,\n noExtensionsLocale = void 0; // 4. Repeat while i < len and availableLocale is undefined:\n\n while (i < len && !availableLocale) {\n // a. Let locale be the element of requestedLocales at 0-origined list\n // position i.\n locale = requestedLocales[i]; // b. Let noExtensionsLocale be the String value that is locale with all\n // Unicode locale extension sequences removed.\n\n noExtensionsLocale = String(locale).replace(expUnicodeExSeq, ''); // c. Let availableLocale be the result of calling the\n // BestAvailableLocale abstract operation (defined in 9.2.2) with\n // arguments availableLocales and noExtensionsLocale.\n\n availableLocale = BestAvailableLocale(availableLocales, noExtensionsLocale); // d. Increase i by 1.\n\n i++;\n } // 5. Let result be a new Record.\n\n\n var result = new Record(); // 6. If availableLocale is not undefined, then\n\n if (availableLocale !== undefined) {\n // a. Set result.[[locale]] to availableLocale.\n result['[[locale]]'] = availableLocale; // b. If locale and noExtensionsLocale are not the same String value, then\n\n if (String(locale) !== String(noExtensionsLocale)) {\n // i. Let extension be the String value consisting of the first\n // substring of locale that is a Unicode locale extension sequence.\n var extension = locale.match(expUnicodeExSeq)[0]; // ii. Let extensionIndex be the character position of the initial\n // \"-\" of the first Unicode locale extension sequence within locale.\n\n var extensionIndex = locale.indexOf('-u-'); // iii. Set result.[[extension]] to extension.\n\n result['[[extension]]'] = extension; // iv. Set result.[[extensionIndex]] to extensionIndex.\n\n result['[[extensionIndex]]'] = extensionIndex;\n }\n } // 7. Else\n else // a. Set result.[[locale]] to the value returned by the DefaultLocale abstract\n // operation (defined in 6.2.4).\n result['[[locale]]'] = DefaultLocale(); // 8. Return result\n\n\n return result;\n}\n/**\n * The BestFitMatcher abstract operation compares requestedLocales, which must be\n * a List as returned by CanonicalizeLocaleList, against the locales in\n * availableLocales and determines the best available language to meet the\n * request. The algorithm is implementation dependent, but should produce results\n * that a typical user of the requested locales would perceive as at least as\n * good as those produced by the LookupMatcher abstract operation. Options\n * specified through Unicode locale extension sequences must be ignored by the\n * algorithm. Information about such subsequences is returned separately.\n * The abstract operation returns a record with a [[locale]] field, whose value\n * is the language tag of the selected locale, which must be an element of\n * availableLocales. If the language tag of the request locale that led to the\n * selected locale contained a Unicode locale extension sequence, then the\n * returned record also contains an [[extension]] field whose value is the first\n * Unicode locale extension sequence, and an [[extensionIndex]] field whose value\n * is the index of the first Unicode locale extension sequence within the request\n * locale language tag.\n */\n\n\nfunction\n/* 9.2.4 */\nBestFitMatcher(availableLocales, requestedLocales) {\n return LookupMatcher(availableLocales, requestedLocales);\n}\n/**\n * The ResolveLocale abstract operation compares a BCP 47 language priority list\n * requestedLocales against the locales in availableLocales and determines the\n * best available language to meet the request. availableLocales and\n * requestedLocales must be provided as List values, options as a Record.\n */\n\n\nfunction\n/* 9.2.5 */\nResolveLocale(availableLocales, requestedLocales, options, relevantExtensionKeys, localeData) {\n if (availableLocales.length === 0) {\n throw new ReferenceError('No locale data has been provided for this object yet.');\n } // The following steps are taken:\n // 1. Let matcher be the value of options.[[localeMatcher]].\n\n\n var matcher = options['[[localeMatcher]]'];\n var r = void 0; // 2. If matcher is \"lookup\", then\n\n if (matcher === 'lookup') // a. Let r be the result of calling the LookupMatcher abstract operation\n // (defined in 9.2.3) with arguments availableLocales and\n // requestedLocales.\n r = LookupMatcher(availableLocales, requestedLocales); // 3. Else\n else // a. Let r be the result of calling the BestFitMatcher abstract\n // operation (defined in 9.2.4) with arguments availableLocales and\n // requestedLocales.\n r = BestFitMatcher(availableLocales, requestedLocales); // 4. Let foundLocale be the value of r.[[locale]].\n\n var foundLocale = r['[[locale]]'];\n var extensionSubtags = void 0,\n extensionSubtagsLength = void 0; // 5. If r has an [[extension]] field, then\n\n if (hop.call(r, '[[extension]]')) {\n // a. Let extension be the value of r.[[extension]].\n var extension = r['[[extension]]']; // b. Let split be the standard built-in function object defined in ES5,\n // 15.5.4.14.\n\n var split = String.prototype.split; // c. Let extensionSubtags be the result of calling the [[Call]] internal\n // method of split with extension as the this value and an argument\n // list containing the single item \"-\".\n\n extensionSubtags = split.call(extension, '-'); // d. Let extensionSubtagsLength be the result of calling the [[Get]]\n // internal method of extensionSubtags with argument \"length\".\n\n extensionSubtagsLength = extensionSubtags.length;\n } // 6. Let result be a new Record.\n\n\n var result = new Record(); // 7. Set result.[[dataLocale]] to foundLocale.\n\n result['[[dataLocale]]'] = foundLocale; // 8. Let supportedExtension be \"-u\".\n\n var supportedExtension = '-u'; // 9. Let i be 0.\n\n var i = 0; // 10. Let len be the result of calling the [[Get]] internal method of\n // relevantExtensionKeys with argument \"length\".\n\n var len = relevantExtensionKeys.length; // 11 Repeat while i < len:\n\n while (i < len) {\n // a. Let key be the result of calling the [[Get]] internal method of\n // relevantExtensionKeys with argument ToString(i).\n var key = relevantExtensionKeys[i]; // b. Let foundLocaleData be the result of calling the [[Get]] internal\n // method of localeData with the argument foundLocale.\n\n var foundLocaleData = localeData[foundLocale]; // c. Let keyLocaleData be the result of calling the [[Get]] internal\n // method of foundLocaleData with the argument key.\n\n var keyLocaleData = foundLocaleData[key]; // d. Let value be the result of calling the [[Get]] internal method of\n // keyLocaleData with argument \"0\".\n\n var value = keyLocaleData['0']; // e. Let supportedExtensionAddition be \"\".\n\n var supportedExtensionAddition = ''; // f. Let indexOf be the standard built-in function object defined in\n // ES5, 15.4.4.14.\n\n var indexOf = arrIndexOf; // g. If extensionSubtags is not undefined, then\n\n if (extensionSubtags !== undefined) {\n // i. Let keyPos be the result of calling the [[Call]] internal\n // method of indexOf with extensionSubtags as the this value and\n // an argument list containing the single item key.\n var keyPos = indexOf.call(extensionSubtags, key); // ii. If keyPos ≠ -1, then\n\n if (keyPos !== -1) {\n // 1. If keyPos + 1 < extensionSubtagsLength and the length of the\n // result of calling the [[Get]] internal method of\n // extensionSubtags with argument ToString(keyPos +1) is greater\n // than 2, then\n if (keyPos + 1 < extensionSubtagsLength && extensionSubtags[keyPos + 1].length > 2) {\n // a. Let requestedValue be the result of calling the [[Get]]\n // internal method of extensionSubtags with argument\n // ToString(keyPos + 1).\n var requestedValue = extensionSubtags[keyPos + 1]; // b. Let valuePos be the result of calling the [[Call]]\n // internal method of indexOf with keyLocaleData as the\n // this value and an argument list containing the single\n // item requestedValue.\n\n var valuePos = indexOf.call(keyLocaleData, requestedValue); // c. If valuePos ≠ -1, then\n\n if (valuePos !== -1) {\n // i. Let value be requestedValue.\n value = requestedValue, // ii. Let supportedExtensionAddition be the\n // concatenation of \"-\", key, \"-\", and value.\n supportedExtensionAddition = '-' + key + '-' + value;\n }\n } // 2. Else\n else {\n // a. Let valuePos be the result of calling the [[Call]]\n // internal method of indexOf with keyLocaleData as the this\n // value and an argument list containing the single item\n // \"true\".\n var _valuePos = indexOf(keyLocaleData, 'true'); // b. If valuePos ≠ -1, then\n\n\n if (_valuePos !== -1) // i. Let value be \"true\".\n value = 'true';\n }\n }\n } // h. If options has a field [[]], then\n\n\n if (hop.call(options, '[[' + key + ']]')) {\n // i. Let optionsValue be the value of options.[[]].\n var optionsValue = options['[[' + key + ']]']; // ii. If the result of calling the [[Call]] internal method of indexOf\n // with keyLocaleData as the this value and an argument list\n // containing the single item optionsValue is not -1, then\n\n if (indexOf.call(keyLocaleData, optionsValue) !== -1) {\n // 1. If optionsValue is not equal to value, then\n if (optionsValue !== value) {\n // a. Let value be optionsValue.\n value = optionsValue; // b. Let supportedExtensionAddition be \"\".\n\n supportedExtensionAddition = '';\n }\n }\n } // i. Set result.[[]] to value.\n\n\n result['[[' + key + ']]'] = value; // j. Append supportedExtensionAddition to supportedExtension.\n\n supportedExtension += supportedExtensionAddition; // k. Increase i by 1.\n\n i++;\n } // 12. If the length of supportedExtension is greater than 2, then\n\n\n if (supportedExtension.length > 2) {\n // a.\n var privateIndex = foundLocale.indexOf(\"-x-\"); // b.\n\n if (privateIndex === -1) {\n // i.\n foundLocale = foundLocale + supportedExtension;\n } // c.\n else {\n // i.\n var preExtension = foundLocale.substring(0, privateIndex); // ii.\n\n var postExtension = foundLocale.substring(privateIndex); // iii.\n\n foundLocale = preExtension + supportedExtension + postExtension;\n } // d. asserting - skipping\n // e.\n\n\n foundLocale = CanonicalizeLanguageTag(foundLocale);\n } // 13. Set result.[[locale]] to foundLocale.\n\n\n result['[[locale]]'] = foundLocale; // 14. Return result.\n\n return result;\n}\n/**\n * The LookupSupportedLocales abstract operation returns the subset of the\n * provided BCP 47 language priority list requestedLocales for which\n * availableLocales has a matching locale when using the BCP 47 Lookup algorithm.\n * Locales appear in the same order in the returned list as in requestedLocales.\n * The following steps are taken:\n */\n\n\nfunction\n/* 9.2.6 */\nLookupSupportedLocales(availableLocales, requestedLocales) {\n // 1. Let len be the number of elements in requestedLocales.\n var len = requestedLocales.length; // 2. Let subset be a new empty List.\n\n var subset = new List(); // 3. Let k be 0.\n\n var k = 0; // 4. Repeat while k < len\n\n while (k < len) {\n // a. Let locale be the element of requestedLocales at 0-origined list\n // position k.\n var locale = requestedLocales[k]; // b. Let noExtensionsLocale be the String value that is locale with all\n // Unicode locale extension sequences removed.\n\n var noExtensionsLocale = String(locale).replace(expUnicodeExSeq, ''); // c. Let availableLocale be the result of calling the\n // BestAvailableLocale abstract operation (defined in 9.2.2) with\n // arguments availableLocales and noExtensionsLocale.\n\n var availableLocale = BestAvailableLocale(availableLocales, noExtensionsLocale); // d. If availableLocale is not undefined, then append locale to the end of\n // subset.\n\n if (availableLocale !== undefined) arrPush.call(subset, locale); // e. Increment k by 1.\n\n k++;\n } // 5. Let subsetArray be a new Array object whose elements are the same\n // values in the same order as the elements of subset.\n\n\n var subsetArray = arrSlice.call(subset); // 6. Return subsetArray.\n\n return subsetArray;\n}\n/**\n * The BestFitSupportedLocales abstract operation returns the subset of the\n * provided BCP 47 language priority list requestedLocales for which\n * availableLocales has a matching locale when using the Best Fit Matcher\n * algorithm. Locales appear in the same order in the returned list as in\n * requestedLocales. The steps taken are implementation dependent.\n */\n\n\nfunction\n/*9.2.7 */\nBestFitSupportedLocales(availableLocales, requestedLocales) {\n // ###TODO: implement this function as described by the specification###\n return LookupSupportedLocales(availableLocales, requestedLocales);\n}\n/**\n * The SupportedLocales abstract operation returns the subset of the provided BCP\n * 47 language priority list requestedLocales for which availableLocales has a\n * matching locale. Two algorithms are available to match the locales: the Lookup\n * algorithm described in RFC 4647 section 3.4, and an implementation dependent\n * best-fit algorithm. Locales appear in the same order in the returned list as\n * in requestedLocales. The following steps are taken:\n */\n\n\nfunction\n/*9.2.8 */\nSupportedLocales(availableLocales, requestedLocales, options) {\n var matcher = void 0,\n subset = void 0; // 1. If options is not undefined, then\n\n if (options !== undefined) {\n // a. Let options be ToObject(options).\n options = new Record(toObject(options)); // b. Let matcher be the result of calling the [[Get]] internal method of\n // options with argument \"localeMatcher\".\n\n matcher = options.localeMatcher; // c. If matcher is not undefined, then\n\n if (matcher !== undefined) {\n // i. Let matcher be ToString(matcher).\n matcher = String(matcher); // ii. If matcher is not \"lookup\" or \"best fit\", then throw a RangeError\n // exception.\n\n if (matcher !== 'lookup' && matcher !== 'best fit') throw new RangeError('matcher should be \"lookup\" or \"best fit\"');\n }\n } // 2. If matcher is undefined or \"best fit\", then\n\n\n if (matcher === undefined || matcher === 'best fit') // a. Let subset be the result of calling the BestFitSupportedLocales\n // abstract operation (defined in 9.2.7) with arguments\n // availableLocales and requestedLocales.\n subset = BestFitSupportedLocales(availableLocales, requestedLocales); // 3. Else\n else // a. Let subset be the result of calling the LookupSupportedLocales\n // abstract operation (defined in 9.2.6) with arguments\n // availableLocales and requestedLocales.\n subset = LookupSupportedLocales(availableLocales, requestedLocales); // 4. For each named own property name P of subset,\n\n for (var P in subset) {\n if (!hop.call(subset, P)) continue; // a. Let desc be the result of calling the [[GetOwnProperty]] internal\n // method of subset with P.\n // b. Set desc.[[Writable]] to false.\n // c. Set desc.[[Configurable]] to false.\n // d. Call the [[DefineOwnProperty]] internal method of subset with P, desc,\n // and true as arguments.\n\n defineProperty(subset, P, {\n writable: false,\n configurable: false,\n value: subset[P]\n });\n } // \"Freeze\" the array so no new elements can be added\n\n\n defineProperty(subset, 'length', {\n writable: false\n }); // 5. Return subset\n\n return subset;\n}\n/**\n * The GetOption abstract operation extracts the value of the property named\n * property from the provided options object, converts it to the required type,\n * checks whether it is one of a List of allowed values, and fills in a fallback\n * value if necessary.\n */\n\n\nfunction\n/*9.2.9 */\nGetOption(options, property, type, values, fallback) {\n // 1. Let value be the result of calling the [[Get]] internal method of\n // options with argument property.\n var value = options[property]; // 2. If value is not undefined, then\n\n if (value !== undefined) {\n // a. Assert: type is \"boolean\" or \"string\".\n // b. If type is \"boolean\", then let value be ToBoolean(value).\n // c. If type is \"string\", then let value be ToString(value).\n value = type === 'boolean' ? Boolean(value) : type === 'string' ? String(value) : value; // d. If values is not undefined, then\n\n if (values !== undefined) {\n // i. If values does not contain an element equal to value, then throw a\n // RangeError exception.\n if (arrIndexOf.call(values, value) === -1) throw new RangeError(\"'\" + value + \"' is not an allowed value for `\" + property + '`');\n } // e. Return value.\n\n\n return value;\n } // Else return fallback.\n\n\n return fallback;\n}\n/**\n * The GetNumberOption abstract operation extracts a property value from the\n * provided options object, converts it to a Number value, checks whether it is\n * in the allowed range, and fills in a fallback value if necessary.\n */\n\n\nfunction\n/* 9.2.10 */\nGetNumberOption(options, property, minimum, maximum, fallback) {\n // 1. Let value be the result of calling the [[Get]] internal method of\n // options with argument property.\n var value = options[property]; // 2. If value is not undefined, then\n\n if (value !== undefined) {\n // a. Let value be ToNumber(value).\n value = Number(value); // b. If value is NaN or less than minimum or greater than maximum, throw a\n // RangeError exception.\n\n if (isNaN(value) || value < minimum || value > maximum) throw new RangeError('Value is not a number or outside accepted range'); // c. Return floor(value).\n\n return Math.floor(value);\n } // 3. Else return fallback.\n\n\n return fallback;\n} // 8 The Intl Object\n\n\nvar Intl = {}; // 8.2 Function Properties of the Intl Object\n// 8.2.1\n// @spec[tc39/ecma402/master/spec/intl.html]\n// @clause[sec-intl.getcanonicallocales]\n\nfunction getCanonicalLocales(locales) {\n // 1. Let ll be ? CanonicalizeLocaleList(locales).\n var ll = CanonicalizeLocaleList(locales); // 2. Return CreateArrayFromList(ll).\n\n {\n var result = [];\n var len = ll.length;\n var k = 0;\n\n while (k < len) {\n result[k] = ll[k];\n k++;\n }\n\n return result;\n }\n}\n\nObject.defineProperty(Intl, 'getCanonicalLocales', {\n enumerable: false,\n configurable: true,\n writable: true,\n value: getCanonicalLocales\n}); // Currency minor units output from get-4217 grunt task, formatted\n\nvar currencyMinorUnits = {\n BHD: 3,\n BYR: 0,\n XOF: 0,\n BIF: 0,\n XAF: 0,\n CLF: 4,\n CLP: 0,\n KMF: 0,\n DJF: 0,\n XPF: 0,\n GNF: 0,\n ISK: 0,\n IQD: 3,\n JPY: 0,\n JOD: 3,\n KRW: 0,\n KWD: 3,\n LYD: 3,\n OMR: 3,\n PYG: 0,\n RWF: 0,\n TND: 3,\n UGX: 0,\n UYI: 0,\n VUV: 0,\n VND: 0\n}; // Define the NumberFormat constructor internally so it cannot be tainted\n\nfunction NumberFormatConstructor() {\n var locales = arguments[0];\n var options = arguments[1];\n\n if (!this || this === Intl) {\n return new Intl.NumberFormat(locales, options);\n }\n\n return InitializeNumberFormat(toObject(this), locales, options);\n}\n\ndefineProperty(Intl, 'NumberFormat', {\n configurable: true,\n writable: true,\n value: NumberFormatConstructor\n}); // Must explicitly set prototypes as unwritable\n\ndefineProperty(Intl.NumberFormat, 'prototype', {\n writable: false\n});\n/**\n * The abstract operation InitializeNumberFormat accepts the arguments\n * numberFormat (which must be an object), locales, and options. It initializes\n * numberFormat as a NumberFormat object.\n */\n\nfunction\n/*11.1.1.1 */\nInitializeNumberFormat(numberFormat, locales, options) {\n // This will be a internal properties object if we're not already initialized\n var internal = getInternalProperties(numberFormat); // Create an object whose props can be used to restore the values of RegExp props\n\n var regexpRestore = createRegExpRestore(); // 1. If numberFormat has an [[initializedIntlObject]] internal property with\n // value true, throw a TypeError exception.\n\n if (internal['[[initializedIntlObject]]'] === true) throw new TypeError('`this` object has already been initialized as an Intl object'); // Need this to access the `internal` object\n\n defineProperty(numberFormat, '__getInternalProperties', {\n value: function value() {\n // NOTE: Non-standard, for internal use only\n if (arguments[0] === secret) return internal;\n }\n }); // 2. Set the [[initializedIntlObject]] internal property of numberFormat to true.\n\n internal['[[initializedIntlObject]]'] = true; // 3. Let requestedLocales be the result of calling the CanonicalizeLocaleList\n // abstract operation (defined in 9.2.1) with argument locales.\n\n var requestedLocales = CanonicalizeLocaleList(locales); // 4. If options is undefined, then\n\n if (options === undefined) // a. Let options be the result of creating a new object as if by the\n // expression new Object() where Object is the standard built-in constructor\n // with that name.\n options = {}; // 5. Else\n else // a. Let options be ToObject(options).\n options = toObject(options); // 6. Let opt be a new Record.\n\n var opt = new Record(),\n // 7. Let matcher be the result of calling the GetOption abstract operation\n // (defined in 9.2.9) with the arguments options, \"localeMatcher\", \"string\",\n // a List containing the two String values \"lookup\" and \"best fit\", and\n // \"best fit\".\n matcher = GetOption(options, 'localeMatcher', 'string', new List('lookup', 'best fit'), 'best fit'); // 8. Set opt.[[localeMatcher]] to matcher.\n\n opt['[[localeMatcher]]'] = matcher; // 9. Let NumberFormat be the standard built-in object that is the initial value\n // of Intl.NumberFormat.\n // 10. Let localeData be the value of the [[localeData]] internal property of\n // NumberFormat.\n\n var localeData = internals.NumberFormat['[[localeData]]']; // 11. Let r be the result of calling the ResolveLocale abstract operation\n // (defined in 9.2.5) with the [[availableLocales]] internal property of\n // NumberFormat, requestedLocales, opt, the [[relevantExtensionKeys]]\n // internal property of NumberFormat, and localeData.\n\n var r = ResolveLocale(internals.NumberFormat['[[availableLocales]]'], requestedLocales, opt, internals.NumberFormat['[[relevantExtensionKeys]]'], localeData); // 12. Set the [[locale]] internal property of numberFormat to the value of\n // r.[[locale]].\n\n internal['[[locale]]'] = r['[[locale]]']; // 13. Set the [[numberingSystem]] internal property of numberFormat to the value\n // of r.[[nu]].\n\n internal['[[numberingSystem]]'] = r['[[nu]]']; // The specification doesn't tell us to do this, but it's helpful later on\n\n internal['[[dataLocale]]'] = r['[[dataLocale]]']; // 14. Let dataLocale be the value of r.[[dataLocale]].\n\n var dataLocale = r['[[dataLocale]]']; // 15. Let s be the result of calling the GetOption abstract operation with the\n // arguments options, \"style\", \"string\", a List containing the three String\n // values \"decimal\", \"percent\", and \"currency\", and \"decimal\".\n\n var s = GetOption(options, 'style', 'string', new List('decimal', 'percent', 'currency'), 'decimal'); // 16. Set the [[style]] internal property of numberFormat to s.\n\n internal['[[style]]'] = s; // 17. Let c be the result of calling the GetOption abstract operation with the\n // arguments options, \"currency\", \"string\", undefined, and undefined.\n\n var c = GetOption(options, 'currency', 'string'); // 18. If c is not undefined and the result of calling the\n // IsWellFormedCurrencyCode abstract operation (defined in 6.3.1) with\n // argument c is false, then throw a RangeError exception.\n\n if (c !== undefined && !IsWellFormedCurrencyCode(c)) throw new RangeError(\"'\" + c + \"' is not a valid currency code\"); // 19. If s is \"currency\" and c is undefined, throw a TypeError exception.\n\n if (s === 'currency' && c === undefined) throw new TypeError('Currency code is required when style is currency');\n var cDigits = void 0; // 20. If s is \"currency\", then\n\n if (s === 'currency') {\n // a. Let c be the result of converting c to upper case as specified in 6.1.\n c = c.toUpperCase(); // b. Set the [[currency]] internal property of numberFormat to c.\n\n internal['[[currency]]'] = c; // c. Let cDigits be the result of calling the CurrencyDigits abstract\n // operation (defined below) with argument c.\n\n cDigits = CurrencyDigits(c);\n } // 21. Let cd be the result of calling the GetOption abstract operation with the\n // arguments options, \"currencyDisplay\", \"string\", a List containing the\n // three String values \"code\", \"symbol\", and \"name\", and \"symbol\".\n\n\n var cd = GetOption(options, 'currencyDisplay', 'string', new List('code', 'symbol', 'name'), 'symbol'); // 22. If s is \"currency\", then set the [[currencyDisplay]] internal property of\n // numberFormat to cd.\n\n if (s === 'currency') internal['[[currencyDisplay]]'] = cd; // 23. Let mnid be the result of calling the GetNumberOption abstract operation\n // (defined in 9.2.10) with arguments options, \"minimumIntegerDigits\", 1, 21,\n // and 1.\n\n var mnid = GetNumberOption(options, 'minimumIntegerDigits', 1, 21, 1); // 24. Set the [[minimumIntegerDigits]] internal property of numberFormat to mnid.\n\n internal['[[minimumIntegerDigits]]'] = mnid; // 25. If s is \"currency\", then let mnfdDefault be cDigits; else let mnfdDefault\n // be 0.\n\n var mnfdDefault = s === 'currency' ? cDigits : 0; // 26. Let mnfd be the result of calling the GetNumberOption abstract operation\n // with arguments options, \"minimumFractionDigits\", 0, 20, and mnfdDefault.\n\n var mnfd = GetNumberOption(options, 'minimumFractionDigits', 0, 20, mnfdDefault); // 27. Set the [[minimumFractionDigits]] internal property of numberFormat to mnfd.\n\n internal['[[minimumFractionDigits]]'] = mnfd; // 28. If s is \"currency\", then let mxfdDefault be max(mnfd, cDigits); else if s\n // is \"percent\", then let mxfdDefault be max(mnfd, 0); else let mxfdDefault\n // be max(mnfd, 3).\n\n var mxfdDefault = s === 'currency' ? Math.max(mnfd, cDigits) : s === 'percent' ? Math.max(mnfd, 0) : Math.max(mnfd, 3); // 29. Let mxfd be the result of calling the GetNumberOption abstract operation\n // with arguments options, \"maximumFractionDigits\", mnfd, 20, and mxfdDefault.\n\n var mxfd = GetNumberOption(options, 'maximumFractionDigits', mnfd, 20, mxfdDefault); // 30. Set the [[maximumFractionDigits]] internal property of numberFormat to mxfd.\n\n internal['[[maximumFractionDigits]]'] = mxfd; // 31. Let mnsd be the result of calling the [[Get]] internal method of options\n // with argument \"minimumSignificantDigits\".\n\n var mnsd = options.minimumSignificantDigits; // 32. Let mxsd be the result of calling the [[Get]] internal method of options\n // with argument \"maximumSignificantDigits\".\n\n var mxsd = options.maximumSignificantDigits; // 33. If mnsd is not undefined or mxsd is not undefined, then:\n\n if (mnsd !== undefined || mxsd !== undefined) {\n // a. Let mnsd be the result of calling the GetNumberOption abstract\n // operation with arguments options, \"minimumSignificantDigits\", 1, 21,\n // and 1.\n mnsd = GetNumberOption(options, 'minimumSignificantDigits', 1, 21, 1); // b. Let mxsd be the result of calling the GetNumberOption abstract\n // operation with arguments options, \"maximumSignificantDigits\", mnsd,\n // 21, and 21.\n\n mxsd = GetNumberOption(options, 'maximumSignificantDigits', mnsd, 21, 21); // c. Set the [[minimumSignificantDigits]] internal property of numberFormat\n // to mnsd, and the [[maximumSignificantDigits]] internal property of\n // numberFormat to mxsd.\n\n internal['[[minimumSignificantDigits]]'] = mnsd;\n internal['[[maximumSignificantDigits]]'] = mxsd;\n } // 34. Let g be the result of calling the GetOption abstract operation with the\n // arguments options, \"useGrouping\", \"boolean\", undefined, and true.\n\n\n var g = GetOption(options, 'useGrouping', 'boolean', undefined, true); // 35. Set the [[useGrouping]] internal property of numberFormat to g.\n\n internal['[[useGrouping]]'] = g; // 36. Let dataLocaleData be the result of calling the [[Get]] internal method of\n // localeData with argument dataLocale.\n\n var dataLocaleData = localeData[dataLocale]; // 37. Let patterns be the result of calling the [[Get]] internal method of\n // dataLocaleData with argument \"patterns\".\n\n var patterns = dataLocaleData.patterns; // 38. Assert: patterns is an object (see 11.2.3)\n // 39. Let stylePatterns be the result of calling the [[Get]] internal method of\n // patterns with argument s.\n\n var stylePatterns = patterns[s]; // 40. Set the [[positivePattern]] internal property of numberFormat to the\n // result of calling the [[Get]] internal method of stylePatterns with the\n // argument \"positivePattern\".\n\n internal['[[positivePattern]]'] = stylePatterns.positivePattern; // 41. Set the [[negativePattern]] internal property of numberFormat to the\n // result of calling the [[Get]] internal method of stylePatterns with the\n // argument \"negativePattern\".\n\n internal['[[negativePattern]]'] = stylePatterns.negativePattern; // 42. Set the [[boundFormat]] internal property of numberFormat to undefined.\n\n internal['[[boundFormat]]'] = undefined; // 43. Set the [[initializedNumberFormat]] internal property of numberFormat to\n // true.\n\n internal['[[initializedNumberFormat]]'] = true; // In ES3, we need to pre-bind the format() function\n\n if (es3) numberFormat.format = GetFormatNumber.call(numberFormat); // Restore the RegExp properties\n\n regexpRestore(); // Return the newly initialised object\n\n return numberFormat;\n}\n\nfunction CurrencyDigits(currency) {\n // When the CurrencyDigits abstract operation is called with an argument currency\n // (which must be an upper case String value), the following steps are taken:\n // 1. If the ISO 4217 currency and funds code list contains currency as an\n // alphabetic code, then return the minor unit value corresponding to the\n // currency from the list; else return 2.\n return currencyMinorUnits[currency] !== undefined ? currencyMinorUnits[currency] : 2;\n}\n/* 11.2.3 */\n\n\ninternals.NumberFormat = {\n '[[availableLocales]]': [],\n '[[relevantExtensionKeys]]': ['nu'],\n '[[localeData]]': {}\n};\n/**\n * When the supportedLocalesOf method of Intl.NumberFormat is called, the\n * following steps are taken:\n */\n\n/* 11.2.2 */\n\ndefineProperty(Intl.NumberFormat, 'supportedLocalesOf', {\n configurable: true,\n writable: true,\n value: fnBind.call(function (locales) {\n // Bound functions only have the `this` value altered if being used as a constructor,\n // this lets us imitate a native function that has no constructor\n if (!hop.call(this, '[[availableLocales]]')) throw new TypeError('supportedLocalesOf() is not a constructor'); // Create an object whose props can be used to restore the values of RegExp props\n\n var regexpRestore = createRegExpRestore(),\n // 1. If options is not provided, then let options be undefined.\n options = arguments[1],\n // 2. Let availableLocales be the value of the [[availableLocales]] internal\n // property of the standard built-in object that is the initial value of\n // Intl.NumberFormat.\n availableLocales = this['[[availableLocales]]'],\n // 3. Let requestedLocales be the result of calling the CanonicalizeLocaleList\n // abstract operation (defined in 9.2.1) with argument locales.\n requestedLocales = CanonicalizeLocaleList(locales); // Restore the RegExp properties\n\n regexpRestore(); // 4. Return the result of calling the SupportedLocales abstract operation\n // (defined in 9.2.8) with arguments availableLocales, requestedLocales,\n // and options.\n\n return SupportedLocales(availableLocales, requestedLocales, options);\n }, internals.NumberFormat)\n});\n/**\n * This named accessor property returns a function that formats a number\n * according to the effective locale and the formatting options of this\n * NumberFormat object.\n */\n\n/* 11.3.2 */\n\ndefineProperty(Intl.NumberFormat.prototype, 'format', {\n configurable: true,\n get: GetFormatNumber\n});\n\nfunction GetFormatNumber() {\n var internal = this !== null && babelHelpers$1[\"typeof\"](this) === 'object' && getInternalProperties(this); // Satisfy test 11.3_b\n\n if (!internal || !internal['[[initializedNumberFormat]]']) throw new TypeError('`this` value for format() is not an initialized Intl.NumberFormat object.'); // The value of the [[Get]] attribute is a function that takes the following\n // steps:\n // 1. If the [[boundFormat]] internal property of this NumberFormat object\n // is undefined, then:\n\n if (internal['[[boundFormat]]'] === undefined) {\n // a. Let F be a Function object, with internal properties set as\n // specified for built-in functions in ES5, 15, or successor, and the\n // length property set to 1, that takes the argument value and\n // performs the following steps:\n var F = function F(value) {\n // i. If value is not provided, then let value be undefined.\n // ii. Let x be ToNumber(value).\n // iii. Return the result of calling the FormatNumber abstract\n // operation (defined below) with arguments this and x.\n return FormatNumber(this,\n /* x = */\n Number(value));\n }; // b. Let bind be the standard built-in function object defined in ES5,\n // 15.3.4.5.\n // c. Let bf be the result of calling the [[Call]] internal method of\n // bind with F as the this value and an argument list containing\n // the single item this.\n\n\n var bf = fnBind.call(F, this); // d. Set the [[boundFormat]] internal property of this NumberFormat\n // object to bf.\n\n internal['[[boundFormat]]'] = bf;\n } // Return the value of the [[boundFormat]] internal property of this\n // NumberFormat object.\n\n\n return internal['[[boundFormat]]'];\n}\n\nfunction formatToParts() {\n var value = arguments.length <= 0 || arguments[0] === undefined ? undefined : arguments[0];\n var internal = this !== null && babelHelpers$1[\"typeof\"](this) === 'object' && getInternalProperties(this);\n if (!internal || !internal['[[initializedNumberFormat]]']) throw new TypeError('`this` value for formatToParts() is not an initialized Intl.NumberFormat object.');\n var x = Number(value);\n return FormatNumberToParts(this, x);\n}\n\nObject.defineProperty(Intl.NumberFormat.prototype, 'formatToParts', {\n configurable: true,\n enumerable: false,\n writable: true,\n value: formatToParts\n});\n/*\n * @spec[stasm/ecma402/number-format-to-parts/spec/numberformat.html]\n * @clause[sec-formatnumbertoparts]\n */\n\nfunction FormatNumberToParts(numberFormat, x) {\n // 1. Let parts be ? PartitionNumberPattern(numberFormat, x).\n var parts = PartitionNumberPattern(numberFormat, x); // 2. Let result be ArrayCreate(0).\n\n var result = []; // 3. Let n be 0.\n\n var n = 0; // 4. For each part in parts, do:\n\n for (var i = 0; parts.length > i; i++) {\n var part = parts[i]; // a. Let O be ObjectCreate(%ObjectPrototype%).\n\n var O = {}; // a. Perform ? CreateDataPropertyOrThrow(O, \"type\", part.[[type]]).\n\n O.type = part['[[type]]']; // a. Perform ? CreateDataPropertyOrThrow(O, \"value\", part.[[value]]).\n\n O.value = part['[[value]]']; // a. Perform ? CreateDataPropertyOrThrow(result, ? ToString(n), O).\n\n result[n] = O; // a. Increment n by 1.\n\n n += 1;\n } // 5. Return result.\n\n\n return result;\n}\n/*\n * @spec[stasm/ecma402/number-format-to-parts/spec/numberformat.html]\n * @clause[sec-partitionnumberpattern]\n */\n\n\nfunction PartitionNumberPattern(numberFormat, x) {\n var internal = getInternalProperties(numberFormat),\n locale = internal['[[dataLocale]]'],\n nums = internal['[[numberingSystem]]'],\n data = internals.NumberFormat['[[localeData]]'][locale],\n ild = data.symbols[nums] || data.symbols.latn,\n pattern = void 0; // 1. If x is not NaN and x < 0, then:\n\n if (!isNaN(x) && x < 0) {\n // a. Let x be -x.\n x = -x; // a. Let pattern be the value of numberFormat.[[negativePattern]].\n\n pattern = internal['[[negativePattern]]'];\n } // 2. Else,\n else {\n // a. Let pattern be the value of numberFormat.[[positivePattern]].\n pattern = internal['[[positivePattern]]'];\n } // 3. Let result be a new empty List.\n\n\n var result = new List(); // 4. Let beginIndex be Call(%StringProto_indexOf%, pattern, \"{\", 0).\n\n var beginIndex = pattern.indexOf('{', 0); // 5. Let endIndex be 0.\n\n var endIndex = 0; // 6. Let nextIndex be 0.\n\n var nextIndex = 0; // 7. Let length be the number of code units in pattern.\n\n var length = pattern.length; // 8. Repeat while beginIndex is an integer index into pattern:\n\n while (beginIndex > -1 && beginIndex < length) {\n // a. Set endIndex to Call(%StringProto_indexOf%, pattern, \"}\", beginIndex)\n endIndex = pattern.indexOf('}', beginIndex); // a. If endIndex = -1, throw new Error exception.\n\n if (endIndex === -1) throw new Error(); // a. If beginIndex is greater than nextIndex, then:\n\n if (beginIndex > nextIndex) {\n // i. Let literal be a substring of pattern from position nextIndex, inclusive, to position beginIndex, exclusive.\n var literal = pattern.substring(nextIndex, beginIndex); // ii. Add new part record { [[type]]: \"literal\", [[value]]: literal } as a new element of the list result.\n\n arrPush.call(result, {\n '[[type]]': 'literal',\n '[[value]]': literal\n });\n } // a. Let p be the substring of pattern from position beginIndex, exclusive, to position endIndex, exclusive.\n\n\n var p = pattern.substring(beginIndex + 1, endIndex); // a. If p is equal \"number\", then:\n\n if (p === \"number\") {\n // i. If x is NaN,\n if (isNaN(x)) {\n // 1. Let n be an ILD String value indicating the NaN value.\n var n = ild.nan; // 2. Add new part record { [[type]]: \"nan\", [[value]]: n } as a new element of the list result.\n\n arrPush.call(result, {\n '[[type]]': 'nan',\n '[[value]]': n\n });\n } // ii. Else if isFinite(x) is false,\n else if (!isFinite(x)) {\n // 1. Let n be an ILD String value indicating infinity.\n var _n = ild.infinity; // 2. Add new part record { [[type]]: \"infinity\", [[value]]: n } as a new element of the list result.\n\n arrPush.call(result, {\n '[[type]]': 'infinity',\n '[[value]]': _n\n });\n } // iii. Else,\n else {\n // 1. If the value of numberFormat.[[style]] is \"percent\" and isFinite(x), let x be 100 × x.\n if (internal['[[style]]'] === 'percent' && isFinite(x)) x *= 100;\n\n var _n2 = void 0; // 2. If the numberFormat.[[minimumSignificantDigits]] and numberFormat.[[maximumSignificantDigits]] are present, then\n\n\n if (hop.call(internal, '[[minimumSignificantDigits]]') && hop.call(internal, '[[maximumSignificantDigits]]')) {\n // a. Let n be ToRawPrecision(x, numberFormat.[[minimumSignificantDigits]], numberFormat.[[maximumSignificantDigits]]).\n _n2 = ToRawPrecision(x, internal['[[minimumSignificantDigits]]'], internal['[[maximumSignificantDigits]]']);\n } // 3. Else,\n else {\n // a. Let n be ToRawFixed(x, numberFormat.[[minimumIntegerDigits]], numberFormat.[[minimumFractionDigits]], numberFormat.[[maximumFractionDigits]]).\n _n2 = ToRawFixed(x, internal['[[minimumIntegerDigits]]'], internal['[[minimumFractionDigits]]'], internal['[[maximumFractionDigits]]']);\n } // 4. If the value of the numberFormat.[[numberingSystem]] matches one of the values in the \"Numbering System\" column of Table 2 below, then\n\n\n if (numSys[nums]) {\n (function () {\n // a. Let digits be an array whose 10 String valued elements are the UTF-16 string representations of the 10 digits specified in the \"Digits\" column of the matching row in Table 2.\n var digits = numSys[nums]; // a. Replace each digit in n with the value of digits[digit].\n\n _n2 = String(_n2).replace(/\\d/g, function (digit) {\n return digits[digit];\n });\n })();\n } // 5. Else use an implementation dependent algorithm to map n to the appropriate representation of n in the given numbering system.\n else _n2 = String(_n2); // ###TODO###\n\n\n var integer = void 0;\n var fraction = void 0; // 6. Let decimalSepIndex be Call(%StringProto_indexOf%, n, \".\", 0).\n\n var decimalSepIndex = _n2.indexOf('.', 0); // 7. If decimalSepIndex > 0, then:\n\n\n if (decimalSepIndex > 0) {\n // a. Let integer be the substring of n from position 0, inclusive, to position decimalSepIndex, exclusive.\n integer = _n2.substring(0, decimalSepIndex); // a. Let fraction be the substring of n from position decimalSepIndex, exclusive, to the end of n.\n\n fraction = _n2.substring(decimalSepIndex + 1, decimalSepIndex.length);\n } // 8. Else:\n else {\n // a. Let integer be n.\n integer = _n2; // a. Let fraction be undefined.\n\n fraction = undefined;\n } // 9. If the value of the numberFormat.[[useGrouping]] is true,\n\n\n if (internal['[[useGrouping]]'] === true) {\n // a. Let groupSepSymbol be the ILND String representing the grouping separator.\n var groupSepSymbol = ild.group; // a. Let groups be a List whose elements are, in left to right order, the substrings defined by ILND set of locations within the integer.\n\n var groups = []; // ----> implementation:\n // Primary group represents the group closest to the decimal\n\n var pgSize = data.patterns.primaryGroupSize || 3; // Secondary group is every other group\n\n var sgSize = data.patterns.secondaryGroupSize || pgSize; // Group only if necessary\n\n if (integer.length > pgSize) {\n // Index of the primary grouping separator\n var end = integer.length - pgSize; // Starting index for our loop\n\n var idx = end % sgSize;\n var start = integer.slice(0, idx);\n if (start.length) arrPush.call(groups, start); // Loop to separate into secondary grouping digits\n\n while (idx < end) {\n arrPush.call(groups, integer.slice(idx, idx + sgSize));\n idx += sgSize;\n } // Add the primary grouping digits\n\n\n arrPush.call(groups, integer.slice(end));\n } else {\n arrPush.call(groups, integer);\n } // a. Assert: The number of elements in groups List is greater than 0.\n\n\n if (groups.length === 0) throw new Error(); // a. Repeat, while groups List is not empty:\n\n while (groups.length) {\n // i. Remove the first element from groups and let integerGroup be the value of that element.\n var integerGroup = arrShift.call(groups); // ii. Add new part record { [[type]]: \"integer\", [[value]]: integerGroup } as a new element of the list result.\n\n arrPush.call(result, {\n '[[type]]': 'integer',\n '[[value]]': integerGroup\n }); // iii. If groups List is not empty, then:\n\n if (groups.length) {\n // 1. Add new part record { [[type]]: \"group\", [[value]]: groupSepSymbol } as a new element of the list result.\n arrPush.call(result, {\n '[[type]]': 'group',\n '[[value]]': groupSepSymbol\n });\n }\n }\n } // 10. Else,\n else {\n // a. Add new part record { [[type]]: \"integer\", [[value]]: integer } as a new element of the list result.\n arrPush.call(result, {\n '[[type]]': 'integer',\n '[[value]]': integer\n });\n } // 11. If fraction is not undefined, then:\n\n\n if (fraction !== undefined) {\n // a. Let decimalSepSymbol be the ILND String representing the decimal separator.\n var decimalSepSymbol = ild.decimal; // a. Add new part record { [[type]]: \"decimal\", [[value]]: decimalSepSymbol } as a new element of the list result.\n\n arrPush.call(result, {\n '[[type]]': 'decimal',\n '[[value]]': decimalSepSymbol\n }); // a. Add new part record { [[type]]: \"fraction\", [[value]]: fraction } as a new element of the list result.\n\n arrPush.call(result, {\n '[[type]]': 'fraction',\n '[[value]]': fraction\n });\n }\n }\n } // a. Else if p is equal \"plusSign\", then:\n else if (p === \"plusSign\") {\n // i. Let plusSignSymbol be the ILND String representing the plus sign.\n var plusSignSymbol = ild.plusSign; // ii. Add new part record { [[type]]: \"plusSign\", [[value]]: plusSignSymbol } as a new element of the list result.\n\n arrPush.call(result, {\n '[[type]]': 'plusSign',\n '[[value]]': plusSignSymbol\n });\n } // a. Else if p is equal \"minusSign\", then:\n else if (p === \"minusSign\") {\n // i. Let minusSignSymbol be the ILND String representing the minus sign.\n var minusSignSymbol = ild.minusSign; // ii. Add new part record { [[type]]: \"minusSign\", [[value]]: minusSignSymbol } as a new element of the list result.\n\n arrPush.call(result, {\n '[[type]]': 'minusSign',\n '[[value]]': minusSignSymbol\n });\n } // a. Else if p is equal \"percentSign\" and numberFormat.[[style]] is \"percent\", then:\n else if (p === \"percentSign\" && internal['[[style]]'] === \"percent\") {\n // i. Let percentSignSymbol be the ILND String representing the percent sign.\n var percentSignSymbol = ild.percentSign; // ii. Add new part record { [[type]]: \"percentSign\", [[value]]: percentSignSymbol } as a new element of the list result.\n\n arrPush.call(result, {\n '[[type]]': 'literal',\n '[[value]]': percentSignSymbol\n });\n } // a. Else if p is equal \"currency\" and numberFormat.[[style]] is \"currency\", then:\n else if (p === \"currency\" && internal['[[style]]'] === \"currency\") {\n // i. Let currency be the value of numberFormat.[[currency]].\n var currency = internal['[[currency]]'];\n var cd = void 0; // ii. If numberFormat.[[currencyDisplay]] is \"code\", then\n\n if (internal['[[currencyDisplay]]'] === \"code\") {\n // 1. Let cd be currency.\n cd = currency;\n } // iii. Else if numberFormat.[[currencyDisplay]] is \"symbol\", then\n else if (internal['[[currencyDisplay]]'] === \"symbol\") {\n // 1. Let cd be an ILD string representing currency in short form. If the implementation does not have such a representation of currency, use currency itself.\n cd = data.currencies[currency] || currency;\n } // iv. Else if numberFormat.[[currencyDisplay]] is \"name\", then\n else if (internal['[[currencyDisplay]]'] === \"name\") {\n // 1. Let cd be an ILD string representing currency in long form. If the implementation does not have such a representation of currency, then use currency itself.\n cd = currency;\n } // v. Add new part record { [[type]]: \"currency\", [[value]]: cd } as a new element of the list result.\n\n\n arrPush.call(result, {\n '[[type]]': 'currency',\n '[[value]]': cd\n });\n } // a. Else,\n else {\n // i. Let literal be the substring of pattern from position beginIndex, inclusive, to position endIndex, inclusive.\n var _literal = pattern.substring(beginIndex, endIndex); // ii. Add new part record { [[type]]: \"literal\", [[value]]: literal } as a new element of the list result.\n\n\n arrPush.call(result, {\n '[[type]]': 'literal',\n '[[value]]': _literal\n });\n } // a. Set nextIndex to endIndex + 1.\n\n\n nextIndex = endIndex + 1; // a. Set beginIndex to Call(%StringProto_indexOf%, pattern, \"{\", nextIndex)\n\n beginIndex = pattern.indexOf('{', nextIndex);\n } // 9. If nextIndex is less than length, then:\n\n\n if (nextIndex < length) {\n // a. Let literal be the substring of pattern from position nextIndex, inclusive, to position length, exclusive.\n var _literal2 = pattern.substring(nextIndex, length); // a. Add new part record { [[type]]: \"literal\", [[value]]: literal } as a new element of the list result.\n\n\n arrPush.call(result, {\n '[[type]]': 'literal',\n '[[value]]': _literal2\n });\n } // 10. Return result.\n\n\n return result;\n}\n/*\n * @spec[stasm/ecma402/number-format-to-parts/spec/numberformat.html]\n * @clause[sec-formatnumber]\n */\n\n\nfunction FormatNumber(numberFormat, x) {\n // 1. Let parts be ? PartitionNumberPattern(numberFormat, x).\n var parts = PartitionNumberPattern(numberFormat, x); // 2. Let result be an empty String.\n\n var result = ''; // 3. For each part in parts, do:\n\n for (var i = 0; parts.length > i; i++) {\n var part = parts[i]; // a. Set result to a String value produced by concatenating result and part.[[value]].\n\n result += part['[[value]]'];\n } // 4. Return result.\n\n\n return result;\n}\n/**\n * When the ToRawPrecision abstract operation is called with arguments x (which\n * must be a finite non-negative number), minPrecision, and maxPrecision (both\n * must be integers between 1 and 21) the following steps are taken:\n */\n\n\nfunction ToRawPrecision(x, minPrecision, maxPrecision) {\n // 1. Let p be maxPrecision.\n var p = maxPrecision;\n var m = void 0,\n e = void 0; // 2. If x = 0, then\n\n if (x === 0) {\n // a. Let m be the String consisting of p occurrences of the character \"0\".\n m = arrJoin.call(Array(p + 1), '0'); // b. Let e be 0.\n\n e = 0;\n } // 3. Else\n else {\n // a. Let e and n be integers such that 10ᵖ⁻¹ ≤ n < 10ᵖ and for which the\n // exact mathematical value of n × 10ᵉ⁻ᵖ⁺¹ – x is as close to zero as\n // possible. If there are two such sets of e and n, pick the e and n for\n // which n × 10ᵉ⁻ᵖ⁺¹ is larger.\n e = log10Floor(Math.abs(x)); // Easier to get to m from here\n\n var f = Math.round(Math.exp(Math.abs(e - p + 1) * Math.LN10)); // b. Let m be the String consisting of the digits of the decimal\n // representation of n (in order, with no leading zeroes)\n\n m = String(Math.round(e - p + 1 < 0 ? x * f : x / f));\n } // 4. If e ≥ p, then\n\n\n if (e >= p) // a. Return the concatenation of m and e-p+1 occurrences of the character \"0\".\n return m + arrJoin.call(Array(e - p + 1 + 1), '0'); // 5. If e = p-1, then\n else if (e === p - 1) // a. Return m.\n return m; // 6. If e ≥ 0, then\n else if (e >= 0) // a. Let m be the concatenation of the first e+1 characters of m, the character\n // \".\", and the remaining p–(e+1) characters of m.\n m = m.slice(0, e + 1) + '.' + m.slice(e + 1); // 7. If e < 0, then\n else if (e < 0) // a. Let m be the concatenation of the String \"0.\", –(e+1) occurrences of the\n // character \"0\", and the string m.\n m = '0.' + arrJoin.call(Array(-(e + 1) + 1), '0') + m; // 8. If m contains the character \".\", and maxPrecision > minPrecision, then\n\n if (m.indexOf(\".\") >= 0 && maxPrecision > minPrecision) {\n // a. Let cut be maxPrecision – minPrecision.\n var cut = maxPrecision - minPrecision; // b. Repeat while cut > 0 and the last character of m is \"0\":\n\n while (cut > 0 && m.charAt(m.length - 1) === '0') {\n // i. Remove the last character from m.\n m = m.slice(0, -1); // ii. Decrease cut by 1.\n\n cut--;\n } // c. If the last character of m is \".\", then\n\n\n if (m.charAt(m.length - 1) === '.') // i. Remove the last character from m.\n m = m.slice(0, -1);\n } // 9. Return m.\n\n\n return m;\n}\n/**\n * @spec[tc39/ecma402/master/spec/numberformat.html]\n * @clause[sec-torawfixed]\n * When the ToRawFixed abstract operation is called with arguments x (which must\n * be a finite non-negative number), minInteger (which must be an integer between\n * 1 and 21), minFraction, and maxFraction (which must be integers between 0 and\n * 20) the following steps are taken:\n */\n\n\nfunction ToRawFixed(x, minInteger, minFraction, maxFraction) {\n // 1. Let f be maxFraction.\n var f = maxFraction; // 2. Let n be an integer for which the exact mathematical value of n ÷ 10f – x is as close to zero as possible. If there are two such n, pick the larger n.\n\n var n = Math.pow(10, f) * x; // diverging...\n // 3. If n = 0, let m be the String \"0\". Otherwise, let m be the String consisting of the digits of the decimal representation of n (in order, with no leading zeroes).\n\n var m = n === 0 ? \"0\" : n.toFixed(0); // divering...\n\n {\n // this diversion is needed to take into consideration big numbers, e.g.:\n // 1.2344501e+37 -> 12344501000000000000000000000000000000\n var idx = void 0;\n var exp = (idx = m.indexOf('e')) > -1 ? m.slice(idx + 1) : 0;\n\n if (exp) {\n m = m.slice(0, idx).replace('.', '');\n m += arrJoin.call(Array(exp - (m.length - 1) + 1), '0');\n }\n }\n var int = void 0; // 4. If f ≠ 0, then\n\n if (f !== 0) {\n // a. Let k be the number of characters in m.\n var k = m.length; // a. If k ≤ f, then\n\n if (k <= f) {\n // i. Let z be the String consisting of f+1–k occurrences of the character \"0\".\n var z = arrJoin.call(Array(f + 1 - k + 1), '0'); // ii. Let m be the concatenation of Strings z and m.\n\n m = z + m; // iii. Let k be f+1.\n\n k = f + 1;\n } // a. Let a be the first k–f characters of m, and let b be the remaining f characters of m.\n\n\n var a = m.substring(0, k - f),\n b = m.substring(k - f, m.length); // a. Let m be the concatenation of the three Strings a, \".\", and b.\n\n m = a + \".\" + b; // a. Let int be the number of characters in a.\n\n int = a.length;\n } // 5. Else, let int be the number of characters in m.\n else int = m.length; // 6. Let cut be maxFraction – minFraction.\n\n\n var cut = maxFraction - minFraction; // 7. Repeat while cut > 0 and the last character of m is \"0\":\n\n while (cut > 0 && m.slice(-1) === \"0\") {\n // a. Remove the last character from m.\n m = m.slice(0, -1); // a. Decrease cut by 1.\n\n cut--;\n } // 8. If the last character of m is \".\", then\n\n\n if (m.slice(-1) === \".\") {\n // a. Remove the last character from m.\n m = m.slice(0, -1);\n } // 9. If int < minInteger, then\n\n\n if (int < minInteger) {\n // a. Let z be the String consisting of minInteger–int occurrences of the character \"0\".\n var _z = arrJoin.call(Array(minInteger - int + 1), '0'); // a. Let m be the concatenation of Strings z and m.\n\n\n m = _z + m;\n } // 10. Return m.\n\n\n return m;\n} // Sect 11.3.2 Table 2, Numbering systems\n// ======================================\n\n\nvar numSys = {\n arab: [\"٠\", \"١\", \"٢\", \"٣\", \"٤\", \"٥\", \"٦\", \"٧\", \"٨\", \"٩\"],\n arabext: [\"۰\", \"۱\", \"۲\", \"۳\", \"۴\", \"۵\", \"۶\", \"۷\", \"۸\", \"۹\"],\n bali: [\"᭐\", \"᭑\", \"᭒\", \"᭓\", \"᭔\", \"᭕\", \"᭖\", \"᭗\", \"᭘\", \"᭙\"],\n beng: [\"০\", \"১\", \"২\", \"৩\", \"৪\", \"৫\", \"৬\", \"৭\", \"৮\", \"৯\"],\n deva: [\"०\", \"१\", \"२\", \"३\", \"४\", \"५\", \"६\", \"७\", \"८\", \"९\"],\n fullwide: [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\"],\n gujr: [\"૦\", \"૧\", \"૨\", \"૩\", \"૪\", \"૫\", \"૬\", \"૭\", \"૮\", \"૯\"],\n guru: [\"੦\", \"੧\", \"੨\", \"੩\", \"੪\", \"੫\", \"੬\", \"੭\", \"੮\", \"੯\"],\n hanidec: [\"〇\", \"一\", \"二\", \"三\", \"四\", \"五\", \"六\", \"七\", \"八\", \"九\"],\n khmr: [\"០\", \"១\", \"២\", \"៣\", \"៤\", \"៥\", \"៦\", \"៧\", \"៨\", \"៩\"],\n knda: [\"೦\", \"೧\", \"೨\", \"೩\", \"೪\", \"೫\", \"೬\", \"೭\", \"೮\", \"೯\"],\n laoo: [\"໐\", \"໑\", \"໒\", \"໓\", \"໔\", \"໕\", \"໖\", \"໗\", \"໘\", \"໙\"],\n latn: [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\"],\n limb: [\"᥆\", \"᥇\", \"᥈\", \"᥉\", \"᥊\", \"᥋\", \"᥌\", \"᥍\", \"᥎\", \"᥏\"],\n mlym: [\"൦\", \"൧\", \"൨\", \"൩\", \"൪\", \"൫\", \"൬\", \"൭\", \"൮\", \"൯\"],\n mong: [\"᠐\", \"᠑\", \"᠒\", \"᠓\", \"᠔\", \"᠕\", \"᠖\", \"᠗\", \"᠘\", \"᠙\"],\n mymr: [\"၀\", \"၁\", \"၂\", \"၃\", \"၄\", \"၅\", \"၆\", \"၇\", \"၈\", \"၉\"],\n orya: [\"୦\", \"୧\", \"୨\", \"୩\", \"୪\", \"୫\", \"୬\", \"୭\", \"୮\", \"୯\"],\n tamldec: [\"௦\", \"௧\", \"௨\", \"௩\", \"௪\", \"௫\", \"௬\", \"௭\", \"௮\", \"௯\"],\n telu: [\"౦\", \"౧\", \"౨\", \"౩\", \"౪\", \"౫\", \"౬\", \"౭\", \"౮\", \"౯\"],\n thai: [\"๐\", \"๑\", \"๒\", \"๓\", \"๔\", \"๕\", \"๖\", \"๗\", \"๘\", \"๙\"],\n tibt: [\"༠\", \"༡\", \"༢\", \"༣\", \"༤\", \"༥\", \"༦\", \"༧\", \"༨\", \"༩\"]\n};\n/**\n * This function provides access to the locale and formatting options computed\n * during initialization of the object.\n *\n * The function returns a new object whose properties and attributes are set as\n * if constructed by an object literal assigning to each of the following\n * properties the value of the corresponding internal property of this\n * NumberFormat object (see 11.4): locale, numberingSystem, style, currency,\n * currencyDisplay, minimumIntegerDigits, minimumFractionDigits,\n * maximumFractionDigits, minimumSignificantDigits, maximumSignificantDigits, and\n * useGrouping. Properties whose corresponding internal properties are not present\n * are not assigned.\n */\n\n/* 11.3.3 */\n\ndefineProperty(Intl.NumberFormat.prototype, 'resolvedOptions', {\n configurable: true,\n writable: true,\n value: function value() {\n var prop = void 0,\n descs = new Record(),\n props = ['locale', 'numberingSystem', 'style', 'currency', 'currencyDisplay', 'minimumIntegerDigits', 'minimumFractionDigits', 'maximumFractionDigits', 'minimumSignificantDigits', 'maximumSignificantDigits', 'useGrouping'],\n internal = this !== null && babelHelpers$1[\"typeof\"](this) === 'object' && getInternalProperties(this); // Satisfy test 11.3_b\n\n if (!internal || !internal['[[initializedNumberFormat]]']) throw new TypeError('`this` value for resolvedOptions() is not an initialized Intl.NumberFormat object.');\n\n for (var i = 0, max = props.length; i < max; i++) {\n if (hop.call(internal, prop = '[[' + props[i] + ']]')) descs[props[i]] = {\n value: internal[prop],\n writable: true,\n configurable: true,\n enumerable: true\n };\n }\n\n return objCreate({}, descs);\n }\n});\n/* jslint esnext: true */\n// Match these datetime components in a CLDR pattern, except those in single quotes\n\nvar expDTComponents = /(?:[Eec]{1,6}|G{1,5}|[Qq]{1,5}|(?:[yYur]+|U{1,5})|[ML]{1,5}|d{1,2}|D{1,3}|F{1}|[abB]{1,5}|[hkHK]{1,2}|w{1,2}|W{1}|m{1,2}|s{1,2}|[zZOvVxX]{1,4})(?=([^']*'[^']*')*[^']*$)/g; // trim patterns after transformations\n\nvar expPatternTrimmer = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g; // Skip over patterns with these datetime components because we don't have data\n// to back them up:\n// timezone, weekday, amoung others\n\nvar unwantedDTCs = /[rqQASjJgwWIQq]/; // xXVO were removed from this list in favor of computing matches with timeZoneName values but printing as empty string\n\nvar dtKeys = [\"era\", \"year\", \"month\", \"day\", \"weekday\", \"quarter\"];\nvar tmKeys = [\"hour\", \"minute\", \"second\", \"hour12\", \"timeZoneName\"];\n\nfunction isDateFormatOnly(obj) {\n for (var i = 0; i < tmKeys.length; i += 1) {\n if (obj.hasOwnProperty(tmKeys[i])) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction isTimeFormatOnly(obj) {\n for (var i = 0; i < dtKeys.length; i += 1) {\n if (obj.hasOwnProperty(dtKeys[i])) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction joinDateAndTimeFormats(dateFormatObj, timeFormatObj) {\n var o = {\n _: {}\n };\n\n for (var i = 0; i < dtKeys.length; i += 1) {\n if (dateFormatObj[dtKeys[i]]) {\n o[dtKeys[i]] = dateFormatObj[dtKeys[i]];\n }\n\n if (dateFormatObj._[dtKeys[i]]) {\n o._[dtKeys[i]] = dateFormatObj._[dtKeys[i]];\n }\n }\n\n for (var j = 0; j < tmKeys.length; j += 1) {\n if (timeFormatObj[tmKeys[j]]) {\n o[tmKeys[j]] = timeFormatObj[tmKeys[j]];\n }\n\n if (timeFormatObj._[tmKeys[j]]) {\n o._[tmKeys[j]] = timeFormatObj._[tmKeys[j]];\n }\n }\n\n return o;\n}\n\nfunction computeFinalPatterns(formatObj) {\n // From http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns:\n // 'In patterns, two single quotes represents a literal single quote, either\n // inside or outside single quotes. Text within single quotes is not\n // interpreted in any way (except for two adjacent single quotes).'\n formatObj.pattern12 = formatObj.extendedPattern.replace(/'([^']*)'/g, function ($0, literal) {\n return literal ? literal : \"'\";\n }); // pattern 12 is always the default. we can produce the 24 by removing {ampm}\n\n formatObj.pattern = formatObj.pattern12.replace('{ampm}', '').replace(expPatternTrimmer, '');\n return formatObj;\n}\n\nfunction expDTComponentsMeta($0, formatObj) {\n switch ($0.charAt(0)) {\n // --- Era\n case 'G':\n formatObj.era = ['short', 'short', 'short', 'long', 'narrow'][$0.length - 1];\n return '{era}';\n // --- Year\n\n case 'y':\n case 'Y':\n case 'u':\n case 'U':\n case 'r':\n formatObj.year = $0.length === 2 ? '2-digit' : 'numeric';\n return '{year}';\n // --- Quarter (not supported in this polyfill)\n\n case 'Q':\n case 'q':\n formatObj.quarter = ['numeric', '2-digit', 'short', 'long', 'narrow'][$0.length - 1];\n return '{quarter}';\n // --- Month\n\n case 'M':\n case 'L':\n formatObj.month = ['numeric', '2-digit', 'short', 'long', 'narrow'][$0.length - 1];\n return '{month}';\n // --- Week (not supported in this polyfill)\n\n case 'w':\n // week of the year\n formatObj.week = $0.length === 2 ? '2-digit' : 'numeric';\n return '{weekday}';\n\n case 'W':\n // week of the month\n formatObj.week = 'numeric';\n return '{weekday}';\n // --- Day\n\n case 'd':\n // day of the month\n formatObj.day = $0.length === 2 ? '2-digit' : 'numeric';\n return '{day}';\n\n case 'D': // day of the year\n\n case 'F': // day of the week\n\n case 'g':\n // 1..n: Modified Julian day\n formatObj.day = 'numeric';\n return '{day}';\n // --- Week Day\n\n case 'E':\n // day of the week\n formatObj.weekday = ['short', 'short', 'short', 'long', 'narrow', 'short'][$0.length - 1];\n return '{weekday}';\n\n case 'e':\n // local day of the week\n formatObj.weekday = ['numeric', '2-digit', 'short', 'long', 'narrow', 'short'][$0.length - 1];\n return '{weekday}';\n\n case 'c':\n // stand alone local day of the week\n formatObj.weekday = ['numeric', undefined, 'short', 'long', 'narrow', 'short'][$0.length - 1];\n return '{weekday}';\n // --- Period\n\n case 'a': // AM, PM\n\n case 'b': // am, pm, noon, midnight\n\n case 'B':\n // flexible day periods\n formatObj.hour12 = true;\n return '{ampm}';\n // --- Hour\n\n case 'h':\n case 'H':\n formatObj.hour = $0.length === 2 ? '2-digit' : 'numeric';\n return '{hour}';\n\n case 'k':\n case 'K':\n formatObj.hour12 = true; // 12-hour-cycle time formats (using h or K)\n\n formatObj.hour = $0.length === 2 ? '2-digit' : 'numeric';\n return '{hour}';\n // --- Minute\n\n case 'm':\n formatObj.minute = $0.length === 2 ? '2-digit' : 'numeric';\n return '{minute}';\n // --- Second\n\n case 's':\n formatObj.second = $0.length === 2 ? '2-digit' : 'numeric';\n return '{second}';\n\n case 'S':\n case 'A':\n formatObj.second = 'numeric';\n return '{second}';\n // --- Timezone\n\n case 'z': // 1..3, 4: specific non-location format\n\n case 'Z': // 1..3, 4, 5: The ISO8601 varios formats\n\n case 'O': // 1, 4: miliseconds in day short, long\n\n case 'v': // 1, 4: generic non-location format\n\n case 'V': // 1, 2, 3, 4: time zone ID or city\n\n case 'X': // 1, 2, 3, 4: The ISO8601 varios formats\n\n case 'x':\n // 1, 2, 3, 4: The ISO8601 varios formats\n // this polyfill only supports much, for now, we are just doing something dummy\n formatObj.timeZoneName = $0.length < 4 ? 'short' : 'long';\n return '{timeZoneName}';\n }\n}\n/**\n * Converts the CLDR availableFormats into the objects and patterns required by\n * the ECMAScript Internationalization API specification.\n */\n\n\nfunction createDateTimeFormat(skeleton, pattern) {\n // we ignore certain patterns that are unsupported to avoid this expensive op.\n if (unwantedDTCs.test(pattern)) return undefined;\n var formatObj = {\n originalPattern: pattern,\n _: {}\n }; // Replace the pattern string with the one required by the specification, whilst\n // at the same time evaluating it for the subsets and formats\n\n formatObj.extendedPattern = pattern.replace(expDTComponents, function ($0) {\n // See which symbol we're dealing with\n return expDTComponentsMeta($0, formatObj._);\n }); // Match the skeleton string with the one required by the specification\n // this implementation is based on the Date Field Symbol Table:\n // http://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table\n // Note: we are adding extra data to the formatObject even though this polyfill\n // might not support it.\n\n skeleton.replace(expDTComponents, function ($0) {\n // See which symbol we're dealing with\n return expDTComponentsMeta($0, formatObj);\n });\n return computeFinalPatterns(formatObj);\n}\n/**\n * Processes DateTime formats from CLDR to an easier-to-parse format.\n * the result of this operation should be cached the first time a particular\n * calendar is analyzed.\n *\n * The specification requires we support at least the following subsets of\n * date/time components:\n *\n * - 'weekday', 'year', 'month', 'day', 'hour', 'minute', 'second'\n * - 'weekday', 'year', 'month', 'day'\n * - 'year', 'month', 'day'\n * - 'year', 'month'\n * - 'month', 'day'\n * - 'hour', 'minute', 'second'\n * - 'hour', 'minute'\n *\n * We need to cherry pick at least these subsets from the CLDR data and convert\n * them into the pattern objects used in the ECMA-402 API.\n */\n\n\nfunction createDateTimeFormats(formats) {\n var availableFormats = formats.availableFormats;\n var timeFormats = formats.timeFormats;\n var dateFormats = formats.dateFormats;\n var result = [];\n var skeleton = void 0,\n pattern = void 0,\n computed = void 0,\n i = void 0,\n j = void 0;\n var timeRelatedFormats = [];\n var dateRelatedFormats = []; // Map available (custom) formats into a pattern for createDateTimeFormats\n\n for (skeleton in availableFormats) {\n if (availableFormats.hasOwnProperty(skeleton)) {\n pattern = availableFormats[skeleton];\n computed = createDateTimeFormat(skeleton, pattern);\n\n if (computed) {\n result.push(computed); // in some cases, the format is only displaying date specific props\n // or time specific props, in which case we need to also produce the\n // combined formats.\n\n if (isDateFormatOnly(computed)) {\n dateRelatedFormats.push(computed);\n } else if (isTimeFormatOnly(computed)) {\n timeRelatedFormats.push(computed);\n }\n }\n }\n } // Map time formats into a pattern for createDateTimeFormats\n\n\n for (skeleton in timeFormats) {\n if (timeFormats.hasOwnProperty(skeleton)) {\n pattern = timeFormats[skeleton];\n computed = createDateTimeFormat(skeleton, pattern);\n\n if (computed) {\n result.push(computed);\n timeRelatedFormats.push(computed);\n }\n }\n } // Map date formats into a pattern for createDateTimeFormats\n\n\n for (skeleton in dateFormats) {\n if (dateFormats.hasOwnProperty(skeleton)) {\n pattern = dateFormats[skeleton];\n computed = createDateTimeFormat(skeleton, pattern);\n\n if (computed) {\n result.push(computed);\n dateRelatedFormats.push(computed);\n }\n }\n } // combine custom time and custom date formats when they are orthogonals to complete the\n // formats supported by CLDR.\n // This Algo is based on section \"Missing Skeleton Fields\" from:\n // http://unicode.org/reports/tr35/tr35-dates.html#availableFormats_appendItems\n\n\n for (i = 0; i < timeRelatedFormats.length; i += 1) {\n for (j = 0; j < dateRelatedFormats.length; j += 1) {\n if (dateRelatedFormats[j].month === 'long') {\n pattern = dateRelatedFormats[j].weekday ? formats.full : formats.long;\n } else if (dateRelatedFormats[j].month === 'short') {\n pattern = formats.medium;\n } else {\n pattern = formats.short;\n }\n\n computed = joinDateAndTimeFormats(dateRelatedFormats[j], timeRelatedFormats[i]);\n computed.originalPattern = pattern;\n computed.extendedPattern = pattern.replace('{0}', timeRelatedFormats[i].extendedPattern).replace('{1}', dateRelatedFormats[j].extendedPattern).replace(/^[,\\s]+|[,\\s]+$/gi, '');\n result.push(computeFinalPatterns(computed));\n }\n }\n\n return result;\n} // this represents the exceptions of the rule that are not covered by CLDR availableFormats\n// for single property configurations, they play no role when using multiple properties, and\n// those that are not in this table, are not exceptions or are not covered by the data we\n// provide.\n\n\nvar validSyntheticProps = {\n second: {\n numeric: 's',\n '2-digit': 'ss'\n },\n minute: {\n numeric: 'm',\n '2-digit': 'mm'\n },\n year: {\n numeric: 'y',\n '2-digit': 'yy'\n },\n day: {\n numeric: 'd',\n '2-digit': 'dd'\n },\n month: {\n numeric: 'L',\n '2-digit': 'LL',\n narrow: 'LLLLL',\n short: 'LLL',\n long: 'LLLL'\n },\n weekday: {\n narrow: 'ccccc',\n short: 'ccc',\n long: 'cccc'\n }\n};\n\nfunction generateSyntheticFormat(propName, propValue) {\n if (validSyntheticProps[propName] && validSyntheticProps[propName][propValue]) {\n var _ref2;\n\n return _ref2 = {\n originalPattern: validSyntheticProps[propName][propValue],\n _: defineProperty$1({}, propName, propValue),\n extendedPattern: \"{\" + propName + \"}\"\n }, defineProperty$1(_ref2, propName, propValue), defineProperty$1(_ref2, \"pattern12\", \"{\" + propName + \"}\"), defineProperty$1(_ref2, \"pattern\", \"{\" + propName + \"}\"), _ref2;\n }\n} // An object map of date component keys, saves using a regex later\n\n\nvar dateWidths = objCreate(null, {\n narrow: {},\n short: {},\n long: {}\n});\n/**\n * Returns a string for a date component, resolved using multiple inheritance as specified\n * as specified in the Unicode Technical Standard 35.\n */\n\nfunction resolveDateString(data, ca, component, width, key) {\n // From http://www.unicode.org/reports/tr35/tr35.html#Multiple_Inheritance:\n // 'In clearly specified instances, resources may inherit from within the same locale.\n // For example, ... the Buddhist calendar inherits from the Gregorian calendar.'\n var obj = data[ca] && data[ca][component] ? data[ca][component] : data.gregory[component],\n // \"sideways\" inheritance resolves strings when a key doesn't exist\n alts = {\n narrow: ['short', 'long'],\n short: ['long', 'narrow'],\n long: ['short', 'narrow']\n },\n //\n resolved = hop.call(obj, width) ? obj[width] : hop.call(obj, alts[width][0]) ? obj[alts[width][0]] : obj[alts[width][1]]; // `key` wouldn't be specified for components 'dayPeriods'\n\n return key !== null ? resolved[key] : resolved;\n} // Define the DateTimeFormat constructor internally so it cannot be tainted\n\n\nfunction DateTimeFormatConstructor() {\n var locales = arguments[0];\n var options = arguments[1];\n\n if (!this || this === Intl) {\n return new Intl.DateTimeFormat(locales, options);\n }\n\n return InitializeDateTimeFormat(toObject(this), locales, options);\n}\n\ndefineProperty(Intl, 'DateTimeFormat', {\n configurable: true,\n writable: true,\n value: DateTimeFormatConstructor\n}); // Must explicitly set prototypes as unwritable\n\ndefineProperty(DateTimeFormatConstructor, 'prototype', {\n writable: false\n});\n/**\n * The abstract operation InitializeDateTimeFormat accepts the arguments dateTimeFormat\n * (which must be an object), locales, and options. It initializes dateTimeFormat as a\n * DateTimeFormat object.\n */\n\nfunction\n/* 12.1.1.1 */\nInitializeDateTimeFormat(dateTimeFormat, locales, options) {\n // This will be a internal properties object if we're not already initialized\n var internal = getInternalProperties(dateTimeFormat); // Create an object whose props can be used to restore the values of RegExp props\n\n var regexpRestore = createRegExpRestore(); // 1. If dateTimeFormat has an [[initializedIntlObject]] internal property with\n // value true, throw a TypeError exception.\n\n if (internal['[[initializedIntlObject]]'] === true) throw new TypeError('`this` object has already been initialized as an Intl object'); // Need this to access the `internal` object\n\n defineProperty(dateTimeFormat, '__getInternalProperties', {\n value: function value() {\n // NOTE: Non-standard, for internal use only\n if (arguments[0] === secret) return internal;\n }\n }); // 2. Set the [[initializedIntlObject]] internal property of numberFormat to true.\n\n internal['[[initializedIntlObject]]'] = true; // 3. Let requestedLocales be the result of calling the CanonicalizeLocaleList\n // abstract operation (defined in 9.2.1) with argument locales.\n\n var requestedLocales = CanonicalizeLocaleList(locales); // 4. Let options be the result of calling the ToDateTimeOptions abstract\n // operation (defined below) with arguments options, \"any\", and \"date\".\n\n options = ToDateTimeOptions(options, 'any', 'date'); // 5. Let opt be a new Record.\n\n var opt = new Record(); // 6. Let matcher be the result of calling the GetOption abstract operation\n // (defined in 9.2.9) with arguments options, \"localeMatcher\", \"string\", a List\n // containing the two String values \"lookup\" and \"best fit\", and \"best fit\".\n\n var matcher = GetOption(options, 'localeMatcher', 'string', new List('lookup', 'best fit'), 'best fit'); // 7. Set opt.[[localeMatcher]] to matcher.\n\n opt['[[localeMatcher]]'] = matcher; // 8. Let DateTimeFormat be the standard built-in object that is the initial\n // value of Intl.DateTimeFormat.\n\n var DateTimeFormat = internals.DateTimeFormat; // This is what we *really* need\n // 9. Let localeData be the value of the [[localeData]] internal property of\n // DateTimeFormat.\n\n var localeData = DateTimeFormat['[[localeData]]']; // 10. Let r be the result of calling the ResolveLocale abstract operation\n // (defined in 9.2.5) with the [[availableLocales]] internal property of\n // DateTimeFormat, requestedLocales, opt, the [[relevantExtensionKeys]]\n // internal property of DateTimeFormat, and localeData.\n\n var r = ResolveLocale(DateTimeFormat['[[availableLocales]]'], requestedLocales, opt, DateTimeFormat['[[relevantExtensionKeys]]'], localeData); // 11. Set the [[locale]] internal property of dateTimeFormat to the value of\n // r.[[locale]].\n\n internal['[[locale]]'] = r['[[locale]]']; // 12. Set the [[calendar]] internal property of dateTimeFormat to the value of\n // r.[[ca]].\n\n internal['[[calendar]]'] = r['[[ca]]']; // 13. Set the [[numberingSystem]] internal property of dateTimeFormat to the value of\n // r.[[nu]].\n\n internal['[[numberingSystem]]'] = r['[[nu]]']; // The specification doesn't tell us to do this, but it's helpful later on\n\n internal['[[dataLocale]]'] = r['[[dataLocale]]']; // 14. Let dataLocale be the value of r.[[dataLocale]].\n\n var dataLocale = r['[[dataLocale]]']; // 15. Let tz be the result of calling the [[Get]] internal method of options with\n // argument \"timeZone\".\n\n var tz = options.timeZone; // 16. If tz is not undefined, then\n\n if (tz !== undefined) {\n // a. Let tz be ToString(tz).\n // b. Convert tz to upper case as described in 6.1.\n // NOTE: If an implementation accepts additional time zone values, as permitted\n // under certain conditions by the Conformance clause, different casing\n // rules apply.\n tz = toLatinUpperCase(tz); // c. If tz is not \"UTC\", then throw a RangeError exception.\n // ###TODO: accept more time zones###\n\n if (tz !== 'UTC') throw new RangeError('timeZone is not supported.');\n } // 17. Set the [[timeZone]] internal property of dateTimeFormat to tz.\n\n\n internal['[[timeZone]]'] = tz; // 18. Let opt be a new Record.\n\n opt = new Record(); // 19. For each row of Table 3, except the header row, do:\n\n for (var prop in dateTimeComponents) {\n if (!hop.call(dateTimeComponents, prop)) continue; // 20. Let prop be the name given in the Property column of the row.\n // 21. Let value be the result of calling the GetOption abstract operation,\n // passing as argument options, the name given in the Property column of the\n // row, \"string\", a List containing the strings given in the Values column of\n // the row, and undefined.\n\n var value = GetOption(options, prop, 'string', dateTimeComponents[prop]); // 22. Set opt.[[]] to value.\n\n opt['[[' + prop + ']]'] = value;\n } // Assigned a value below\n\n\n var bestFormat = void 0; // 23. Let dataLocaleData be the result of calling the [[Get]] internal method of\n // localeData with argument dataLocale.\n\n var dataLocaleData = localeData[dataLocale]; // 24. Let formats be the result of calling the [[Get]] internal method of\n // dataLocaleData with argument \"formats\".\n // Note: we process the CLDR formats into the spec'd structure\n\n var formats = ToDateTimeFormats(dataLocaleData.formats); // 25. Let matcher be the result of calling the GetOption abstract operation with\n // arguments options, \"formatMatcher\", \"string\", a List containing the two String\n // values \"basic\" and \"best fit\", and \"best fit\".\n\n matcher = GetOption(options, 'formatMatcher', 'string', new List('basic', 'best fit'), 'best fit'); // Optimization: caching the processed formats as a one time operation by\n // replacing the initial structure from localeData\n\n dataLocaleData.formats = formats; // 26. If matcher is \"basic\", then\n\n if (matcher === 'basic') {\n // 27. Let bestFormat be the result of calling the BasicFormatMatcher abstract\n // operation (defined below) with opt and formats.\n bestFormat = BasicFormatMatcher(opt, formats); // 28. Else\n } else {\n {\n // diverging\n var _hr = GetOption(options, 'hour12', 'boolean'\n /*, undefined, undefined*/\n );\n\n opt.hour12 = _hr === undefined ? dataLocaleData.hour12 : _hr;\n } // 29. Let bestFormat be the result of calling the BestFitFormatMatcher\n // abstract operation (defined below) with opt and formats.\n\n bestFormat = BestFitFormatMatcher(opt, formats);\n } // 30. For each row in Table 3, except the header row, do\n\n\n for (var _prop in dateTimeComponents) {\n if (!hop.call(dateTimeComponents, _prop)) continue; // a. Let prop be the name given in the Property column of the row.\n // b. Let pDesc be the result of calling the [[GetOwnProperty]] internal method of\n // bestFormat with argument prop.\n // c. If pDesc is not undefined, then\n\n if (hop.call(bestFormat, _prop)) {\n // i. Let p be the result of calling the [[Get]] internal method of bestFormat\n // with argument prop.\n var p = bestFormat[_prop];\n {\n // diverging\n p = bestFormat._ && hop.call(bestFormat._, _prop) ? bestFormat._[_prop] : p;\n } // ii. Set the [[]] internal property of dateTimeFormat to p.\n\n internal['[[' + _prop + ']]'] = p;\n }\n }\n\n var pattern = void 0; // Assigned a value below\n // 31. Let hr12 be the result of calling the GetOption abstract operation with\n // arguments options, \"hour12\", \"boolean\", undefined, and undefined.\n\n var hr12 = GetOption(options, 'hour12', 'boolean'\n /*, undefined, undefined*/\n ); // 32. If dateTimeFormat has an internal property [[hour]], then\n\n if (internal['[[hour]]']) {\n // a. If hr12 is undefined, then let hr12 be the result of calling the [[Get]]\n // internal method of dataLocaleData with argument \"hour12\".\n hr12 = hr12 === undefined ? dataLocaleData.hour12 : hr12; // b. Set the [[hour12]] internal property of dateTimeFormat to hr12.\n\n internal['[[hour12]]'] = hr12; // c. If hr12 is true, then\n\n if (hr12 === true) {\n // i. Let hourNo0 be the result of calling the [[Get]] internal method of\n // dataLocaleData with argument \"hourNo0\".\n var hourNo0 = dataLocaleData.hourNo0; // ii. Set the [[hourNo0]] internal property of dateTimeFormat to hourNo0.\n\n internal['[[hourNo0]]'] = hourNo0; // iii. Let pattern be the result of calling the [[Get]] internal method of\n // bestFormat with argument \"pattern12\".\n\n pattern = bestFormat.pattern12;\n } // d. Else\n else // i. Let pattern be the result of calling the [[Get]] internal method of\n // bestFormat with argument \"pattern\".\n pattern = bestFormat.pattern;\n } // 33. Else\n else // a. Let pattern be the result of calling the [[Get]] internal method of\n // bestFormat with argument \"pattern\".\n pattern = bestFormat.pattern; // 34. Set the [[pattern]] internal property of dateTimeFormat to pattern.\n\n\n internal['[[pattern]]'] = pattern; // 35. Set the [[boundFormat]] internal property of dateTimeFormat to undefined.\n\n internal['[[boundFormat]]'] = undefined; // 36. Set the [[initializedDateTimeFormat]] internal property of dateTimeFormat to\n // true.\n\n internal['[[initializedDateTimeFormat]]'] = true; // In ES3, we need to pre-bind the format() function\n\n if (es3) dateTimeFormat.format = GetFormatDateTime.call(dateTimeFormat); // Restore the RegExp properties\n\n regexpRestore(); // Return the newly initialised object\n\n return dateTimeFormat;\n}\n/**\n * Several DateTimeFormat algorithms use values from the following table, which provides\n * property names and allowable values for the components of date and time formats:\n */\n\n\nvar dateTimeComponents = {\n weekday: [\"narrow\", \"short\", \"long\"],\n era: [\"narrow\", \"short\", \"long\"],\n year: [\"2-digit\", \"numeric\"],\n month: [\"2-digit\", \"numeric\", \"narrow\", \"short\", \"long\"],\n day: [\"2-digit\", \"numeric\"],\n hour: [\"2-digit\", \"numeric\"],\n minute: [\"2-digit\", \"numeric\"],\n second: [\"2-digit\", \"numeric\"],\n timeZoneName: [\"short\", \"long\"]\n};\n/**\n * When the ToDateTimeOptions abstract operation is called with arguments options,\n * required, and defaults, the following steps are taken:\n */\n\nfunction ToDateTimeFormats(formats) {\n if (Object.prototype.toString.call(formats) === '[object Array]') {\n return formats;\n }\n\n return createDateTimeFormats(formats);\n}\n/**\n * When the ToDateTimeOptions abstract operation is called with arguments options,\n * required, and defaults, the following steps are taken:\n */\n\n\nfunction ToDateTimeOptions(options, required, defaults) {\n // 1. If options is undefined, then let options be null, else let options be\n // ToObject(options).\n if (options === undefined) options = null;else {\n // (#12) options needs to be a Record, but it also needs to inherit properties\n var opt2 = toObject(options);\n options = new Record();\n\n for (var k in opt2) {\n options[k] = opt2[k];\n }\n } // 2. Let create be the standard built-in function object defined in ES5, 15.2.3.5.\n\n var create = objCreate; // 3. Let options be the result of calling the [[Call]] internal method of create with\n // undefined as the this value and an argument list containing the single item\n // options.\n\n options = create(options); // 4. Let needDefaults be true.\n\n var needDefaults = true; // 5. If required is \"date\" or \"any\", then\n\n if (required === 'date' || required === 'any') {\n // a. For each of the property names \"weekday\", \"year\", \"month\", \"day\":\n // i. If the result of calling the [[Get]] internal method of options with the\n // property name is not undefined, then let needDefaults be false.\n if (options.weekday !== undefined || options.year !== undefined || options.month !== undefined || options.day !== undefined) needDefaults = false;\n } // 6. If required is \"time\" or \"any\", then\n\n\n if (required === 'time' || required === 'any') {\n // a. For each of the property names \"hour\", \"minute\", \"second\":\n // i. If the result of calling the [[Get]] internal method of options with the\n // property name is not undefined, then let needDefaults be false.\n if (options.hour !== undefined || options.minute !== undefined || options.second !== undefined) needDefaults = false;\n } // 7. If needDefaults is true and defaults is either \"date\" or \"all\", then\n\n\n if (needDefaults && (defaults === 'date' || defaults === 'all')) // a. For each of the property names \"year\", \"month\", \"day\":\n // i. Call the [[DefineOwnProperty]] internal method of options with the\n // property name, Property Descriptor {[[Value]]: \"numeric\", [[Writable]]:\n // true, [[Enumerable]]: true, [[Configurable]]: true}, and false.\n options.year = options.month = options.day = 'numeric'; // 8. If needDefaults is true and defaults is either \"time\" or \"all\", then\n\n if (needDefaults && (defaults === 'time' || defaults === 'all')) // a. For each of the property names \"hour\", \"minute\", \"second\":\n // i. Call the [[DefineOwnProperty]] internal method of options with the\n // property name, Property Descriptor {[[Value]]: \"numeric\", [[Writable]]:\n // true, [[Enumerable]]: true, [[Configurable]]: true}, and false.\n options.hour = options.minute = options.second = 'numeric'; // 9. Return options.\n\n return options;\n}\n/**\n * When the BasicFormatMatcher abstract operation is called with two arguments options and\n * formats, the following steps are taken:\n */\n\n\nfunction BasicFormatMatcher(options, formats) {\n // 1. Let removalPenalty be 120.\n var removalPenalty = 120; // 2. Let additionPenalty be 20.\n\n var additionPenalty = 20; // 3. Let longLessPenalty be 8.\n\n var longLessPenalty = 8; // 4. Let longMorePenalty be 6.\n\n var longMorePenalty = 6; // 5. Let shortLessPenalty be 6.\n\n var shortLessPenalty = 6; // 6. Let shortMorePenalty be 3.\n\n var shortMorePenalty = 3; // 7. Let bestScore be -Infinity.\n\n var bestScore = -Infinity; // 8. Let bestFormat be undefined.\n\n var bestFormat = void 0; // 9. Let i be 0.\n\n var i = 0; // 10. Assert: formats is an Array object.\n // 11. Let len be the result of calling the [[Get]] internal method of formats with argument \"length\".\n\n var len = formats.length; // 12. Repeat while i < len:\n\n while (i < len) {\n // a. Let format be the result of calling the [[Get]] internal method of formats with argument ToString(i).\n var format = formats[i]; // b. Let score be 0.\n\n var score = 0; // c. For each property shown in Table 3:\n\n for (var property in dateTimeComponents) {\n if (!hop.call(dateTimeComponents, property)) continue; // i. Let optionsProp be options.[[]].\n\n var optionsProp = options['[[' + property + ']]']; // ii. Let formatPropDesc be the result of calling the [[GetOwnProperty]] internal method of format\n // with argument property.\n // iii. If formatPropDesc is not undefined, then\n // 1. Let formatProp be the result of calling the [[Get]] internal method of format with argument property.\n\n var formatProp = hop.call(format, property) ? format[property] : undefined; // iv. If optionsProp is undefined and formatProp is not undefined, then decrease score by\n // additionPenalty.\n\n if (optionsProp === undefined && formatProp !== undefined) score -= additionPenalty; // v. Else if optionsProp is not undefined and formatProp is undefined, then decrease score by\n // removalPenalty.\n else if (optionsProp !== undefined && formatProp === undefined) score -= removalPenalty; // vi. Else\n else {\n // 1. Let values be the array [\"2-digit\", \"numeric\", \"narrow\", \"short\",\n // \"long\"].\n var values = ['2-digit', 'numeric', 'narrow', 'short', 'long']; // 2. Let optionsPropIndex be the index of optionsProp within values.\n\n var optionsPropIndex = arrIndexOf.call(values, optionsProp); // 3. Let formatPropIndex be the index of formatProp within values.\n\n var formatPropIndex = arrIndexOf.call(values, formatProp); // 4. Let delta be max(min(formatPropIndex - optionsPropIndex, 2), -2).\n\n var delta = Math.max(Math.min(formatPropIndex - optionsPropIndex, 2), -2); // 5. If delta = 2, decrease score by longMorePenalty.\n\n if (delta === 2) score -= longMorePenalty; // 6. Else if delta = 1, decrease score by shortMorePenalty.\n else if (delta === 1) score -= shortMorePenalty; // 7. Else if delta = -1, decrease score by shortLessPenalty.\n else if (delta === -1) score -= shortLessPenalty; // 8. Else if delta = -2, decrease score by longLessPenalty.\n else if (delta === -2) score -= longLessPenalty;\n }\n } // d. If score > bestScore, then\n\n\n if (score > bestScore) {\n // i. Let bestScore be score.\n bestScore = score; // ii. Let bestFormat be format.\n\n bestFormat = format;\n } // e. Increase i by 1.\n\n\n i++;\n } // 13. Return bestFormat.\n\n\n return bestFormat;\n}\n/**\n * When the BestFitFormatMatcher abstract operation is called with two arguments options\n * and formats, it performs implementation dependent steps, which should return a set of\n * component representations that a typical user of the selected locale would perceive as\n * at least as good as the one returned by BasicFormatMatcher.\n *\n * This polyfill defines the algorithm to be the same as BasicFormatMatcher,\n * with the addition of bonus points awarded where the requested format is of\n * the same data type as the potentially matching format.\n *\n * This algo relies on the concept of closest distance matching described here:\n * http://unicode.org/reports/tr35/tr35-dates.html#Matching_Skeletons\n * Typically a “best match” is found using a closest distance match, such as:\n *\n * Symbols requesting a best choice for the locale are replaced.\n * j → one of {H, k, h, K}; C → one of {a, b, B}\n * -> Covered by cldr.js matching process\n *\n * For fields with symbols representing the same type (year, month, day, etc):\n * Most symbols have a small distance from each other.\n * M ≅ L; E ≅ c; a ≅ b ≅ B; H ≅ k ≅ h ≅ K; ...\n * -> Covered by cldr.js matching process\n *\n * Width differences among fields, other than those marking text vs numeric, are given small distance from each other.\n * MMM ≅ MMMM\n * MM ≅ M\n * Numeric and text fields are given a larger distance from each other.\n * MMM ≈ MM\n * Symbols representing substantial differences (week of year vs week of month) are given much larger a distances from each other.\n * d ≋ D; ...\n * Missing or extra fields cause a match to fail. (But see Missing Skeleton Fields).\n *\n *\n * For example,\n *\n * { month: 'numeric', day: 'numeric' }\n *\n * should match\n *\n * { month: '2-digit', day: '2-digit' }\n *\n * rather than\n *\n * { month: 'short', day: 'numeric' }\n *\n * This makes sense because a user requesting a formatted date with numeric parts would\n * not expect to see the returned format containing narrow, short or long part names\n */\n\n\nfunction BestFitFormatMatcher(options, formats) {\n /** Diverging: this block implements the hack for single property configuration, eg.:\n *\n * `new Intl.DateTimeFormat('en', {day: 'numeric'})`\n *\n * should produce a single digit with the day of the month. This is needed because\n * CLDR `availableFormats` data structure doesn't cover these cases.\n */\n {\n var optionsPropNames = [];\n\n for (var property in dateTimeComponents) {\n if (!hop.call(dateTimeComponents, property)) continue;\n\n if (options['[[' + property + ']]'] !== undefined) {\n optionsPropNames.push(property);\n }\n }\n\n if (optionsPropNames.length === 1) {\n var _bestFormat = generateSyntheticFormat(optionsPropNames[0], options['[[' + optionsPropNames[0] + ']]']);\n\n if (_bestFormat) {\n return _bestFormat;\n }\n }\n } // 1. Let removalPenalty be 120.\n\n var removalPenalty = 120; // 2. Let additionPenalty be 20.\n\n var additionPenalty = 20; // 3. Let longLessPenalty be 8.\n\n var longLessPenalty = 8; // 4. Let longMorePenalty be 6.\n\n var longMorePenalty = 6; // 5. Let shortLessPenalty be 6.\n\n var shortLessPenalty = 6; // 6. Let shortMorePenalty be 3.\n\n var shortMorePenalty = 3;\n var patternPenalty = 2;\n var hour12Penalty = 1; // 7. Let bestScore be -Infinity.\n\n var bestScore = -Infinity; // 8. Let bestFormat be undefined.\n\n var bestFormat = void 0; // 9. Let i be 0.\n\n var i = 0; // 10. Assert: formats is an Array object.\n // 11. Let len be the result of calling the [[Get]] internal method of formats with argument \"length\".\n\n var len = formats.length; // 12. Repeat while i < len:\n\n while (i < len) {\n // a. Let format be the result of calling the [[Get]] internal method of formats with argument ToString(i).\n var format = formats[i]; // b. Let score be 0.\n\n var score = 0; // c. For each property shown in Table 3:\n\n for (var _property in dateTimeComponents) {\n if (!hop.call(dateTimeComponents, _property)) continue; // i. Let optionsProp be options.[[]].\n\n var optionsProp = options['[[' + _property + ']]']; // ii. Let formatPropDesc be the result of calling the [[GetOwnProperty]] internal method of format\n // with argument property.\n // iii. If formatPropDesc is not undefined, then\n // 1. Let formatProp be the result of calling the [[Get]] internal method of format with argument property.\n\n var formatProp = hop.call(format, _property) ? format[_property] : undefined; // Diverging: using the default properties produced by the pattern/skeleton\n // to match it with user options, and apply a penalty\n\n var patternProp = hop.call(format._, _property) ? format._[_property] : undefined;\n\n if (optionsProp !== patternProp) {\n score -= patternPenalty;\n } // iv. If optionsProp is undefined and formatProp is not undefined, then decrease score by\n // additionPenalty.\n\n\n if (optionsProp === undefined && formatProp !== undefined) score -= additionPenalty; // v. Else if optionsProp is not undefined and formatProp is undefined, then decrease score by\n // removalPenalty.\n else if (optionsProp !== undefined && formatProp === undefined) score -= removalPenalty; // vi. Else\n else {\n // 1. Let values be the array [\"2-digit\", \"numeric\", \"narrow\", \"short\",\n // \"long\"].\n var values = ['2-digit', 'numeric', 'narrow', 'short', 'long']; // 2. Let optionsPropIndex be the index of optionsProp within values.\n\n var optionsPropIndex = arrIndexOf.call(values, optionsProp); // 3. Let formatPropIndex be the index of formatProp within values.\n\n var formatPropIndex = arrIndexOf.call(values, formatProp); // 4. Let delta be max(min(formatPropIndex - optionsPropIndex, 2), -2).\n\n var delta = Math.max(Math.min(formatPropIndex - optionsPropIndex, 2), -2);\n {\n // diverging from spec\n // When the bestFit argument is true, subtract additional penalty where data types are not the same\n if (formatPropIndex <= 1 && optionsPropIndex >= 2 || formatPropIndex >= 2 && optionsPropIndex <= 1) {\n // 5. If delta = 2, decrease score by longMorePenalty.\n if (delta > 0) score -= longMorePenalty;else if (delta < 0) score -= longLessPenalty;\n } else {\n // 5. If delta = 2, decrease score by longMorePenalty.\n if (delta > 1) score -= shortMorePenalty;else if (delta < -1) score -= shortLessPenalty;\n }\n }\n }\n }\n\n {\n // diverging to also take into consideration differences between 12 or 24 hours\n // which is special for the best fit only.\n if (format._.hour12 !== options.hour12) {\n score -= hour12Penalty;\n }\n } // d. If score > bestScore, then\n\n if (score > bestScore) {\n // i. Let bestScore be score.\n bestScore = score; // ii. Let bestFormat be format.\n\n bestFormat = format;\n } // e. Increase i by 1.\n\n\n i++;\n } // 13. Return bestFormat.\n\n\n return bestFormat;\n}\n/* 12.2.3 */\n\n\ninternals.DateTimeFormat = {\n '[[availableLocales]]': [],\n '[[relevantExtensionKeys]]': ['ca', 'nu'],\n '[[localeData]]': {}\n};\n/**\n * When the supportedLocalesOf method of Intl.DateTimeFormat is called, the\n * following steps are taken:\n */\n\n/* 12.2.2 */\n\ndefineProperty(Intl.DateTimeFormat, 'supportedLocalesOf', {\n configurable: true,\n writable: true,\n value: fnBind.call(function (locales) {\n // Bound functions only have the `this` value altered if being used as a constructor,\n // this lets us imitate a native function that has no constructor\n if (!hop.call(this, '[[availableLocales]]')) throw new TypeError('supportedLocalesOf() is not a constructor'); // Create an object whose props can be used to restore the values of RegExp props\n\n var regexpRestore = createRegExpRestore(),\n // 1. If options is not provided, then let options be undefined.\n options = arguments[1],\n // 2. Let availableLocales be the value of the [[availableLocales]] internal\n // property of the standard built-in object that is the initial value of\n // Intl.NumberFormat.\n availableLocales = this['[[availableLocales]]'],\n // 3. Let requestedLocales be the result of calling the CanonicalizeLocaleList\n // abstract operation (defined in 9.2.1) with argument locales.\n requestedLocales = CanonicalizeLocaleList(locales); // Restore the RegExp properties\n\n regexpRestore(); // 4. Return the result of calling the SupportedLocales abstract operation\n // (defined in 9.2.8) with arguments availableLocales, requestedLocales,\n // and options.\n\n return SupportedLocales(availableLocales, requestedLocales, options);\n }, internals.NumberFormat)\n});\n/**\n * This named accessor property returns a function that formats a number\n * according to the effective locale and the formatting options of this\n * DateTimeFormat object.\n */\n\n/* 12.3.2 */\n\ndefineProperty(Intl.DateTimeFormat.prototype, 'format', {\n configurable: true,\n get: GetFormatDateTime\n});\n\nfunction GetFormatDateTime() {\n var internal = this !== null && babelHelpers$1[\"typeof\"](this) === 'object' && getInternalProperties(this); // Satisfy test 12.3_b\n\n if (!internal || !internal['[[initializedDateTimeFormat]]']) throw new TypeError('`this` value for format() is not an initialized Intl.DateTimeFormat object.'); // The value of the [[Get]] attribute is a function that takes the following\n // steps:\n // 1. If the [[boundFormat]] internal property of this DateTimeFormat object\n // is undefined, then:\n\n if (internal['[[boundFormat]]'] === undefined) {\n // a. Let F be a Function object, with internal properties set as\n // specified for built-in functions in ES5, 15, or successor, and the\n // length property set to 0, that takes the argument date and\n // performs the following steps:\n var F = function F() {\n var date = arguments.length <= 0 || arguments[0] === undefined ? undefined : arguments[0]; // i. If date is not provided or is undefined, then let x be the\n // result as if by the expression Date.now() where Date.now is\n // the standard built-in function defined in ES5, 15.9.4.4.\n // ii. Else let x be ToNumber(date).\n // iii. Return the result of calling the FormatDateTime abstract\n // operation (defined below) with arguments this and x.\n\n var x = date === undefined ? Date.now() : toNumber(date);\n return FormatDateTime(this, x);\n }; // b. Let bind be the standard built-in function object defined in ES5,\n // 15.3.4.5.\n // c. Let bf be the result of calling the [[Call]] internal method of\n // bind with F as the this value and an argument list containing\n // the single item this.\n\n\n var bf = fnBind.call(F, this); // d. Set the [[boundFormat]] internal property of this NumberFormat\n // object to bf.\n\n internal['[[boundFormat]]'] = bf;\n } // Return the value of the [[boundFormat]] internal property of this\n // NumberFormat object.\n\n\n return internal['[[boundFormat]]'];\n}\n\nfunction formatToParts$1() {\n var date = arguments.length <= 0 || arguments[0] === undefined ? undefined : arguments[0];\n var internal = this !== null && babelHelpers$1[\"typeof\"](this) === 'object' && getInternalProperties(this);\n if (!internal || !internal['[[initializedDateTimeFormat]]']) throw new TypeError('`this` value for formatToParts() is not an initialized Intl.DateTimeFormat object.');\n var x = date === undefined ? Date.now() : toNumber(date);\n return FormatToPartsDateTime(this, x);\n}\n\nObject.defineProperty(Intl.DateTimeFormat.prototype, 'formatToParts', {\n enumerable: false,\n writable: true,\n configurable: true,\n value: formatToParts$1\n});\n\nfunction CreateDateTimeParts(dateTimeFormat, x) {\n // 1. If x is not a finite Number, then throw a RangeError exception.\n if (!isFinite(x)) throw new RangeError('Invalid valid date passed to format');\n\n var internal = dateTimeFormat.__getInternalProperties(secret); // Creating restore point for properties on the RegExp object... please wait\n\n /* let regexpRestore = */\n\n\n createRegExpRestore(); // ###TODO: review this\n // 2. Let locale be the value of the [[locale]] internal property of dateTimeFormat.\n\n var locale = internal['[[locale]]']; // 3. Let nf be the result of creating a new NumberFormat object as if by the\n // expression new Intl.NumberFormat([locale], {useGrouping: false}) where\n // Intl.NumberFormat is the standard built-in constructor defined in 11.1.3.\n\n var nf = new Intl.NumberFormat([locale], {\n useGrouping: false\n }); // 4. Let nf2 be the result of creating a new NumberFormat object as if by the\n // expression new Intl.NumberFormat([locale], {minimumIntegerDigits: 2, useGrouping:\n // false}) where Intl.NumberFormat is the standard built-in constructor defined in\n // 11.1.3.\n\n var nf2 = new Intl.NumberFormat([locale], {\n minimumIntegerDigits: 2,\n useGrouping: false\n }); // 5. Let tm be the result of calling the ToLocalTime abstract operation (defined\n // below) with x, the value of the [[calendar]] internal property of dateTimeFormat,\n // and the value of the [[timeZone]] internal property of dateTimeFormat.\n\n var tm = ToLocalTime(x, internal['[[calendar]]'], internal['[[timeZone]]']); // 6. Let result be the value of the [[pattern]] internal property of dateTimeFormat.\n\n var pattern = internal['[[pattern]]']; // 7.\n\n var result = new List(); // 8.\n\n var index = 0; // 9.\n\n var beginIndex = pattern.indexOf('{'); // 10.\n\n var endIndex = 0; // Need the locale minus any extensions\n\n var dataLocale = internal['[[dataLocale]]']; // Need the calendar data from CLDR\n\n var localeData = internals.DateTimeFormat['[[localeData]]'][dataLocale].calendars;\n var ca = internal['[[calendar]]']; // 11.\n\n while (beginIndex !== -1) {\n var fv = void 0; // a.\n\n endIndex = pattern.indexOf('}', beginIndex); // b.\n\n if (endIndex === -1) {\n throw new Error('Unclosed pattern');\n } // c.\n\n\n if (beginIndex > index) {\n arrPush.call(result, {\n type: 'literal',\n value: pattern.substring(index, beginIndex)\n });\n } // d.\n\n\n var p = pattern.substring(beginIndex + 1, endIndex); // e.\n\n if (dateTimeComponents.hasOwnProperty(p)) {\n // i. Let f be the value of the [[

]] internal property of dateTimeFormat.\n var f = internal['[[' + p + ']]']; // ii. Let v be the value of tm.[[

]].\n\n var v = tm['[[' + p + ']]']; // iii. If p is \"year\" and v ≤ 0, then let v be 1 - v.\n\n if (p === 'year' && v <= 0) {\n v = 1 - v;\n } // iv. If p is \"month\", then increase v by 1.\n else if (p === 'month') {\n v++;\n } // v. If p is \"hour\" and the value of the [[hour12]] internal property of\n // dateTimeFormat is true, then\n else if (p === 'hour' && internal['[[hour12]]'] === true) {\n // 1. Let v be v modulo 12.\n v = v % 12; // 2. If v is 0 and the value of the [[hourNo0]] internal property of\n // dateTimeFormat is true, then let v be 12.\n\n if (v === 0 && internal['[[hourNo0]]'] === true) {\n v = 12;\n }\n } // vi. If f is \"numeric\", then\n\n\n if (f === 'numeric') {\n // 1. Let fv be the result of calling the FormatNumber abstract operation\n // (defined in 11.3.2) with arguments nf and v.\n fv = FormatNumber(nf, v);\n } // vii. Else if f is \"2-digit\", then\n else if (f === '2-digit') {\n // 1. Let fv be the result of calling the FormatNumber abstract operation\n // with arguments nf2 and v.\n fv = FormatNumber(nf2, v); // 2. If the length of fv is greater than 2, let fv be the substring of fv\n // containing the last two characters.\n\n if (fv.length > 2) {\n fv = fv.slice(-2);\n }\n } // viii. Else if f is \"narrow\", \"short\", or \"long\", then let fv be a String\n // value representing f in the desired form; the String value depends upon\n // the implementation and the effective locale and calendar of\n // dateTimeFormat. If p is \"month\", then the String value may also depend\n // on whether dateTimeFormat has a [[day]] internal property. If p is\n // \"timeZoneName\", then the String value may also depend on the value of\n // the [[inDST]] field of tm.\n else if (f in dateWidths) {\n switch (p) {\n case 'month':\n fv = resolveDateString(localeData, ca, 'months', f, tm['[[' + p + ']]']);\n break;\n\n case 'weekday':\n try {\n fv = resolveDateString(localeData, ca, 'days', f, tm['[[' + p + ']]']); // fv = resolveDateString(ca.days, f)[tm['[['+ p +']]']];\n } catch (e) {\n throw new Error('Could not find weekday data for locale ' + locale);\n }\n\n break;\n\n case 'timeZoneName':\n fv = ''; // ###TODO\n\n break;\n\n case 'era':\n try {\n fv = resolveDateString(localeData, ca, 'eras', f, tm['[[' + p + ']]']);\n } catch (e) {\n throw new Error('Could not find era data for locale ' + locale);\n }\n\n break;\n\n default:\n fv = tm['[[' + p + ']]'];\n }\n } // ix\n\n\n arrPush.call(result, {\n type: p,\n value: fv\n }); // f.\n } else if (p === 'ampm') {\n // i.\n var _v = tm['[[hour]]']; // ii./iii.\n\n fv = resolveDateString(localeData, ca, 'dayPeriods', _v > 11 ? 'pm' : 'am', null); // iv.\n\n arrPush.call(result, {\n type: 'dayPeriod',\n value: fv\n }); // g.\n } else {\n arrPush.call(result, {\n type: 'literal',\n value: pattern.substring(beginIndex, endIndex + 1)\n });\n } // h.\n\n\n index = endIndex + 1; // i.\n\n beginIndex = pattern.indexOf('{', index);\n } // 12.\n\n\n if (endIndex < pattern.length - 1) {\n arrPush.call(result, {\n type: 'literal',\n value: pattern.substr(endIndex + 1)\n });\n } // 13.\n\n\n return result;\n}\n/**\n * When the FormatDateTime abstract operation is called with arguments dateTimeFormat\n * (which must be an object initialized as a DateTimeFormat) and x (which must be a Number\n * value), it returns a String value representing x (interpreted as a time value as\n * specified in ES5, 15.9.1.1) according to the effective locale and the formatting\n * options of dateTimeFormat.\n */\n\n\nfunction FormatDateTime(dateTimeFormat, x) {\n var parts = CreateDateTimeParts(dateTimeFormat, x);\n var result = '';\n\n for (var i = 0; parts.length > i; i++) {\n var part = parts[i];\n result += part.value;\n }\n\n return result;\n}\n\nfunction FormatToPartsDateTime(dateTimeFormat, x) {\n var parts = CreateDateTimeParts(dateTimeFormat, x);\n var result = [];\n\n for (var i = 0; parts.length > i; i++) {\n var part = parts[i];\n result.push({\n type: part.type,\n value: part.value\n });\n }\n\n return result;\n}\n/**\n * When the ToLocalTime abstract operation is called with arguments date, calendar, and\n * timeZone, the following steps are taken:\n */\n\n\nfunction ToLocalTime(date, calendar, timeZone) {\n // 1. Apply calendrical calculations on date for the given calendar and time zone to\n // produce weekday, era, year, month, day, hour, minute, second, and inDST values.\n // The calculations should use best available information about the specified\n // calendar and time zone. If the calendar is \"gregory\", then the calculations must\n // match the algorithms specified in ES5, 15.9.1, except that calculations are not\n // bound by the restrictions on the use of best available information on time zones\n // for local time zone adjustment and daylight saving time adjustment imposed by\n // ES5, 15.9.1.7 and 15.9.1.8.\n // ###TODO###\n var d = new Date(date),\n m = 'get' + (timeZone || ''); // 2. Return a Record with fields [[weekday]], [[era]], [[year]], [[month]], [[day]],\n // [[hour]], [[minute]], [[second]], and [[inDST]], each with the corresponding\n // calculated value.\n\n return new Record({\n '[[weekday]]': d[m + 'Day'](),\n '[[era]]': +(d[m + 'FullYear']() >= 0),\n '[[year]]': d[m + 'FullYear'](),\n '[[month]]': d[m + 'Month'](),\n '[[day]]': d[m + 'Date'](),\n '[[hour]]': d[m + 'Hours'](),\n '[[minute]]': d[m + 'Minutes'](),\n '[[second]]': d[m + 'Seconds'](),\n '[[inDST]]': false // ###TODO###\n\n });\n}\n/**\n * The function returns a new object whose properties and attributes are set as if\n * constructed by an object literal assigning to each of the following properties the\n * value of the corresponding internal property of this DateTimeFormat object (see 12.4):\n * locale, calendar, numberingSystem, timeZone, hour12, weekday, era, year, month, day,\n * hour, minute, second, and timeZoneName. Properties whose corresponding internal\n * properties are not present are not assigned.\n */\n\n/* 12.3.3 */\n\n\ndefineProperty(Intl.DateTimeFormat.prototype, 'resolvedOptions', {\n writable: true,\n configurable: true,\n value: function value() {\n var prop = void 0,\n descs = new Record(),\n props = ['locale', 'calendar', 'numberingSystem', 'timeZone', 'hour12', 'weekday', 'era', 'year', 'month', 'day', 'hour', 'minute', 'second', 'timeZoneName'],\n internal = this !== null && babelHelpers$1[\"typeof\"](this) === 'object' && getInternalProperties(this); // Satisfy test 12.3_b\n\n if (!internal || !internal['[[initializedDateTimeFormat]]']) throw new TypeError('`this` value for resolvedOptions() is not an initialized Intl.DateTimeFormat object.');\n\n for (var i = 0, max = props.length; i < max; i++) {\n if (hop.call(internal, prop = '[[' + props[i] + ']]')) descs[props[i]] = {\n value: internal[prop],\n writable: true,\n configurable: true,\n enumerable: true\n };\n }\n\n return objCreate({}, descs);\n }\n});\nvar ls = Intl.__localeSensitiveProtos = {\n Number: {},\n Date: {}\n};\n/**\n * When the toLocaleString method is called with optional arguments locales and options,\n * the following steps are taken:\n */\n\n/* 13.2.1 */\n\nls.Number.toLocaleString = function () {\n // Satisfy test 13.2.1_1\n if (Object.prototype.toString.call(this) !== '[object Number]') throw new TypeError('`this` value must be a number for Number.prototype.toLocaleString()'); // 1. Let x be this Number value (as defined in ES5, 15.7.4).\n // 2. If locales is not provided, then let locales be undefined.\n // 3. If options is not provided, then let options be undefined.\n // 4. Let numberFormat be the result of creating a new object as if by the\n // expression new Intl.NumberFormat(locales, options) where\n // Intl.NumberFormat is the standard built-in constructor defined in 11.1.3.\n // 5. Return the result of calling the FormatNumber abstract operation\n // (defined in 11.3.2) with arguments numberFormat and x.\n\n return FormatNumber(new NumberFormatConstructor(arguments[0], arguments[1]), this);\n};\n/**\n * When the toLocaleString method is called with optional arguments locales and options,\n * the following steps are taken:\n */\n\n/* 13.3.1 */\n\n\nls.Date.toLocaleString = function () {\n // Satisfy test 13.3.0_1\n if (Object.prototype.toString.call(this) !== '[object Date]') throw new TypeError('`this` value must be a Date instance for Date.prototype.toLocaleString()'); // 1. Let x be this time value (as defined in ES5, 15.9.5).\n\n var x = +this; // 2. If x is NaN, then return \"Invalid Date\".\n\n if (isNaN(x)) return 'Invalid Date'; // 3. If locales is not provided, then let locales be undefined.\n\n var locales = arguments[0]; // 4. If options is not provided, then let options be undefined.\n\n var options = arguments[1]; // 5. Let options be the result of calling the ToDateTimeOptions abstract\n // operation (defined in 12.1.1) with arguments options, \"any\", and \"all\".\n\n options = ToDateTimeOptions(options, 'any', 'all'); // 6. Let dateTimeFormat be the result of creating a new object as if by the\n // expression new Intl.DateTimeFormat(locales, options) where\n // Intl.DateTimeFormat is the standard built-in constructor defined in 12.1.3.\n\n var dateTimeFormat = new DateTimeFormatConstructor(locales, options); // 7. Return the result of calling the FormatDateTime abstract operation (defined\n // in 12.3.2) with arguments dateTimeFormat and x.\n\n return FormatDateTime(dateTimeFormat, x);\n};\n/**\n * When the toLocaleDateString method is called with optional arguments locales and\n * options, the following steps are taken:\n */\n\n/* 13.3.2 */\n\n\nls.Date.toLocaleDateString = function () {\n // Satisfy test 13.3.0_1\n if (Object.prototype.toString.call(this) !== '[object Date]') throw new TypeError('`this` value must be a Date instance for Date.prototype.toLocaleDateString()'); // 1. Let x be this time value (as defined in ES5, 15.9.5).\n\n var x = +this; // 2. If x is NaN, then return \"Invalid Date\".\n\n if (isNaN(x)) return 'Invalid Date'; // 3. If locales is not provided, then let locales be undefined.\n\n var locales = arguments[0],\n // 4. If options is not provided, then let options be undefined.\n options = arguments[1]; // 5. Let options be the result of calling the ToDateTimeOptions abstract\n // operation (defined in 12.1.1) with arguments options, \"date\", and \"date\".\n\n options = ToDateTimeOptions(options, 'date', 'date'); // 6. Let dateTimeFormat be the result of creating a new object as if by the\n // expression new Intl.DateTimeFormat(locales, options) where\n // Intl.DateTimeFormat is the standard built-in constructor defined in 12.1.3.\n\n var dateTimeFormat = new DateTimeFormatConstructor(locales, options); // 7. Return the result of calling the FormatDateTime abstract operation (defined\n // in 12.3.2) with arguments dateTimeFormat and x.\n\n return FormatDateTime(dateTimeFormat, x);\n};\n/**\n * When the toLocaleTimeString method is called with optional arguments locales and\n * options, the following steps are taken:\n */\n\n/* 13.3.3 */\n\n\nls.Date.toLocaleTimeString = function () {\n // Satisfy test 13.3.0_1\n if (Object.prototype.toString.call(this) !== '[object Date]') throw new TypeError('`this` value must be a Date instance for Date.prototype.toLocaleTimeString()'); // 1. Let x be this time value (as defined in ES5, 15.9.5).\n\n var x = +this; // 2. If x is NaN, then return \"Invalid Date\".\n\n if (isNaN(x)) return 'Invalid Date'; // 3. If locales is not provided, then let locales be undefined.\n\n var locales = arguments[0]; // 4. If options is not provided, then let options be undefined.\n\n var options = arguments[1]; // 5. Let options be the result of calling the ToDateTimeOptions abstract\n // operation (defined in 12.1.1) with arguments options, \"time\", and \"time\".\n\n options = ToDateTimeOptions(options, 'time', 'time'); // 6. Let dateTimeFormat be the result of creating a new object as if by the\n // expression new Intl.DateTimeFormat(locales, options) where\n // Intl.DateTimeFormat is the standard built-in constructor defined in 12.1.3.\n\n var dateTimeFormat = new DateTimeFormatConstructor(locales, options); // 7. Return the result of calling the FormatDateTime abstract operation (defined\n // in 12.3.2) with arguments dateTimeFormat and x.\n\n return FormatDateTime(dateTimeFormat, x);\n};\n\ndefineProperty(Intl, '__applyLocaleSensitivePrototypes', {\n writable: true,\n configurable: true,\n value: function value() {\n defineProperty(Number.prototype, 'toLocaleString', {\n writable: true,\n configurable: true,\n value: ls.Number.toLocaleString\n }); // Need this here for IE 8, to avoid the _DontEnum_ bug\n\n defineProperty(Date.prototype, 'toLocaleString', {\n writable: true,\n configurable: true,\n value: ls.Date.toLocaleString\n });\n\n for (var k in ls.Date) {\n if (hop.call(ls.Date, k)) defineProperty(Date.prototype, k, {\n writable: true,\n configurable: true,\n value: ls.Date[k]\n });\n }\n }\n});\n/**\n * Can't really ship a single script with data for hundreds of locales, so we provide\n * this __addLocaleData method as a means for the developer to add the data on an\n * as-needed basis\n */\n\ndefineProperty(Intl, '__addLocaleData', {\n value: function value(data) {\n if (!IsStructurallyValidLanguageTag(data.locale)) throw new Error(\"Object passed doesn't identify itself with a valid language tag\");\n addLocaleData(data, data.locale);\n }\n});\n\nfunction addLocaleData(data, tag) {\n // Both NumberFormat and DateTimeFormat require number data, so throw if it isn't present\n if (!data.number) throw new Error(\"Object passed doesn't contain locale data for Intl.NumberFormat\");\n var locale = void 0,\n locales = [tag],\n parts = tag.split('-'); // Create fallbacks for locale data with scripts, e.g. Latn, Hans, Vaii, etc\n\n if (parts.length > 2 && parts[1].length === 4) arrPush.call(locales, parts[0] + '-' + parts[2]);\n\n while (locale = arrShift.call(locales)) {\n // Add to NumberFormat internal properties as per 11.2.3\n arrPush.call(internals.NumberFormat['[[availableLocales]]'], locale);\n internals.NumberFormat['[[localeData]]'][locale] = data.number; // ...and DateTimeFormat internal properties as per 12.2.3\n\n if (data.date) {\n data.date.nu = data.number.nu;\n arrPush.call(internals.DateTimeFormat['[[availableLocales]]'], locale);\n internals.DateTimeFormat['[[localeData]]'][locale] = data.date;\n }\n } // If this is the first set of locale data added, make it the default\n\n\n if (defaultLocale === undefined) setDefaultLocale(tag);\n}\n\ndefineProperty(Intl, '__disableRegExpRestore', {\n value: function value() {\n internals.disableRegExpRestore = true;\n }\n});\nmodule.exports = Intl;","\"use strict\";\n\nvar global = require(\"ext/global-this\"),\n validTypes = {\n object: true,\n symbol: true\n};\n\nmodule.exports = function () {\n var Symbol = global.Symbol;\n var symbol;\n if (typeof Symbol !== \"function\") return false;\n symbol = Symbol(\"test symbol\");\n\n try {\n String(symbol);\n } catch (e) {\n return false;\n } // Return 'true' also for polyfills\n\n\n if (!validTypes[typeof Symbol.iterator]) return false;\n if (!validTypes[typeof Symbol.toPrimitive]) return false;\n if (!validTypes[typeof Symbol.toStringTag]) return false;\n return true;\n};","\"use strict\";\n\nmodule.exports = function () {\n if (typeof globalThis !== \"object\") return false;\n if (!globalThis) return false;\n return globalThis.Array === Array;\n};","var naiveFallback = function naiveFallback() {\n if (typeof self === \"object\" && self) return self;\n if (typeof window === \"object\" && window) return window;\n throw new Error(\"Unable to resolve global `this`\");\n};\n\nmodule.exports = function () {\n if (this) return this; // Unexpected strict mode (may happen if e.g. bundled into ESM module)\n // Thanks @mathiasbynens -> https://mathiasbynens.be/notes/globalthis\n // In all ES5+ engines global object inherits from Object.prototype\n // (if you approached one that doesn't please report)\n\n try {\n Object.defineProperty(Object.prototype, \"__global__\", {\n get: function get() {\n return this;\n },\n configurable: true\n });\n } catch (error) {\n // Unfortunate case of Object.prototype being sealed (via preventExtensions, seal or freeze)\n return naiveFallback();\n }\n\n try {\n // Safari case (window.__global__ is resolved with global context, but __global__ does not)\n if (!__global__) return naiveFallback();\n return __global__;\n } finally {\n delete Object.prototype.__global__;\n }\n}();","// ES2015 Symbol polyfill for environments that do not (or partially) support it\n\"use strict\";\n\nvar d = require(\"d\"),\n validateSymbol = require(\"./validate-symbol\"),\n NativeSymbol = require(\"ext/global-this\").Symbol,\n generateName = require(\"./lib/private/generate-name\"),\n setupStandardSymbols = require(\"./lib/private/setup/standard-symbols\"),\n setupSymbolRegistry = require(\"./lib/private/setup/symbol-registry\");\n\nvar create = Object.create,\n defineProperties = Object.defineProperties,\n defineProperty = Object.defineProperty;\nvar SymbolPolyfill, HiddenSymbol, isNativeSafe;\n\nif (typeof NativeSymbol === \"function\") {\n try {\n String(NativeSymbol());\n isNativeSafe = true;\n } catch (ignore) {}\n} else {\n NativeSymbol = null;\n} // Internal constructor (not one exposed) for creating Symbol instances.\n// This one is used to ensure that `someSymbol instanceof Symbol` always return false\n\n\nHiddenSymbol = function Symbol(description) {\n if (this instanceof HiddenSymbol) throw new TypeError(\"Symbol is not a constructor\");\n return SymbolPolyfill(description);\n}; // Exposed `Symbol` constructor\n// (returns instances of HiddenSymbol)\n\n\nmodule.exports = SymbolPolyfill = function Symbol(description) {\n var symbol;\n if (this instanceof Symbol) throw new TypeError(\"Symbol is not a constructor\");\n if (isNativeSafe) return NativeSymbol(description);\n symbol = create(HiddenSymbol.prototype);\n description = description === undefined ? \"\" : String(description);\n return defineProperties(symbol, {\n __description__: d(\"\", description),\n __name__: d(\"\", generateName(description))\n });\n};\n\nsetupStandardSymbols(SymbolPolyfill);\nsetupSymbolRegistry(SymbolPolyfill); // Internal tweaks for real symbol producer\n\ndefineProperties(HiddenSymbol.prototype, {\n constructor: d(SymbolPolyfill),\n toString: d(\"\", function () {\n return this.__name__;\n })\n}); // Proper implementation of methods exposed on Symbol.prototype\n// They won't be accessible on produced symbol instances as they derive from HiddenSymbol.prototype\n\ndefineProperties(SymbolPolyfill.prototype, {\n toString: d(function () {\n return \"Symbol (\" + validateSymbol(this).__description__ + \")\";\n }),\n valueOf: d(function () {\n return validateSymbol(this);\n })\n});\ndefineProperty(SymbolPolyfill.prototype, SymbolPolyfill.toPrimitive, d(\"\", function () {\n var symbol = validateSymbol(this);\n if (typeof symbol === \"symbol\") return symbol;\n return symbol.toString();\n}));\ndefineProperty(SymbolPolyfill.prototype, SymbolPolyfill.toStringTag, d(\"c\", \"Symbol\")); // Proper implementaton of toPrimitive and toStringTag for returned symbol instances\n\ndefineProperty(HiddenSymbol.prototype, SymbolPolyfill.toStringTag, d(\"c\", SymbolPolyfill.prototype[SymbolPolyfill.toStringTag])); // Note: It's important to define `toPrimitive` as last one, as some implementations\n// implement `toPrimitive` natively without implementing `toStringTag` (or other specified symbols)\n// And that may invoke error in definition flow:\n// See: https://github.com/medikoo/es6-symbol/issues/13#issuecomment-164146149\n\ndefineProperty(HiddenSymbol.prototype, SymbolPolyfill.toPrimitive, d(\"c\", SymbolPolyfill.prototype[SymbolPolyfill.toPrimitive]));","\"use strict\";\n\nvar isFunction = require(\"../function/is\");\n\nvar classRe = /^\\s*class[\\s{/}]/,\n functionToString = Function.prototype.toString;\n\nmodule.exports = function (value) {\n if (!isFunction(value)) return false;\n if (classRe.test(functionToString.call(value))) return false;\n return true;\n};","\"use strict\";\n\nvar isPrototype = require(\"../prototype/is\");\n\nmodule.exports = function (value) {\n if (typeof value !== \"function\") return false;\n if (!hasOwnProperty.call(value, \"length\")) return false;\n\n try {\n if (typeof value.length !== \"number\") return false;\n if (typeof value.call !== \"function\") return false;\n if (typeof value.apply !== \"function\") return false;\n } catch (error) {\n return false;\n }\n\n return !isPrototype(value);\n};","\"use strict\";\n\nvar isObject = require(\"../object/is\");\n\nmodule.exports = function (value) {\n if (!isObject(value)) return false;\n\n try {\n if (!value.constructor) return false;\n return value.constructor.prototype === value;\n } catch (error) {\n return false;\n }\n};","\"use strict\";\n\nvar isValue = require(\"../value/is\"); // prettier-ignore\n\n\nvar possibleTypes = {\n \"object\": true,\n \"function\": true,\n \"undefined\": true\n /* document.all */\n\n};\n\nmodule.exports = function (value) {\n if (!isValue(value)) return false;\n return hasOwnProperty.call(possibleTypes, typeof value);\n};","\"use strict\";\n\nmodule.exports = require(\"./is-implemented\")() ? Object.assign : require(\"./shim\");","\"use strict\";\n\nmodule.exports = function () {\n var assign = Object.assign,\n obj;\n if (typeof assign !== \"function\") return false;\n obj = {\n foo: \"raz\"\n };\n assign(obj, {\n bar: \"dwa\"\n }, {\n trzy: \"trzy\"\n });\n return obj.foo + obj.bar + obj.trzy === \"razdwatrzy\";\n};","\"use strict\";\n\nvar keys = require(\"../keys\"),\n value = require(\"../valid-value\"),\n max = Math.max;\n\nmodule.exports = function (dest, src\n/*, …srcn*/\n) {\n var error,\n i,\n length = max(arguments.length, 2),\n assign;\n dest = Object(value(dest));\n\n assign = function assign(key) {\n try {\n dest[key] = src[key];\n } catch (e) {\n if (!error) error = e;\n }\n };\n\n for (i = 1; i < length; ++i) {\n src = arguments[i];\n keys(src).forEach(assign);\n }\n\n if (error !== undefined) throw error;\n return dest;\n};","\"use strict\";\n\nmodule.exports = require(\"./is-implemented\")() ? Object.keys : require(\"./shim\");","\"use strict\";\n\nmodule.exports = function () {\n try {\n Object.keys(\"primitive\");\n return true;\n } catch (e) {\n return false;\n }\n};","\"use strict\";\n\nvar isValue = require(\"../is-value\");\n\nvar keys = Object.keys;\n\nmodule.exports = function (object) {\n return keys(isValue(object) ? Object(object) : object);\n};","\"use strict\"; // eslint-disable-next-line no-empty-function\n\nmodule.exports = function () {};","\"use strict\";\n\nvar isValue = require(\"./is-value\");\n\nmodule.exports = function (value) {\n if (!isValue(value)) throw new TypeError(\"Cannot use null or undefined\");\n return value;\n};","\"use strict\";\n\nvar isValue = require(\"./is-value\");\n\nvar forEach = Array.prototype.forEach,\n create = Object.create;\n\nvar process = function process(src, obj) {\n var key;\n\n for (key in src) {\n obj[key] = src[key];\n }\n}; // eslint-disable-next-line no-unused-vars\n\n\nmodule.exports = function (opts1\n/*, …options*/\n) {\n var result = create(null);\n forEach.call(arguments, function (options) {\n if (!isValue(options)) return;\n process(Object(options), result);\n });\n return result;\n};","\"use strict\";\n\nmodule.exports = require(\"./is-implemented\")() ? String.prototype.contains : require(\"./shim\");","\"use strict\";\n\nvar str = \"razdwatrzy\";\n\nmodule.exports = function () {\n if (typeof str.contains !== \"function\") return false;\n return str.contains(\"dwa\") === true && str.contains(\"foo\") === false;\n};","\"use strict\";\n\nvar indexOf = String.prototype.indexOf;\n\nmodule.exports = function (searchString\n/*, position*/\n) {\n return indexOf.call(this, searchString, arguments[1]) > -1;\n};","\"use strict\";\n\nmodule.exports = function (value) {\n if (!value) return false;\n if (typeof value === \"symbol\") return true;\n if (!value.constructor) return false;\n if (value.constructor.name !== \"Symbol\") return false;\n return value[value.constructor.toStringTag] === \"Symbol\";\n};","\"use strict\";\n\nvar d = require(\"d\");\n\nvar create = Object.create,\n defineProperty = Object.defineProperty,\n objPrototype = Object.prototype;\nvar created = create(null);\n\nmodule.exports = function (desc) {\n var postfix = 0,\n name,\n ie11BugWorkaround;\n\n while (created[desc + (postfix || \"\")]) {\n ++postfix;\n }\n\n desc += postfix || \"\";\n created[desc] = true;\n name = \"@@\" + desc;\n defineProperty(objPrototype, name, d.gs(null, function (value) {\n // For IE11 issue see:\n // https://connect.microsoft.com/IE/feedbackdetail/view/1928508/\n // ie11-broken-getters-on-dom-objects\n // https://github.com/medikoo/es6-symbol/issues/12\n if (ie11BugWorkaround) return;\n ie11BugWorkaround = true;\n defineProperty(this, name, d(value));\n ie11BugWorkaround = false;\n }));\n return name;\n};","\"use strict\";\n\nvar d = require(\"d\"),\n NativeSymbol = require(\"ext/global-this\").Symbol;\n\nmodule.exports = function (SymbolPolyfill) {\n return Object.defineProperties(SymbolPolyfill, {\n // To ensure proper interoperability with other native functions (e.g. Array.from)\n // fallback to eventual native implementation of given symbol\n hasInstance: d(\"\", NativeSymbol && NativeSymbol.hasInstance || SymbolPolyfill(\"hasInstance\")),\n isConcatSpreadable: d(\"\", NativeSymbol && NativeSymbol.isConcatSpreadable || SymbolPolyfill(\"isConcatSpreadable\")),\n iterator: d(\"\", NativeSymbol && NativeSymbol.iterator || SymbolPolyfill(\"iterator\")),\n match: d(\"\", NativeSymbol && NativeSymbol.match || SymbolPolyfill(\"match\")),\n replace: d(\"\", NativeSymbol && NativeSymbol.replace || SymbolPolyfill(\"replace\")),\n search: d(\"\", NativeSymbol && NativeSymbol.search || SymbolPolyfill(\"search\")),\n species: d(\"\", NativeSymbol && NativeSymbol.species || SymbolPolyfill(\"species\")),\n split: d(\"\", NativeSymbol && NativeSymbol.split || SymbolPolyfill(\"split\")),\n toPrimitive: d(\"\", NativeSymbol && NativeSymbol.toPrimitive || SymbolPolyfill(\"toPrimitive\")),\n toStringTag: d(\"\", NativeSymbol && NativeSymbol.toStringTag || SymbolPolyfill(\"toStringTag\")),\n unscopables: d(\"\", NativeSymbol && NativeSymbol.unscopables || SymbolPolyfill(\"unscopables\"))\n });\n};","\"use strict\";\n\nvar d = require(\"d\"),\n validateSymbol = require(\"../../../validate-symbol\");\n\nvar registry = Object.create(null);\n\nmodule.exports = function (SymbolPolyfill) {\n return Object.defineProperties(SymbolPolyfill, {\n for: d(function (key) {\n if (registry[key]) return registry[key];\n return registry[key] = SymbolPolyfill(String(key));\n }),\n keyFor: d(function (symbol) {\n var key;\n validateSymbol(symbol);\n\n for (key in registry) {\n if (registry[key] === symbol) return key;\n }\n\n return undefined;\n })\n });\n};","'use strict';\n\nvar slice = Array.prototype.slice;\n\nvar isArgs = require('./isArguments');\n\nvar origKeys = Object.keys;\nvar keysShim = origKeys ? function keys(o) {\n return origKeys(o);\n} : require('./implementation');\nvar originalKeys = Object.keys;\n\nkeysShim.shim = function shimObjectKeys() {\n if (Object.keys) {\n var keysWorksWithArguments = function () {\n // Safari 5.0 bug\n var args = Object.keys(arguments);\n return args && args.length === arguments.length;\n }(1, 2);\n\n if (!keysWorksWithArguments) {\n Object.keys = function keys(object) {\n // eslint-disable-line func-name-matching\n if (isArgs(object)) {\n return originalKeys(slice.call(object));\n }\n\n return originalKeys(object);\n };\n }\n } else {\n Object.keys = keysShim;\n }\n\n return Object.keys || keysShim;\n};\n\nmodule.exports = keysShim;","'use strict';\n\nvar keysShim;\n\nif (!Object.keys) {\n // modified from https://github.com/es-shims/es5-shim\n var has = Object.prototype.hasOwnProperty;\n var toStr = Object.prototype.toString;\n\n var isArgs = require('./isArguments'); // eslint-disable-line global-require\n\n\n var isEnumerable = Object.prototype.propertyIsEnumerable;\n var hasDontEnumBug = !isEnumerable.call({\n toString: null\n }, 'toString');\n var hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');\n var dontEnums = ['toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor'];\n\n var equalsConstructorPrototype = function equalsConstructorPrototype(o) {\n var ctor = o.constructor;\n return ctor && ctor.prototype === o;\n };\n\n var excludedKeys = {\n $applicationCache: true,\n $console: true,\n $external: true,\n $frame: true,\n $frameElement: true,\n $frames: true,\n $innerHeight: true,\n $innerWidth: true,\n $onmozfullscreenchange: true,\n $onmozfullscreenerror: true,\n $outerHeight: true,\n $outerWidth: true,\n $pageXOffset: true,\n $pageYOffset: true,\n $parent: true,\n $scrollLeft: true,\n $scrollTop: true,\n $scrollX: true,\n $scrollY: true,\n $self: true,\n $webkitIndexedDB: true,\n $webkitStorageInfo: true,\n $window: true\n };\n\n var hasAutomationEqualityBug = function () {\n /* global window */\n if (typeof window === 'undefined') {\n return false;\n }\n\n for (var k in window) {\n try {\n if (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {\n try {\n equalsConstructorPrototype(window[k]);\n } catch (e) {\n return true;\n }\n }\n } catch (e) {\n return true;\n }\n }\n\n return false;\n }();\n\n var equalsConstructorPrototypeIfNotBuggy = function equalsConstructorPrototypeIfNotBuggy(o) {\n /* global window */\n if (typeof window === 'undefined' || !hasAutomationEqualityBug) {\n return equalsConstructorPrototype(o);\n }\n\n try {\n return equalsConstructorPrototype(o);\n } catch (e) {\n return false;\n }\n };\n\n keysShim = function keys(object) {\n var isObject = object !== null && typeof object === 'object';\n var isFunction = toStr.call(object) === '[object Function]';\n var isArguments = isArgs(object);\n var isString = isObject && toStr.call(object) === '[object String]';\n var theKeys = [];\n\n if (!isObject && !isFunction && !isArguments) {\n throw new TypeError('Object.keys called on a non-object');\n }\n\n var skipProto = hasProtoEnumBug && isFunction;\n\n if (isString && object.length > 0 && !has.call(object, 0)) {\n for (var i = 0; i < object.length; ++i) {\n theKeys.push(String(i));\n }\n }\n\n if (isArguments && object.length > 0) {\n for (var j = 0; j < object.length; ++j) {\n theKeys.push(String(j));\n }\n } else {\n for (var name in object) {\n if (!(skipProto && name === 'prototype') && has.call(object, name)) {\n theKeys.push(String(name));\n }\n }\n }\n\n if (hasDontEnumBug) {\n var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);\n\n for (var k = 0; k < dontEnums.length; ++k) {\n if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {\n theKeys.push(dontEnums[k]);\n }\n }\n }\n\n return theKeys;\n };\n}\n\nmodule.exports = keysShim;","'use strict';\n/* eslint complexity: [2, 18], max-statements: [2, 33] */\n\nmodule.exports = function hasSymbols() {\n if (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') {\n return false;\n }\n\n if (typeof Symbol.iterator === 'symbol') {\n return true;\n }\n\n var obj = {};\n var sym = Symbol('test');\n var symObj = Object(sym);\n\n if (typeof sym === 'string') {\n return false;\n }\n\n if (Object.prototype.toString.call(sym) !== '[object Symbol]') {\n return false;\n }\n\n if (Object.prototype.toString.call(symObj) !== '[object Symbol]') {\n return false;\n } // temp disabled per https://github.com/ljharb/object.assign/issues/17\n // if (sym instanceof Symbol) { return false; }\n // temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4\n // if (!(symObj instanceof Symbol)) { return false; }\n // if (typeof Symbol.prototype.toString !== 'function') { return false; }\n // if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }\n\n\n var symVal = 42;\n obj[sym] = symVal;\n\n for (sym in obj) {\n return false;\n } // eslint-disable-line no-restricted-syntax\n\n\n if (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) {\n return false;\n }\n\n if (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) {\n return false;\n }\n\n var syms = Object.getOwnPropertySymbols(obj);\n\n if (syms.length !== 1 || syms[0] !== sym) {\n return false;\n }\n\n if (!Object.prototype.propertyIsEnumerable.call(obj, sym)) {\n return false;\n }\n\n if (typeof Object.getOwnPropertyDescriptor === 'function') {\n var descriptor = Object.getOwnPropertyDescriptor(obj, sym);\n\n if (descriptor.value !== symVal || descriptor.enumerable !== true) {\n return false;\n }\n }\n\n return true;\n};","'use strict';\n/* eslint no-invalid-this: 1 */\n\nvar ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';\nvar slice = Array.prototype.slice;\nvar toStr = Object.prototype.toString;\nvar funcType = '[object Function]';\n\nmodule.exports = function bind(that) {\n var target = this;\n\n if (typeof target !== 'function' || toStr.call(target) !== funcType) {\n throw new TypeError(ERROR_MESSAGE + target);\n }\n\n var args = slice.call(arguments, 1);\n var bound;\n\n var binder = function binder() {\n if (this instanceof bound) {\n var result = target.apply(this, args.concat(slice.call(arguments)));\n\n if (Object(result) === result) {\n return result;\n }\n\n return this;\n } else {\n return target.apply(that, args.concat(slice.call(arguments)));\n }\n };\n\n var boundLength = Math.max(0, target.length - args.length);\n var boundArgs = [];\n\n for (var i = 0; i < boundLength; i++) {\n boundArgs.push('$' + i);\n }\n\n bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);\n\n if (target.prototype) {\n var Empty = function Empty() {};\n\n Empty.prototype = target.prototype;\n bound.prototype = new Empty();\n Empty.prototype = null;\n }\n\n return bound;\n};","'use strict';\n\nvar GetIntrinsic = require('../GetIntrinsic');\n\nvar $Math = GetIntrinsic('%Math%');\n\nvar ToNumber = require('./ToNumber');\n\nvar $isNaN = require('../helpers/isNaN');\n\nvar $isFinite = require('../helpers/isFinite');\n\nvar $sign = require('../helpers/sign');\n\nvar $floor = $Math.floor;\nvar $abs = $Math.abs; // http://www.ecma-international.org/ecma-262/5.1/#sec-9.4\n\nmodule.exports = function ToInteger(value) {\n var number = ToNumber(value);\n\n if ($isNaN(number)) {\n return 0;\n }\n\n if (number === 0 || !$isFinite(number)) {\n return number;\n }\n\n return $sign(number) * $floor($abs(number));\n};","'use strict'; // http://www.ecma-international.org/ecma-262/5.1/#sec-9.3\n\nmodule.exports = function ToNumber(value) {\n return +value; // eslint-disable-line no-implicit-coercion\n};","'use strict';\n\nmodule.exports = function sign(number) {\n return number >= 0 ? 1 : -1;\n};","'use strict';\n\nvar GetIntrinsic = require('../GetIntrinsic');\n\nvar $TypeError = GetIntrinsic('%TypeError%');\nvar $Number = GetIntrinsic('%Number%');\nvar $RegExp = GetIntrinsic('%RegExp%');\nvar $parseInteger = GetIntrinsic('%parseInt%');\n\nvar callBound = require('../helpers/callBound');\n\nvar regexTester = require('../helpers/regexTester');\n\nvar isPrimitive = require('../helpers/isPrimitive');\n\nvar $strSlice = callBound('String.prototype.slice');\nvar isBinary = regexTester(/^0b[01]+$/i);\nvar isOctal = regexTester(/^0o[0-7]+$/i);\nvar isInvalidHexLiteral = regexTester(/^[-+]0x[0-9a-f]+$/i);\nvar nonWS = [\"\\x85\", \"\\u200B\", \"\\uFFFE\"].join('');\nvar nonWSregex = new $RegExp('[' + nonWS + ']', 'g');\nvar hasNonWS = regexTester(nonWSregex); // whitespace from: https://es5.github.io/#x15.5.4.20\n// implementation from https://github.com/es-shims/es5-shim/blob/v3.4.0/es5-shim.js#L1304-L1324\n\nvar ws = [\"\\t\\n\\x0B\\f\\r \\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003\", \"\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\", \"\\u2029\\uFEFF\"].join('');\nvar trimRegex = new RegExp('(^[' + ws + ']+)|([' + ws + ']+$)', 'g');\nvar $replace = callBound('String.prototype.replace');\n\nvar $trim = function $trim(value) {\n return $replace(value, trimRegex, '');\n};\n\nvar ToPrimitive = require('./ToPrimitive'); // https://www.ecma-international.org/ecma-262/6.0/#sec-tonumber\n\n\nmodule.exports = function ToNumber(argument) {\n var value = isPrimitive(argument) ? argument : ToPrimitive(argument, $Number);\n\n if (typeof value === 'symbol') {\n throw new $TypeError('Cannot convert a Symbol value to a number');\n }\n\n if (typeof value === 'string') {\n if (isBinary(value)) {\n return ToNumber($parseInteger($strSlice(value, 2), 2));\n } else if (isOctal(value)) {\n return ToNumber($parseInteger($strSlice(value, 2), 8));\n } else if (hasNonWS(value) || isInvalidHexLiteral(value)) {\n return NaN;\n } else {\n var trimmed = $trim(value);\n\n if (trimmed !== value) {\n return ToNumber(trimmed);\n }\n }\n }\n\n return $Number(value);\n};","'use strict';\n\nvar GetIntrinsic = require('../GetIntrinsic');\n\nvar $test = GetIntrinsic('RegExp.prototype.test');\n\nvar callBind = require('./callBind');\n\nmodule.exports = function regexTester(regex) {\n return callBind($test, regex);\n};","'use strict';\n\nmodule.exports = function isPrimitive(value) {\n return value === null || typeof value !== 'function' && typeof value !== 'object';\n};","'use strict';\n\nvar toPrimitive = require('es-to-primitive/es2015'); // https://www.ecma-international.org/ecma-262/6.0/#sec-toprimitive\n\n\nmodule.exports = function ToPrimitive(input) {\n if (arguments.length > 1) {\n return toPrimitive(input, arguments[1]);\n }\n\n return toPrimitive(input);\n};","'use strict';\n\nvar hasSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol';\n\nvar isPrimitive = require('./helpers/isPrimitive');\n\nvar isCallable = require('is-callable');\n\nvar isDate = require('is-date-object');\n\nvar isSymbol = require('is-symbol');\n\nvar ordinaryToPrimitive = function OrdinaryToPrimitive(O, hint) {\n if (typeof O === 'undefined' || O === null) {\n throw new TypeError('Cannot call method on ' + O);\n }\n\n if (typeof hint !== 'string' || hint !== 'number' && hint !== 'string') {\n throw new TypeError('hint must be \"string\" or \"number\"');\n }\n\n var methodNames = hint === 'string' ? ['toString', 'valueOf'] : ['valueOf', 'toString'];\n var method, result, i;\n\n for (i = 0; i < methodNames.length; ++i) {\n method = O[methodNames[i]];\n\n if (isCallable(method)) {\n result = method.call(O);\n\n if (isPrimitive(result)) {\n return result;\n }\n }\n }\n\n throw new TypeError('No default value');\n};\n\nvar GetMethod = function GetMethod(O, P) {\n var func = O[P];\n\n if (func !== null && typeof func !== 'undefined') {\n if (!isCallable(func)) {\n throw new TypeError(func + ' returned for property ' + P + ' of object ' + O + ' is not a function');\n }\n\n return func;\n }\n\n return void 0;\n}; // http://www.ecma-international.org/ecma-262/6.0/#sec-toprimitive\n\n\nmodule.exports = function ToPrimitive(input) {\n if (isPrimitive(input)) {\n return input;\n }\n\n var hint = 'default';\n\n if (arguments.length > 1) {\n if (arguments[1] === String) {\n hint = 'string';\n } else if (arguments[1] === Number) {\n hint = 'number';\n }\n }\n\n var exoticToPrim;\n\n if (hasSymbols) {\n if (Symbol.toPrimitive) {\n exoticToPrim = GetMethod(input, Symbol.toPrimitive);\n } else if (isSymbol(input)) {\n exoticToPrim = Symbol.prototype.valueOf;\n }\n }\n\n if (typeof exoticToPrim !== 'undefined') {\n var result = exoticToPrim.call(input, hint);\n\n if (isPrimitive(result)) {\n return result;\n }\n\n throw new TypeError('unable to convert exotic object to primitive');\n }\n\n if (hint === 'default' && (isDate(input) || isSymbol(input))) {\n hint = 'string';\n }\n\n return ordinaryToPrimitive(input, hint === 'default' ? 'number' : hint);\n};","'use strict';\n\nmodule.exports = function isPrimitive(value) {\n return value === null || typeof value !== 'function' && typeof value !== 'object';\n};","'use strict';\n\nvar getDay = Date.prototype.getDay;\n\nvar tryDateObject = function tryDateObject(value) {\n try {\n getDay.call(value);\n return true;\n } catch (e) {\n return false;\n }\n};\n\nvar toStr = Object.prototype.toString;\nvar dateClass = '[object Date]';\nvar hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';\n\nmodule.exports = function isDateObject(value) {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n return hasToStringTag ? tryDateObject(value) : toStr.call(value) === dateClass;\n};","'use strict';\n\nvar toStr = Object.prototype.toString;\n\nvar hasSymbols = require('has-symbols')();\n\nif (hasSymbols) {\n var symToStr = Symbol.prototype.toString;\n var symStringRegex = /^Symbol\\(.*\\)$/;\n\n var isSymbolObject = function isRealSymbolObject(value) {\n if (typeof value.valueOf() !== 'symbol') {\n return false;\n }\n\n return symStringRegex.test(symToStr.call(value));\n };\n\n module.exports = function isSymbol(value) {\n if (typeof value === 'symbol') {\n return true;\n }\n\n if (toStr.call(value) !== '[object Symbol]') {\n return false;\n }\n\n try {\n return isSymbolObject(value);\n } catch (e) {\n return false;\n }\n };\n} else {\n module.exports = function isSymbol(value) {\n // this environment does not support Symbols.\n return false && value;\n };\n}","'use strict';\n\nvar MAX_SAFE_INTEGER = require('../helpers/maxSafeInteger');\n\nvar ToInteger = require('./ToInteger');\n\nmodule.exports = function ToLength(argument) {\n var len = ToInteger(argument);\n\n if (len <= 0) {\n return 0;\n } // includes converting -0 to +0\n\n\n if (len > MAX_SAFE_INTEGER) {\n return MAX_SAFE_INTEGER;\n }\n\n return len;\n};","'use strict';\n\nvar GetIntrinsic = require('../GetIntrinsic');\n\nvar $Math = GetIntrinsic('%Math%');\nvar $Number = GetIntrinsic('%Number%');\nmodule.exports = $Number.MAX_SAFE_INTEGER || $Math.pow(2, 53) - 1;","'use strict';\n\nvar GetIntrinsic = require('../GetIntrinsic');\n\nvar $Object = GetIntrinsic('%Object%');\n\nvar RequireObjectCoercible = require('./RequireObjectCoercible'); // https://www.ecma-international.org/ecma-262/6.0/#sec-toobject\n\n\nmodule.exports = function ToObject(value) {\n RequireObjectCoercible(value);\n return $Object(value);\n};","'use strict';\n\nvar $isNaN = require('../helpers/isNaN'); // https://www.ecma-international.org/ecma-262/6.0/#sec-samevaluezero\n\n\nmodule.exports = function SameValueZero(x, y) {\n return x === y || $isNaN(x) && $isNaN(y);\n};","'use strict';\n\nvar strValue = String.prototype.valueOf;\n\nvar tryStringObject = function tryStringObject(value) {\n try {\n strValue.call(value);\n return true;\n } catch (e) {\n return false;\n }\n};\n\nvar toStr = Object.prototype.toString;\nvar strClass = '[object String]';\nvar hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';\n\nmodule.exports = function isString(value) {\n if (typeof value === 'string') {\n return true;\n }\n\n if (typeof value !== 'object') {\n return false;\n }\n\n return hasToStringTag ? tryStringObject(value) : toStr.call(value) === strClass;\n};","'use strict';\n\nvar define = require('define-properties');\n\nvar getPolyfill = require('./polyfill');\n\nmodule.exports = function shimArrayPrototypeIncludes() {\n var polyfill = getPolyfill();\n define(Array.prototype, {\n includes: polyfill\n }, {\n includes: function includes() {\n return Array.prototype.includes !== polyfill;\n }\n });\n return polyfill;\n};","'use strict';\n\nvar bind = require('function-bind');\n\nmodule.exports = bind.call(Function.call, Object.prototype.hasOwnProperty);","'use strict';\n\nmodule.exports = require('../5/CheckObjectCoercible');","'use strict';\n\nvar getPolyfill = require('./polyfill');\n\nvar define = require('define-properties');\n\nmodule.exports = function shimValues() {\n var polyfill = getPolyfill();\n define(Object, {\n values: polyfill\n }, {\n values: function testValues() {\n return Object.values !== polyfill;\n }\n });\n return polyfill;\n};","'use strict';\n\nvar define = require('define-properties');\n\nvar getPolyfill = require('./polyfill');\n/* http://www.ecma-international.org/ecma-262/6.0/#sec-number.isnan */\n\n\nmodule.exports = function shimNumberIsNaN() {\n var polyfill = getPolyfill();\n define(Number, {\n isNaN: polyfill\n }, {\n isNaN: function testIsNaN() {\n return Number.isNaN !== polyfill;\n }\n });\n return polyfill;\n};","'use strict'; // http://www.ecma-international.org/ecma-262/5.1/#sec-9.11\n\nmodule.exports = require('is-callable');","'use strict';\n\nvar GetIntrinsic = require('../GetIntrinsic');\n\nvar $species = GetIntrinsic('%Symbol.species%', true);\nvar $TypeError = GetIntrinsic('%TypeError%');\n\nvar IsConstructor = require('./IsConstructor');\n\nvar Type = require('./Type'); // https://ecma-international.org/ecma-262/6.0/#sec-speciesconstructor\n\n\nmodule.exports = function SpeciesConstructor(O, defaultConstructor) {\n if (Type(O) !== 'Object') {\n throw new $TypeError('Assertion failed: Type(O) is not Object');\n }\n\n var C = O.constructor;\n\n if (typeof C === 'undefined') {\n return defaultConstructor;\n }\n\n if (Type(C) !== 'Object') {\n throw new $TypeError('O.constructor is not an Object');\n }\n\n var S = $species ? C[$species] : void 0;\n\n if (S == null) {\n return defaultConstructor;\n }\n\n if (IsConstructor(S)) {\n return S;\n }\n\n throw new $TypeError('no constructor found');\n};","'use strict';\n/* globals\n\tAtomics,\n\tSharedArrayBuffer,\n*/\n\nvar undefined;\nvar $TypeError = TypeError;\nvar $gOPD = Object.getOwnPropertyDescriptor;\n\nif ($gOPD) {\n try {\n $gOPD({}, '');\n } catch (e) {\n $gOPD = null; // this is IE 8, which has a broken gOPD\n }\n}\n\nvar throwTypeError = function throwTypeError() {\n throw new $TypeError();\n};\n\nvar ThrowTypeError = $gOPD ? function () {\n try {\n // eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties\n arguments.callee; // IE 8 does not throw here\n\n return throwTypeError;\n } catch (calleeThrows) {\n try {\n // IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')\n return $gOPD(arguments, 'callee').get;\n } catch (gOPDthrows) {\n return throwTypeError;\n }\n }\n}() : throwTypeError;\n\nvar hasSymbols = require('has-symbols')();\n\nvar getProto = Object.getPrototypeOf || function (x) {\n return x.__proto__;\n}; // eslint-disable-line no-proto\n\n\nvar generator; // = function * () {};\n\nvar generatorFunction = generator ? getProto(generator) : undefined;\nvar asyncFn; // async function() {};\n\nvar asyncFunction = asyncFn ? asyncFn.constructor : undefined;\nvar asyncGen; // async function * () {};\n\nvar asyncGenFunction = asyncGen ? getProto(asyncGen) : undefined;\nvar asyncGenIterator = asyncGen ? asyncGen() : undefined;\nvar TypedArray = typeof Uint8Array === 'undefined' ? undefined : getProto(Uint8Array);\nvar INTRINSICS = {\n '%Array%': Array,\n '%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,\n '%ArrayBufferPrototype%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer.prototype,\n '%ArrayIteratorPrototype%': hasSymbols ? getProto([][Symbol.iterator]()) : undefined,\n '%ArrayPrototype%': Array.prototype,\n '%ArrayProto_entries%': Array.prototype.entries,\n '%ArrayProto_forEach%': Array.prototype.forEach,\n '%ArrayProto_keys%': Array.prototype.keys,\n '%ArrayProto_values%': Array.prototype.values,\n '%AsyncFromSyncIteratorPrototype%': undefined,\n '%AsyncFunction%': asyncFunction,\n '%AsyncFunctionPrototype%': asyncFunction ? asyncFunction.prototype : undefined,\n '%AsyncGenerator%': asyncGen ? getProto(asyncGenIterator) : undefined,\n '%AsyncGeneratorFunction%': asyncGenFunction,\n '%AsyncGeneratorPrototype%': asyncGenFunction ? asyncGenFunction.prototype : undefined,\n '%AsyncIteratorPrototype%': asyncGenIterator && hasSymbols && Symbol.asyncIterator ? asyncGenIterator[Symbol.asyncIterator]() : undefined,\n '%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,\n '%Boolean%': Boolean,\n '%BooleanPrototype%': Boolean.prototype,\n '%DataView%': typeof DataView === 'undefined' ? undefined : DataView,\n '%DataViewPrototype%': typeof DataView === 'undefined' ? undefined : DataView.prototype,\n '%Date%': Date,\n '%DatePrototype%': Date.prototype,\n '%decodeURI%': decodeURI,\n '%decodeURIComponent%': decodeURIComponent,\n '%encodeURI%': encodeURI,\n '%encodeURIComponent%': encodeURIComponent,\n '%Error%': Error,\n '%ErrorPrototype%': Error.prototype,\n '%eval%': eval,\n // eslint-disable-line no-eval\n '%EvalError%': EvalError,\n '%EvalErrorPrototype%': EvalError.prototype,\n '%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,\n '%Float32ArrayPrototype%': typeof Float32Array === 'undefined' ? undefined : Float32Array.prototype,\n '%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,\n '%Float64ArrayPrototype%': typeof Float64Array === 'undefined' ? undefined : Float64Array.prototype,\n '%Function%': Function,\n '%FunctionPrototype%': Function.prototype,\n '%Generator%': generator ? getProto(generator()) : undefined,\n '%GeneratorFunction%': generatorFunction,\n '%GeneratorPrototype%': generatorFunction ? generatorFunction.prototype : undefined,\n '%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,\n '%Int8ArrayPrototype%': typeof Int8Array === 'undefined' ? undefined : Int8Array.prototype,\n '%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,\n '%Int16ArrayPrototype%': typeof Int16Array === 'undefined' ? undefined : Int8Array.prototype,\n '%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,\n '%Int32ArrayPrototype%': typeof Int32Array === 'undefined' ? undefined : Int32Array.prototype,\n '%isFinite%': isFinite,\n '%isNaN%': isNaN,\n '%IteratorPrototype%': hasSymbols ? getProto(getProto([][Symbol.iterator]())) : undefined,\n '%JSON%': typeof JSON === 'object' ? JSON : undefined,\n '%JSONParse%': typeof JSON === 'object' ? JSON.parse : undefined,\n '%Map%': typeof Map === 'undefined' ? undefined : Map,\n '%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols ? undefined : getProto(new Map()[Symbol.iterator]()),\n '%MapPrototype%': typeof Map === 'undefined' ? undefined : Map.prototype,\n '%Math%': Math,\n '%Number%': Number,\n '%NumberPrototype%': Number.prototype,\n '%Object%': Object,\n '%ObjectPrototype%': Object.prototype,\n '%ObjProto_toString%': Object.prototype.toString,\n '%ObjProto_valueOf%': Object.prototype.valueOf,\n '%parseFloat%': parseFloat,\n '%parseInt%': parseInt,\n '%Promise%': typeof Promise === 'undefined' ? undefined : Promise,\n '%PromisePrototype%': typeof Promise === 'undefined' ? undefined : Promise.prototype,\n '%PromiseProto_then%': typeof Promise === 'undefined' ? undefined : Promise.prototype.then,\n '%Promise_all%': typeof Promise === 'undefined' ? undefined : Promise.all,\n '%Promise_reject%': typeof Promise === 'undefined' ? undefined : Promise.reject,\n '%Promise_resolve%': typeof Promise === 'undefined' ? undefined : Promise.resolve,\n '%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,\n '%RangeError%': RangeError,\n '%RangeErrorPrototype%': RangeError.prototype,\n '%ReferenceError%': ReferenceError,\n '%ReferenceErrorPrototype%': ReferenceError.prototype,\n '%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,\n '%RegExp%': RegExp,\n '%RegExpPrototype%': RegExp.prototype,\n '%Set%': typeof Set === 'undefined' ? undefined : Set,\n '%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols ? undefined : getProto(new Set()[Symbol.iterator]()),\n '%SetPrototype%': typeof Set === 'undefined' ? undefined : Set.prototype,\n '%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,\n '%SharedArrayBufferPrototype%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer.prototype,\n '%String%': String,\n '%StringIteratorPrototype%': hasSymbols ? getProto(''[Symbol.iterator]()) : undefined,\n '%StringPrototype%': String.prototype,\n '%Symbol%': hasSymbols ? Symbol : undefined,\n '%SymbolPrototype%': hasSymbols ? Symbol.prototype : undefined,\n '%SyntaxError%': SyntaxError,\n '%SyntaxErrorPrototype%': SyntaxError.prototype,\n '%ThrowTypeError%': ThrowTypeError,\n '%TypedArray%': TypedArray,\n '%TypedArrayPrototype%': TypedArray ? TypedArray.prototype : undefined,\n '%TypeError%': $TypeError,\n '%TypeErrorPrototype%': $TypeError.prototype,\n '%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,\n '%Uint8ArrayPrototype%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array.prototype,\n '%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,\n '%Uint8ClampedArrayPrototype%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray.prototype,\n '%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,\n '%Uint16ArrayPrototype%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array.prototype,\n '%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,\n '%Uint32ArrayPrototype%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array.prototype,\n '%URIError%': URIError,\n '%URIErrorPrototype%': URIError.prototype,\n '%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,\n '%WeakMapPrototype%': typeof WeakMap === 'undefined' ? undefined : WeakMap.prototype,\n '%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet,\n '%WeakSetPrototype%': typeof WeakSet === 'undefined' ? undefined : WeakSet.prototype\n};\n\nvar bind = require('function-bind');\n\nvar $replace = bind.call(Function.call, String.prototype.replace);\n/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */\n\nvar rePropName = /[^%.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|%$))/g;\nvar reEscapeChar = /\\\\(\\\\)?/g;\n/** Used to match backslashes in property paths. */\n\nvar stringToPath = function stringToPath(string) {\n var result = [];\n $replace(string, rePropName, function (match, number, quote, subString) {\n result[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;\n });\n return result;\n};\n/* end adaptation */\n\n\nvar getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {\n if (!(name in INTRINSICS)) {\n throw new SyntaxError('intrinsic ' + name + ' does not exist!');\n } // istanbul ignore if // hopefully this is impossible to test :-)\n\n\n if (typeof INTRINSICS[name] === 'undefined' && !allowMissing) {\n throw new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');\n }\n\n return INTRINSICS[name];\n};\n\nmodule.exports = function GetIntrinsic(name, allowMissing) {\n if (typeof name !== 'string' || name.length === 0) {\n throw new TypeError('intrinsic name must be a non-empty string');\n }\n\n if (arguments.length > 1 && typeof allowMissing !== 'boolean') {\n throw new TypeError('\"allowMissing\" argument must be a boolean');\n }\n\n var parts = stringToPath(name);\n var value = getBaseIntrinsic('%' + (parts.length > 0 ? parts[0] : '') + '%', allowMissing);\n\n for (var i = 1; i < parts.length; i += 1) {\n if (value != null) {\n if ($gOPD && i + 1 >= parts.length) {\n var desc = $gOPD(value, parts[i]);\n\n if (!allowMissing && !(parts[i] in value)) {\n throw new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');\n }\n\n value = desc ? desc.get || desc.value : value[parts[i]];\n } else {\n value = value[parts[i]];\n }\n }\n }\n\n return value;\n};","'use strict'; // https://www.ecma-international.org/ecma-262/6.0/#sec-isconstructor\n\nmodule.exports = function IsConstructor(argument) {\n return typeof argument === 'function' && !!argument.prototype; // unfortunately there's no way to truly check this without try/catch `new argument`\n};","'use strict'; // https://www.ecma-international.org/ecma-262/5.1/#sec-8\n\nmodule.exports = function Type(x) {\n if (x === null) {\n return 'Null';\n }\n\n if (typeof x === 'undefined') {\n return 'Undefined';\n }\n\n if (typeof x === 'function' || typeof x === 'object') {\n return 'Object';\n }\n\n if (typeof x === 'number') {\n return 'Number';\n }\n\n if (typeof x === 'boolean') {\n return 'Boolean';\n }\n\n if (typeof x === 'string') {\n return 'String';\n }\n};","'use strict';\n\nvar requirePromise = require('./requirePromise');\n\nvar getPolyfill = require('./polyfill');\n\nvar define = require('define-properties');\n\nmodule.exports = function shimPromiseFinally() {\n requirePromise();\n var polyfill = getPolyfill();\n define(Promise.prototype, {\n 'finally': polyfill\n }, {\n 'finally': function testFinally() {\n return Promise.prototype['finally'] !== polyfill;\n }\n });\n return polyfill;\n};","export const decode = base64 => {\n const rawData = window.atob(base64);\n const outputArray = new Uint8Array(rawData.length);\n\n for (let i = 0; i < rawData.length; ++i) {\n outputArray[i] = rawData.charCodeAt(i);\n }\n\n return outputArray;\n};\n","import 'intl';\nimport 'intl/locale-data/jsonp/en';\nimport 'es6-symbol/implement';\nimport includes from 'array-includes';\nimport assign from 'object-assign';\nimport values from 'object.values';\nimport isNaN from 'is-nan';\nimport { decode as decodeBase64 } from './utils/base64';\nimport promiseFinally from 'promise.prototype.finally';\n\nif (!Array.prototype.includes) {\n includes.shim();\n}\n\nif (!Object.assign) {\n Object.assign = assign;\n}\n\nif (!Object.values) {\n values.shim();\n}\n\nif (!Number.isNaN) {\n Number.isNaN = isNaN;\n}\n\npromiseFinally.shim();\n\nif (!HTMLCanvasElement.prototype.toBlob) {\n const BASE64_MARKER = ';base64,';\n\n Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {\n value(callback, type = 'image/png', quality) {\n const dataURL = this.toDataURL(type, quality);\n let data;\n\n if (dataURL.indexOf(BASE64_MARKER) >= 0) {\n const [, base64] = dataURL.split(BASE64_MARKER);\n data = decodeBase64(base64);\n } else {\n [, data] = dataURL.split(',');\n }\n\n callback(new Blob([data], { type }));\n },\n });\n}\n","import 'intl';\nimport 'intl/locale-data/jsonp/en';\nimport 'es6-symbol/implement';\nimport includes from 'array-includes';\nimport assign from 'object-assign';\nimport values from 'object.values';\nimport isNaN from 'is-nan';\nimport { decode as decodeBase64 } from './base64';\nimport promiseFinally from 'promise.prototype.finally';\n\nif (!Array.prototype.includes) {\n includes.shim();\n}\n\nif (!Object.assign) {\n Object.assign = assign;\n}\n\nif (!Object.values) {\n values.shim();\n}\n\nif (!Number.isNaN) {\n Number.isNaN = isNaN;\n}\n\npromiseFinally.shim();\n\nif (!HTMLCanvasElement.prototype.toBlob) {\n const BASE64_MARKER = ';base64,';\n\n Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {\n value(callback, type = 'image/png', quality) {\n const dataURL = this.toDataURL(type, quality);\n let data;\n\n if (dataURL.indexOf(BASE64_MARKER) >= 0) {\n const [, base64] = dataURL.split(BASE64_MARKER);\n data = decodeBase64(base64);\n } else {\n [, data] = dataURL.split(',');\n }\n\n callback(new Blob([data], { type }));\n },\n });\n}\n","export const decode = base64 => {\n const rawData = window.atob(base64);\n const outputArray = new Uint8Array(rawData.length);\n\n for (let i = 0; i < rawData.length; ++i) {\n outputArray[i] = rawData.charCodeAt(i);\n }\n\n return outputArray;\n};\n","/*\nobject-assign\n(c) Sindre Sorhus\n@license MIT\n*/\n'use strict';\n/* eslint-disable no-unused-vars */\n\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\nfunction toObject(val) {\n if (val === null || val === undefined) {\n throw new TypeError('Object.assign cannot be called with null or undefined');\n }\n\n return Object(val);\n}\n\nfunction shouldUseNative() {\n try {\n if (!Object.assign) {\n return false;\n } // Detect buggy property enumeration order in older V8 versions.\n // https://bugs.chromium.org/p/v8/issues/detail?id=4118\n\n\n var test1 = new String('abc'); // eslint-disable-line no-new-wrappers\n\n test1[5] = 'de';\n\n if (Object.getOwnPropertyNames(test1)[0] === '5') {\n return false;\n } // https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\n\n var test2 = {};\n\n for (var i = 0; i < 10; i++) {\n test2['_' + String.fromCharCode(i)] = i;\n }\n\n var order2 = Object.getOwnPropertyNames(test2).map(function (n) {\n return test2[n];\n });\n\n if (order2.join('') !== '0123456789') {\n return false;\n } // https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\n\n var test3 = {};\n 'abcdefghijklmnopqrst'.split('').forEach(function (letter) {\n test3[letter] = letter;\n });\n\n if (Object.keys(Object.assign({}, test3)).join('') !== 'abcdefghijklmnopqrst') {\n return false;\n }\n\n return true;\n } catch (err) {\n // We don't expect any of the above to throw, but better to be safe.\n return false;\n }\n}\n\nmodule.exports = shouldUseNative() ? Object.assign : function (target, source) {\n var from;\n var to = toObject(target);\n var symbols;\n\n for (var s = 1; s < arguments.length; s++) {\n from = Object(arguments[s]);\n\n for (var key in from) {\n if (hasOwnProperty.call(from, key)) {\n to[key] = from[key];\n }\n }\n\n if (getOwnPropertySymbols) {\n symbols = getOwnPropertySymbols(from);\n\n for (var i = 0; i < symbols.length; i++) {\n if (propIsEnumerable.call(from, symbols[i])) {\n to[symbols[i]] = from[symbols[i]];\n }\n }\n }\n }\n\n return to;\n};"],"sourceRoot":""} \ No newline at end of file diff --git a/priv/static/packs/common.js b/priv/static/packs/common.js deleted file mode 100644 index 372dc3b82..000000000 --- a/priv/static/packs/common.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! For license information please see common.js.LICENSE.txt */ -(window.webpackJsonp=window.webpackJsonp||[]).push([[1],{1048:function(e,t,a){"use strict";a.d(t,"a",(function(){return B}));var i,r=a(0),n=a(2),o=(a(9),a(6),a(8)),s=a(1),u=a(54),l=a.n(u),g=a(3),c=a.n(g),_=a(472),f=a(5),d=a.n(f),h=a(15),m=a(772);var p=function(e){if("boolean"!=typeof i){var t=e.target.getBoundingClientRect(),a=e.boundingClientRect;i=t.height!==a.height||t.top!==a.top||t.width!==a.width||t.bottom!==a.bottom||t.left!==a.left||t.right!==a.right}return i?e.target.getBoundingClientRect():e.boundingClientRect};var F=["id","index","listLength","cachedHeight"],b=function(e){Object(o.a)(a,e);var t;t=a;function a(){for(var t,a=arguments.length,i=new Array(a),r=0;rt.getScrollHeight()-e-t.getClientHeight()&&t.props.onLoadMore&&t.props.hasMore&&!t.props.isLoading&&t.props.onLoadMore(),e<100&&t.props.onScrollToTop?t.props.onScrollToTop():t.props.onScroll&&t.props.onScroll(),t.lastScrollWasSynthetic||(t.scrollToTopOnMouseIdle=!1),t.lastScrollWasSynthetic=!1}}),150,{trailing:!0})),Object(s.a)(Object(n.a)(t),"mouseIdleTimer",null),Object(s.a)(Object(n.a)(t),"mouseMovedRecently",!1),Object(s.a)(Object(n.a)(t),"lastScrollWasSynthetic",!1),Object(s.a)(Object(n.a)(t),"scrollToTopOnMouseIdle",!1),Object(s.a)(Object(n.a)(t),"setScrollTop",(function(e){t.getScrollTop()!==e&&(t.lastScrollWasSynthetic=!0,t.props.bindToDocument?document.scrollingElement.scrollTop=e:t.node.scrollTop=e)})),Object(s.a)(Object(n.a)(t),"clearMouseIdleTimer",(function(){null!==t.mouseIdleTimer&&(clearTimeout(t.mouseIdleTimer),t.mouseIdleTimer=null)})),Object(s.a)(Object(n.a)(t),"handleMouseMove",l()((function(){t.clearMouseIdleTimer(),t.mouseIdleTimer=setTimeout(t.handleMouseIdle,S),t.mouseMovedRecently||0!==t.getScrollTop()||(t.scrollToTopOnMouseIdle=!0),t.mouseMovedRecently=!0}),S/2)),Object(s.a)(Object(n.a)(t),"handleWheel",l()((function(){t.scrollToTopOnMouseIdle=!1}),150,{trailing:!0})),Object(s.a)(Object(n.a)(t),"handleMouseIdle",(function(){t.scrollToTopOnMouseIdle&&t.setScrollTop(0),t.mouseMovedRecently=!1,t.scrollToTopOnMouseIdle=!1})),Object(s.a)(Object(n.a)(t),"getScrollPosition",(function(){return t.node&&(t.getScrollTop()>0||t.mouseMovedRecently)?{height:t.getScrollHeight(),top:t.getScrollTop()}:null})),Object(s.a)(Object(n.a)(t),"getScrollTop",(function(){return t.props.bindToDocument?document.scrollingElement.scrollTop:t.node.scrollTop})),Object(s.a)(Object(n.a)(t),"getScrollHeight",(function(){return t.props.bindToDocument?document.scrollingElement.scrollHeight:t.node.scrollHeight})),Object(s.a)(Object(n.a)(t),"getClientHeight",(function(){return t.props.bindToDocument?document.scrollingElement.clientHeight:t.node.clientHeight})),Object(s.a)(Object(n.a)(t),"updateScrollBottom",(function(e){var a=t.getScrollHeight()-e;t.setScrollTop(a)})),Object(s.a)(Object(n.a)(t),"cacheMediaWidth",(function(e){e&&t.state.cachedMediaWidth!=e&&t.setState({cachedMediaWidth:e})})),Object(s.a)(Object(n.a)(t),"onFullScreenChange",(function(){t.setState({fullscreen:Object(x.d)()})})),Object(s.a)(Object(n.a)(t),"setRef",(function(e){t.node=e})),Object(s.a)(Object(n.a)(t),"handleLoadMore",(function(e){e.preventDefault(),t.props.onLoadMore()})),Object(s.a)(Object(n.a)(t),"defaultShouldUpdateScroll",(function(e,t){var a=t.location;return!(((e||{}).location||{}).state||{}).mastodonModalOpen&&!(a.state&&a.state.mastodonModalOpen)})),Object(s.a)(Object(n.a)(t),"handleLoadPending",(function(e){e.preventDefault(),t.props.onLoadPending(),t.scrollToTopOnMouseIdle=!1,t.lastScrollWasSynthetic=!1,t.clearMouseIdleTimer(),t.mouseIdleTimer=setTimeout(t.handleMouseIdle,S),t.mouseMovedRecently=!0})),t}var i=a.prototype;return i.componentDidMount=function(){this.attachScrollListener(),this.attachIntersectionObserver(),Object(x.a)(this.onFullScreenChange),this.handleScroll()},i.getSnapshotBeforeUpdate=function(e,t){var a=c.a.Children.count(e.children)>0&&c.a.Children.count(e.children)0!=this.props.numPending>0||a&&(this.getScrollTop()>0||this.mouseMovedRecently)?this.getScrollHeight()-this.getScrollTop():null},i.componentDidUpdate=function(e,t,a){null!==a&&this.updateScrollBottom(a)},i.componentWillUnmount=function(){this.clearMouseIdleTimer(),this.detachScrollListener(),this.detachIntersectionObserver(),Object(x.b)(this.onFullScreenChange)},i.attachIntersectionObserver=function(){this.intersectionObserverWrapper.connect({root:this.node,rootMargin:"300% 0px"})},i.detachIntersectionObserver=function(){this.intersectionObserverWrapper.disconnect()},i.attachScrollListener=function(){this.props.bindToDocument?(document.addEventListener("scroll",this.handleScroll),document.addEventListener("wheel",this.handleWheel)):(this.node.addEventListener("scroll",this.handleScroll),this.node.addEventListener("wheel",this.handleWheel))},i.detachScrollListener=function(){this.props.bindToDocument?(document.removeEventListener("scroll",this.handleScroll),document.removeEventListener("wheel",this.handleWheel)):(this.node.removeEventListener("scroll",this.handleScroll),this.node.removeEventListener("wheel",this.handleWheel))},i.getFirstChildKey=function(e){var t=e.children,a=t;return t instanceof D.List?a=t.get(0):Array.isArray(t)&&(a=t[0]),a&&a.key},i.render=function(){var e=this,t=this.props,a=t.children,i=t.scrollKey,n=t.trackScroll,o=t.shouldUpdateScroll,s=t.showLoading,u=t.isLoading,l=t.hasMore,g=t.numPending,f=t.prepend,d=t.alwaysPrepend,h=t.emptyMessage,m=t.onLoadMore,p=this.state.fullscreen,F=c.a.Children.count(a),b=l&&m?Object(r.a)(k.a,{visible:!u,onClick:this.handleLoadMore}):null,v=g>0?Object(r.a)(w,{count:g,onClick:this.handleLoadPending}):null,j=null;return j=s?c.a.createElement("div",{className:"scrollable scrollable--flex",ref:this.setRef},Object(r.a)("div",{role:"feed",className:"item-list"},void 0,f),Object(r.a)("div",{className:"scrollable__append"},void 0,Object(r.a)(M.a,{}))):u||F>0||l||!h?c.a.createElement("div",{className:C()("scrollable",{fullscreen:p}),ref:this.setRef,onMouseMove:this.handleMouseMove},Object(r.a)("div",{role:"feed",className:"item-list"},void 0,f,v,c.a.Children.map(this.props.children,(function(t,a){return Object(r.a)(y,{id:t.key,index:a,listLength:F,intersectionObserverWrapper:e.intersectionObserverWrapper,saveHeightKey:n?e.context.router.route.location.key+":"+i:null},t.key,c.a.cloneElement(t,{getScrollPosition:e.getScrollPosition,updateScrollBottom:e.updateScrollBottom,cachedMediaWidth:e.state.cachedMediaWidth,cacheMediaWidth:e.cacheMediaWidth}))})),b)):c.a.createElement("div",{className:C()("scrollable scrollable--flex",{fullscreen:p}),ref:this.setRef},d&&f,Object(r.a)("div",{className:"empty-column-indicator"},void 0,h)),n?Object(r.a)(_.a,{scrollKey:i,shouldUpdateScroll:o||this.defaultShouldUpdateScroll},void 0,j):j},a}(g.PureComponent);Object(s.a)(B,"contextTypes",{router:d.a.object}),Object(s.a)(B,"defaultProps",{trackScroll:!0})},1049:function(e,t,a){"use strict";a.d(t,"a",(function(){return q}));var i,r=a(0),n=a(2),o=(a(9),a(6),a(8)),s=a(1),u=a(54),l=a.n(u),g=a(3),c=a.n(g),_=a(472),f=a(5),d=a.n(f),h=a(15),m=a(778);var p=function(e){if("boolean"!=typeof i){var t=e.target.getBoundingClientRect(),a=e.boundingClientRect;i=t.height!==a.height||t.top!==a.top||t.width!==a.width||t.bottom!==a.bottom||t.left!==a.left||t.right!==a.right}return i?e.target.getBoundingClientRect():e.boundingClientRect},F=a(4);var b=["id","index","listLength"],v=["id","index","listLength","cachedHeight"],y=function(e){Object(o.a)(a,e);var t;t=a;function a(){for(var t,a=arguments.length,i=new Array(a),r=0;rt.getScrollHeight()-e-t.getClientHeight()&&t.props.onLoadMore&&t.props.hasMore&&!t.props.isLoading&&t.props.onLoadMore(),e<100&&t.props.onScrollToTop?t.props.onScrollToTop():t.props.onScroll&&t.props.onScroll(),t.lastScrollWasSynthetic||(t.scrollToTopOnMouseIdle=!1),t.lastScrollWasSynthetic=!1}}),150,{trailing:!0})),Object(s.a)(Object(n.a)(t),"mouseIdleTimer",null),Object(s.a)(Object(n.a)(t),"mouseMovedRecently",!1),Object(s.a)(Object(n.a)(t),"lastScrollWasSynthetic",!1),Object(s.a)(Object(n.a)(t),"scrollToTopOnMouseIdle",!1),Object(s.a)(Object(n.a)(t),"_getScrollingElement",(function(){return t.props.bindToDocument?document.scrollingElement||document.body:t.node})),Object(s.a)(Object(n.a)(t),"setScrollTop",(function(e){t.getScrollTop()!==e&&(t.lastScrollWasSynthetic=!0,t._getScrollingElement().scrollTop=e)})),Object(s.a)(Object(n.a)(t),"clearMouseIdleTimer",(function(){null!==t.mouseIdleTimer&&(clearTimeout(t.mouseIdleTimer),t.mouseIdleTimer=null)})),Object(s.a)(Object(n.a)(t),"handleMouseMove",l()((function(){t.clearMouseIdleTimer(),t.mouseIdleTimer=setTimeout(t.handleMouseIdle,B),t.mouseMovedRecently||0!==t.getScrollTop()||(t.scrollToTopOnMouseIdle=!0),t.mouseMovedRecently=!0}),B/2)),Object(s.a)(Object(n.a)(t),"handleWheel",l()((function(){t.scrollToTopOnMouseIdle=!1}),150,{trailing:!0})),Object(s.a)(Object(n.a)(t),"handleMouseIdle",(function(){t.scrollToTopOnMouseIdle&&t.setScrollTop(0),t.mouseMovedRecently=!1,t.scrollToTopOnMouseIdle=!1})),Object(s.a)(Object(n.a)(t),"getScrollPosition",(function(){return t.node&&(t.getScrollTop()>0||t.mouseMovedRecently)?{height:t.getScrollHeight(),top:t.getScrollTop()}:null})),Object(s.a)(Object(n.a)(t),"getScrollTop",(function(){return t._getScrollingElement().scrollTop})),Object(s.a)(Object(n.a)(t),"getScrollHeight",(function(){return t._getScrollingElement().scrollHeight})),Object(s.a)(Object(n.a)(t),"getClientHeight",(function(){return t._getScrollingElement().clientHeight})),Object(s.a)(Object(n.a)(t),"updateScrollBottom",(function(e){var a=t.getScrollHeight()-e;t.setScrollTop(a)})),Object(s.a)(Object(n.a)(t),"cacheMediaWidth",(function(e){e&&t.state.cachedMediaWidth!==e&&t.setState({cachedMediaWidth:e})})),Object(s.a)(Object(n.a)(t),"onFullScreenChange",(function(){t.setState({fullscreen:Object(M.d)()})})),Object(s.a)(Object(n.a)(t),"setRef",(function(e){t.node=e})),Object(s.a)(Object(n.a)(t),"handleLoadMore",(function(e){e.preventDefault(),t.props.onLoadMore()})),Object(s.a)(Object(n.a)(t),"handleLoadPending",(function(e){e.preventDefault(),t.props.onLoadPending(),t.scrollToTopOnMouseIdle=!1,t.lastScrollWasSynthetic=!1,t.clearMouseIdleTimer(),t.mouseIdleTimer=setTimeout(t.handleMouseIdle,B),t.mouseMovedRecently=!0})),t}var i=a.prototype;return i.componentDidMount=function(){this.attachScrollListener(),this.attachIntersectionObserver(),Object(M.a)(this.onFullScreenChange),this.handleScroll()},i.getSnapshotBeforeUpdate=function(e){var t=c.a.Children.count(e.children)>0&&c.a.Children.count(e.children)0!=this.props.numPending>0||t&&(this.getScrollTop()>0||this.mouseMovedRecently)?this.getScrollHeight()-this.getScrollTop():null},i.componentDidUpdate=function(e,t,a){null!==a&&this.setScrollTop(this.getScrollHeight()-a)},i.componentWillUnmount=function(){this.clearMouseIdleTimer(),this.detachScrollListener(),this.detachIntersectionObserver(),Object(M.b)(this.onFullScreenChange)},i.attachIntersectionObserver=function(){var e={root:this.node,rootMargin:"300% 0px"};this.intersectionObserverWrapper.connect(this.props.bindToDocument?{}:e)},i.detachIntersectionObserver=function(){this.intersectionObserverWrapper.disconnect()},i.attachScrollListener=function(){this.props.bindToDocument?(document.addEventListener("scroll",this.handleScroll),document.addEventListener("wheel",this.handleWheel)):(this.node.addEventListener("scroll",this.handleScroll),this.node.addEventListener("wheel",this.handleWheel))},i.detachScrollListener=function(){this.props.bindToDocument?(document.removeEventListener("scroll",this.handleScroll),document.removeEventListener("wheel",this.handleWheel)):(this.node.removeEventListener("scroll",this.handleScroll),this.node.removeEventListener("wheel",this.handleWheel))},i.getFirstChildKey=function(e){var t=e.children,a=t;return t instanceof F.List?a=t.get(0):Array.isArray(t)&&(a=t[0]),a&&a.key},i.render=function(){var e=this,t=this.props,a=t.children,i=t.scrollKey,n=t.trackScroll,o=t.shouldUpdateScroll,s=t.showLoading,u=t.isLoading,l=t.hasMore,g=t.numPending,f=t.prepend,d=t.alwaysPrepend,h=t.emptyMessage,m=t.onLoadMore,p=this.state.fullscreen,F=c.a.Children.count(a),b=l&&m?Object(r.a)(w.a,{visible:!u,onClick:this.handleLoadMore}):null,v=g>0?Object(r.a)(D,{count:g,onClick:this.handleLoadPending}):null,y=null;return y=s?c.a.createElement("div",{className:"scrollable scrollable--flex",ref:this.setRef},Object(r.a)("div",{role:"feed",className:"item-list"},void 0,f),Object(r.a)("div",{className:"scrollable__append"},void 0,Object(r.a)(S.a,{}))):u||F>0||g>0||l||!h?c.a.createElement("div",{className:x()("scrollable",{fullscreen:p}),ref:this.setRef,onMouseMove:this.handleMouseMove},Object(r.a)("div",{role:"feed",className:"item-list"},void 0,f,v,c.a.Children.map(this.props.children,(function(t,a){return Object(r.a)(j,{id:t.key,index:a,listLength:F,intersectionObserverWrapper:e.intersectionObserverWrapper,saveHeightKey:n?e.context.router.route.location.key+":"+i:null},t.key,c.a.cloneElement(t,{getScrollPosition:e.getScrollPosition,updateScrollBottom:e.updateScrollBottom,cachedMediaWidth:e.state.cachedMediaWidth,cacheMediaWidth:e.cacheMediaWidth}))})),b)):c.a.createElement("div",{className:x()("scrollable scrollable--flex",{fullscreen:p}),ref:this.setRef},d&&f,Object(r.a)("div",{className:"empty-column-indicator"},void 0,h)),n?Object(r.a)(_.a,{scrollKey:i,shouldUpdateScroll:o},void 0,y):y},a}(g.PureComponent);Object(s.a)(q,"contextTypes",{router:d.a.object}),Object(s.a)(q,"defaultProps",{trackScroll:!0})},1052:function(e,t,a){"use strict";t.__esModule=!0,t.default=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}},1053:function(e,t,a){"use strict";var i,r,n,o=a(0),s=a(3),u=a(15),l=a(7),g=a(210),c=a(2),_=(a(9),a(6),a(8)),f=a(1),d=a(16),h=a.n(d),m=a(5),p=a.n(m),F=a(115),b=a(122),v=a(300),y=a(53),k=a(21),j=a(22);var w=Object(l.f)({follow:{id:"account.follow",defaultMessage:"Follow"},unfollow:{id:"account.unfollow",defaultMessage:"Unfollow"},requested:{id:"account.requested",defaultMessage:"Awaiting approval"},unblock:{id:"account.unblock",defaultMessage:"Unblock @{name}"},unmute:{id:"account.unmute",defaultMessage:"Unmute @{name}"},mute_notifications:{id:"account.mute_notifications",defaultMessage:"Mute notifications from @{name}"},unmute_notifications:{id:"account.unmute_notifications",defaultMessage:"Unmute notifications from @{name}"}}),O=Object(l.g)((n=r=function(e){Object(_.a)(a,e);var t;t=a;function a(){for(var t,a=arguments.length,i=new Array(a),r=0;r0?t.props.statusIds.last():void 0)}),300,{leading:!0})),Object(u.a)(Object(o.a)(t),"setRef",(function(e){t.node=e})),t}var l=a.prototype;return l._selectChild=function(e,t){var a=this.node.node,i=a.querySelector("article:nth-of-type("+(e+1)+") .focusable");i&&(t&&a.scrollTop>i.offsetTop?i.scrollIntoView(!0):!t&&a.scrollTop+a.clientHeight0?a.map((function(t,i){return null===t?Object(r.a)(b.a,{disabled:g,maxId:i>0?a.get(i-1):null,onClick:s},"gap:"+a.get(i+1)):Object(r.a)(p.a,{id:t,onMoveUp:e.handleMoveUp,onMoveDown:e.handleMoveDown,contextType:u},t)})):null;return c&&o&&(c=o.map((function(t){return Object(r.a)(p.a,{id:t,featured:!0,onMoveUp:e.handleMoveUp,onMoveDown:e.handleMoveDown,contextType:u},"f-"+t)})).concat(c)),_.a.createElement(v.a,Object(i.default)({},l,{showLoading:g&&0===a.size,onLoadMore:s&&this.handleLoadOlder,ref:this.setRef}),c)},a}(F.a);Object(u.a)(j,"propTypes",{scrollKey:m.a.string.isRequired,statusIds:d.a.list.isRequired,featuredStatusIds:d.a.list,onLoadMore:m.a.func,onScrollToTop:m.a.func,onScroll:m.a.func,trackScroll:m.a.bool,shouldUpdateScroll:m.a.func,isLoading:m.a.bool,isPartial:m.a.bool,hasMore:m.a.bool,prepend:m.a.node,alwaysPrepend:m.a.bool,emptyMessage:m.a.node,timelineId:m.a.string.isRequired}),Object(u.a)(j,"defaultProps",{trackScroll:!0})},1065:function(e,t,a){"use strict";a.d(t,"a",(function(){return j}));var i=a(10),r=a(0),n=a(32),o=a(2),s=(a(9),a(6),a(8)),u=a(1),l=a(65),g=a.n(l),c=a(3),_=a.n(c),f=a(16),d=a.n(f),h=a(5),m=a.n(h),p=a(1080),F=a(21),b=a(1171),v=a(1049),y=a(7),k=function(){return Object(r.a)("div",{className:"regeneration-indicator"},void 0,Object(r.a)("div",{className:"regeneration-indicator__label"},void 0,Object(r.a)(y.b,{id:"regeneration_indicator.label",tagName:"strong",defaultMessage:"Loading…"}),Object(r.a)(y.b,{id:"regeneration_indicator.sublabel",defaultMessage:"Your home feed is being prepared!"})))};var j=function(e){Object(s.a)(a,e);var t;t=a;function a(){for(var t,a=arguments.length,i=new Array(a),r=0;r0?t.props.statusIds.last():void 0)}),300,{leading:!0})),Object(u.a)(Object(o.a)(t),"setRef",(function(e){t.node=e})),t}var l=a.prototype;return l._selectChild=function(e,t){var a=this.node.node,i=a.querySelector("article:nth-of-type("+(e+1)+") .focusable");i&&(t&&a.scrollTop>i.offsetTop?i.scrollIntoView(!0):!t&&a.scrollTop+a.clientHeight0?a.map((function(t,i){return null===t?Object(r.a)(b.a,{disabled:c,maxId:i>0?a.get(i-1):null,onClick:u},"gap:"+a.get(i+1)):Object(r.a)(p.a,{id:t,onMoveUp:e.handleMoveUp,onMoveDown:e.handleMoveDown,contextType:l,showThread:!0},t)})):null;return f&&o&&(f=o.map((function(t){return Object(r.a)(p.a,{id:t,featured:!0,onMoveUp:e.handleMoveUp,onMoveDown:e.handleMoveDown,contextType:l,showThread:!0},"f-"+t)})).concat(f)),_.a.createElement(v.a,Object(i.default)({},g,{showLoading:c&&0===a.size,onLoadMore:u&&this.handleLoadOlder,shouldUpdateScroll:s,ref:this.setRef}),f)},a}(F.a);Object(u.a)(j,"propTypes",{scrollKey:m.a.string.isRequired,statusIds:d.a.list.isRequired,featuredStatusIds:d.a.list,onLoadMore:m.a.func,onScrollToTop:m.a.func,onScroll:m.a.func,trackScroll:m.a.bool,shouldUpdateScroll:m.a.func,isLoading:m.a.bool,isPartial:m.a.bool,hasMore:m.a.bool,prepend:m.a.node,emptyMessage:m.a.node,alwaysPrepend:m.a.bool,timelineId:m.a.string}),Object(u.a)(j,"defaultProps",{trackScroll:!0})},1066:function(e,t,a){"use strict";a.d(t,"b",(function(){return _})),a.d(t,"c",(function(){return c})),a.d(t,"d",(function(){return d})),a.d(t,"a",(function(){return h})),a.d(t,"f",(function(){return g})),a.d(t,"e",(function(){return m}));var i=a(1268),r=a.n(i),n=a(1076),o=String.fromCodePoint||function(){var e,t,a=16384,i=[],r=-1,n=arguments.length;if(!n)return"";for(var o="";++r1114111||Math.floor(s)!=s)throw RangeError("Invalid code point: "+s);s<=65535?i.push(s):(e=55296+((s-=65536)>>10),t=s%1024+56320,i.push(e,t)),(r+1===n||i.length>a)&&(o+=String.fromCharCode.apply(null,i),i.length=0)}return o},s=JSON,u=/^(?:\:([^\:]+)\:)(?:\:skin-tone-(\d)\:)?$/,l=["1F3FA","1F3FB","1F3FC","1F3FD","1F3FE","1F3FF"];function g(e){var t=e.split("-").map((function(e){return"0x"+e}));return o.apply(null,t)}function c(){return e=_.apply(void 0,arguments),t=e.name,a=e.short_names,i=e.skin_tone,r=e.skin_variations,n=e.emoticons,o=e.unified,s=e.custom,u=e.customCategory,l=e.imageUrl,c=e.id||a[0],f=":"+c+":",s?{id:c,name:t,colons:f,emoticons:n,custom:s,customCategory:u,imageUrl:l}:(i&&(f+=":skin-tone-"+i+":"),{id:c,name:t,colons:f,emoticons:n,unified:o.toLowerCase(),skin:i||(r?1:null),native:g(o)});var e,t,a,i,r,n,o,s,u,l,c,f}function _(e,t,a,i){var o={};if("string"==typeof e){var g=e.match(u);if(g&&(e=g[1],g[2]&&(t=parseInt(g[2],10))),i.aliases.hasOwnProperty(e)&&(e=i.aliases[e]),!i.emojis.hasOwnProperty(e))return null;o=i.emojis[e]}else e.id&&(i.aliases.hasOwnProperty(e.id)&&(e.id=i.aliases[e.id]),i.emojis.hasOwnProperty(e.id)&&(o=i.emojis[e.id],t||(t=e.skin)));if(r()(o).length||((o=e).custom=!0,o.search||(o.search=Object(n.buildSearch)(e))),o.emoticons||(o.emoticons=[]),o.variations||(o.variations=[]),o.skin_variations&&t>1&&a){o=JSON.parse(s.stringify(o));var c=l[t-1],_=o.skin_variations[c];if(!_.variations&&o.variations&&delete o.variations,null==_["has_img_"+a]||_["has_img_"+a])for(var f in o.skin_tone=t,_){var d=_[f];o[f]=d}}return o.variations&&o.variations.length&&((o=JSON.parse(s.stringify(o))).unified=o.variations.shift()),o}function f(e){return e.reduce((function(e,t){return-1===e.indexOf(t)&&e.push(t),e}),[])}function d(e,t){var a=f(e),i=f(t);return a.filter((function(e){return i.indexOf(e)>=0}))}function h(e,t){var a={};for(var i in e){var r=e[i],n=r;t.hasOwnProperty(i)&&(n=t[i]),"object"==typeof n&&(n=h(r,n)),a[i]=n}return a}function m(){if("undefined"==typeof document)return 0;var e=document.createElement("div");e.style.width="100px",e.style.height="100px",e.style.overflow="scroll",e.style.position="absolute",e.style.top="-9999px",document.body.appendChild(e);var t=e.offsetWidth-e.clientWidth;return document.body.removeChild(e),t}},1070:function(e,t,a){var i=a(1062),r=a(1054),n=a(1137),o=a(1071),s=a(1075),u=function e(t,a,u){var l,g,c,_=t&e.F,f=t&e.G,d=t&e.S,h=t&e.P,m=t&e.B,p=t&e.W,F=f?r:r[a]||(r[a]={}),b=F.prototype,v=f?i:d?i[a]:(i[a]||{}).prototype;for(l in f&&(u=a),u)(g=!_&&v&&void 0!==v[l])&&s(F,l)||(c=g?v[l]:u[l],F[l]=f&&"function"!=typeof v[l]?u[l]:m&&g?n(c,i):p&&v[l]==c?function(e){var t=function(t,a,i){if(this instanceof e){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,a)}return new e(t,a,i)}return e.apply(this,arguments)};return t.prototype=e.prototype,t}(c):h&&"function"==typeof c?n(Function.call,c):c,h&&((F.virtual||(F.virtual={}))[l]=c,t&e.R&&b&&!b[l]&&o(b,l,c)))};u.F=1,u.G=2,u.S=4,u.P=8,u.B=16,u.W=32,u.U=64,u.R=128,e.exports=u},1071:function(e,t,a){var i=a(1072),r=a(1092);e.exports=a(1074)?function(e,t,a){return i.f(e,t,r(1,a))}:function(e,t,a){return e[t]=a,e}},1072:function(e,t,a){var i=a(1073),r=a(1240),n=a(1241),o=Object.defineProperty;t.f=a(1074)?Object.defineProperty:function(e,t,a){if(i(e),t=n(t,!0),i(a),r)try{return o(e,t,a)}catch(e){}if("get"in a||"set"in a)throw TypeError("Accessors not supported!");return"value"in a&&(e[t]=a.value),e}},1073:function(e,t,a){var i=a(1090);e.exports=function(e){if(!i(e))throw TypeError(e+" is not an object!");return e}},1074:function(e,t,a){e.exports=!a(1091)((function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}))},1075:function(e,t){var a={}.hasOwnProperty;e.exports=function(e,t){return a.call(e,t)}},1076:function(e,t){var a={name:"a",unified:"b",non_qualified:"c",has_img_apple:"d",has_img_google:"e",has_img_twitter:"f",has_img_emojione:"g",has_img_facebook:"h",has_img_messenger:"i",keywords:"j",sheet:"k",emoticons:"l",text:"m",short_names:"n",added_in:"o"},i=function(e){var t=[],a=function(e,a){e&&(Array.isArray(e)?e:[e]).forEach((function(e){(a?e.split(/[-|_|\s]+/):[e]).forEach((function(e){e=e.toLowerCase(),-1==t.indexOf(e)&&t.push(e)}))}))};return a(e.short_names,!0),a(e.name,!0),a(e.keywords,!1),a(e.emoticons,!1),t.join(",")};e.exports={buildSearch:i,compress:function(e){for(var t in e.short_names=e.short_names.filter((function(t){return t!==e.short_name})),delete e.short_name,e.sheet=[e.sheet_x,e.sheet_y],delete e.sheet_x,delete e.sheet_y,e.added_in=parseInt(e.added_in),6===e.added_in&&delete e.added_in,a)e[a[t]]=e[t],delete e[t];for(var i in e){var r=e[i];Array.isArray(r)&&!r.length?delete e[i]:"string"!=typeof r||r.length?null===r&&delete e[i]:delete e[i]}},uncompress:function(e){for(var t in e.compressed=!1,e.emojis){var r=e.emojis[t];for(var n in a)r[n]=r[a[n]],delete r[a[n]];r.short_names||(r.short_names=[]),r.short_names.unshift(t),r.sheet_x=r.sheet[0],r.sheet_y=r.sheet[1],delete r.sheet,r.text||(r.text=""),r.added_in||(r.added_in=6),r.added_in=r.added_in.toFixed(1),r.search=i(r)}}}},1077:function(e,t,a){"use strict";a.d(t,"b",(function(){return n})),a.d(t,"a",(function(){return o})),a.d(t,"c",(function(){return s}));var i=a(5),r=a.n(i),n={data:r.a.object.isRequired,onOver:r.a.func,onLeave:r.a.func,onClick:r.a.func,fallback:r.a.func,backgroundImageFn:r.a.func,native:r.a.bool,forceSize:r.a.bool,tooltip:r.a.bool,skin:r.a.oneOf([1,2,3,4,5,6]),sheetSize:r.a.oneOf([16,20,32,64]),set:r.a.oneOf(["apple","google","twitter","emojione","messenger","facebook"]),size:r.a.number.isRequired,emoji:r.a.oneOfType([r.a.string,r.a.object]).isRequired},o={skin:1,set:"apple",sheetSize:64,native:!1,forceSize:!1,tooltip:!1,backgroundImageFn:function(e,t){return"https://unpkg.com/emoji-datasource-"+e+"@4.0.4/img/"+e+"/sheets-256/"+t+".png"},onOver:function(){},onLeave:function(){},onClick:function(){}},s=(r.a.func,r.a.func,r.a.func,r.a.number,r.a.number,r.a.object,r.a.object,r.a.string,r.a.string,r.a.string,n.set,n.skin,r.a.bool,n.backgroundImageFn,n.sheetSize,r.a.func,r.a.bool,r.a.bool,n.tooltip,r.a.arrayOf(r.a.string),r.a.arrayOf(r.a.string),r.a.arrayOf(r.a.string),r.a.bool,r.a.arrayOf(r.a.shape({name:r.a.string.isRequired,short_names:r.a.arrayOf(r.a.string).isRequired,emoticons:r.a.arrayOf(r.a.string),keywords:r.a.arrayOf(r.a.string),imageUrl:r.a.string.isRequired})),{onClick:function(){},onSelect:function(){},onSkinChange:function(){},emojiSize:24,perLine:9,i18n:{},style:{},title:"Emoji Mart™",emoji:"department_store",color:"#ae65c5",set:o.set,skin:null,defaultSkin:o.skin,native:o.native,sheetSize:o.sheetSize,backgroundImageFn:o.backgroundImageFn,emojisToShowFilter:null,showPreview:!0,showSkinTones:!0,emojiTooltip:o.tooltip,autoFocus:!1,custom:[]})},1078:function(e,t,a){"use strict";a.d(t,"a",(function(){return l}));var i=a(0),r=(a(9),a(6),a(8)),n=a(1),o=a(3),s=a.n(o),u=a(7);var l=function(e){Object(r.a)(a,e);var t;t=a;function a(){return e.apply(this,arguments)||this}return a.prototype.render=function(){var e=this.props,t=e.disabled,a=e.visible;return(Object(i.a)("button",{className:"load-more",disabled:t||!a,style:{visibility:a?"visible":"hidden"},onClick:this.props.onClick},void 0,Object(i.a)(u.b,{id:"status.load_more",defaultMessage:"Load more"})))},a}(s.a.PureComponent);Object(n.a)(l,"defaultProps",{visible:!0})},1079:function(e,t,a){"use strict";a.d(t,"a",(function(){return c}));var i,r=a(0),n=(a(9),a(6),a(8)),o=a(3),s=a.n(o),u=a(758),l=a(7);var g=Object(l.f)({profile:{id:"column_header.profile",defaultMessage:"Profile"}}),c=Object(l.g)(i=function(e){Object(n.a)(a,e);var t;t=a;function a(){return e.apply(this,arguments)||this}return a.prototype.render=function(){var e=this.props,t=e.onClick,a=e.intl,i=e.multiColumn;return(Object(r.a)(u.a,{icon:"user-circle",title:a.formatMessage(g.profile),onClick:t,showBackButton:!0,multiColumn:i}))},a}(s.a.PureComponent))||i},1080:function(e,t,a){"use strict";var i=a(0),r=(a(3),a(15)),n=a(871),o=a(210),s=a(23),u=a(46),l=a(89),g=a(26),c=a(84),_=a(212),f=a(230),d=a(105),h=a(48),m=a(7),p=a(22),F=a(60),b=Object(m.f)({deleteConfirm:{id:"confirmations.delete.confirm",defaultMessage:"Delete"},deleteMessage:{id:"confirmations.delete.message",defaultMessage:"Are you sure you want to delete this status?"},redraftConfirm:{id:"confirmations.redraft.confirm",defaultMessage:"Delete & redraft"},redraftMessage:{id:"confirmations.redraft.message",defaultMessage:"Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned."},replyConfirm:{id:"confirmations.reply.confirm",defaultMessage:"Reply"},replyMessage:{id:"confirmations.reply.message",defaultMessage:"Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?"},blockDomainConfirm:{id:"confirmations.domain_block.confirm",defaultMessage:"Hide entire domain"}});t.a=Object(m.g)(Object(r.connect)((function(){var e=Object(o.f)();return function(t,a){return{status:e(t,a)}}}),(function(e,t){var a=t.intl;return{onReply:function(t,i){e((function(r,n){0!==n().getIn(["compose","text"]).trim().length?e(Object(h.d)("CONFIRM",{message:a.formatMessage(b.replyMessage),confirm:a.formatMessage(b.replyConfirm),onConfirm:function(){return e(Object(s.gb)(t,i))}})):e(Object(s.gb)(t,i))}))},onModalReblog:function(t){t.get("reblogged")?e(Object(u.x)(t)):e(Object(u.t)(t))},onReblog:function(t,a){a&&a.shiftKey||!p.b?this.onModalReblog(t):e(Object(h.d)("BOOST",{status:t,onReblog:this.onModalReblog}))},onFavourite:function(t){t.get("favourited")?e(Object(u.v)(t)):e(Object(u.p)(t))},onBookmark:function(t){t.get("bookmarked")?e(Object(u.u)(t)):e(Object(u.o)(t))},onPin:function(t){t.get("pinned")?e(Object(u.w)(t)):e(Object(u.s)(t))},onEmbed:function(t){e(Object(h.d)("EMBED",{url:t.get("url"),onError:function(t){return e(Object(F.f)(t))}}))},onDelete:function(t,i,r){void 0===r&&(r=!1),p.e?e(Object(h.d)("CONFIRM",{message:a.formatMessage(r?b.redraftMessage:b.deleteMessage),confirm:a.formatMessage(r?b.redraftConfirm:b.deleteConfirm),onConfirm:function(){return e(Object(l.h)(t.get("id"),i,r))}})):e(Object(l.h)(t.get("id"),i,r))},onDirect:function(t,a){e(Object(s.X)(t,a))},onMention:function(t,a){e(Object(s.cb)(t,a))},onOpenMedia:function(t,a){e(Object(h.d)("MEDIA",{media:t,index:a}))},onOpenVideo:function(t,a){e(Object(h.d)("VIDEO",{media:t,time:a}))},onBlock:function(t){var a=t.get("account");e(Object(f.f)(a))},onUnblock:function(t){e(Object(g.J)(t.get("id")))},onReport:function(t){e(Object(d.k)(t.get("account"),t))},onMute:function(t){e(Object(_.g)(t))},onUnmute:function(t){e(Object(g.L)(t.get("id")))},onMuteConversation:function(t){t.get("muted")?e(Object(l.n)(t.get("id"))):e(Object(l.k)(t.get("id")))},onToggleHidden:function(t){t.get("hidden")?e(Object(l.l)(t.get("id"))):e(Object(l.j)(t.get("id")))},onToggleCollapsed:function(t,a){e(Object(l.m)(t.get("id"),a))},onBlockDomain:function(t){e(Object(h.d)("CONFIRM",{message:Object(i.a)(m.b,{id:"confirmations.domain_block.message",defaultMessage:"Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",values:{domain:Object(i.a)("strong",{},void 0,t)}}),confirm:a.formatMessage(b.blockDomainConfirm),onConfirm:function(){return e(Object(c.e)(t))}}))},onUnblockDomain:function(t){e(Object(c.h)(t))}}}))(n.a))},1081:function(e,t,a){"use strict";a.d(t,"a",(function(){return l}));var i=a(0),r=(a(9),a(6),a(8)),n=a(1),o=a(3),s=a.n(o),u=a(7);var l=function(e){Object(r.a)(a,e);var t;t=a;function a(){return e.apply(this,arguments)||this}return a.prototype.render=function(){var e=this.props,t=e.disabled,a=e.visible;return(Object(i.a)("button",{className:"load-more",disabled:t||!a,style:{visibility:a?"visible":"hidden"},onClick:this.props.onClick},void 0,Object(i.a)(u.b,{id:"status.load_more",defaultMessage:"Load more"})))},a}(s.a.PureComponent);Object(n.a)(l,"defaultProps",{visible:!0})},1082:function(e,t,a){"use strict";var i=a(1061),r=Object.getPrototypeOf||function(e){return"function"==typeof(e=Object(e)).constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?Object.prototype:null},n=a(1052),o=a.n(n),s=Object,u=function(){function e(e,t){for(var a=0;a',custom:'',flags:'',foods:'',nature:'',objects:'',people:'',places:'',recent:'',symbols:''},P=function(e){function t(e){o()(this,t);var a=l(this,(t.__proto__||r(t)).call(this,e)),i=e.categories.filter((function(e){return e.first}))[0];return a.state={selected:i.name},a.handleClick=a.handleClick.bind(a),a}return c(t,e),u(t,[{key:"getSVG",value:function(e){if(this.SVGs||(this.SVGs={}),this.SVGs[e])return this.SVGs[e];var t='\n '+T[e]+"\n ";return this.SVGs[e]=t,t}},{key:"handleClick",value:function(e){var t=e.currentTarget.getAttribute("data-index"),a=this.props,i=a.categories;(0,a.onAnchorClick)(i[t],t)}},{key:"render",value:function(){var e=this,t=this.props,a=t.categories,i=(t.onAnchorClick,t.color),r=t.i18n,n=this.state.selected;return f.a.createElement("div",{className:"emoji-mart-anchors"},a.map((function(t,a){var o=t.id,s=t.name,u=t.anchor,l=s==n;if(!1===u)return null;var g=o.startsWith("custom-")?"custom":o;return f.a.createElement("span",{key:o,title:r.categories[o],"data-index":a,onClick:e.handleClick,className:"emoji-mart-anchor "+(l?"emoji-mart-anchor-selected":""),style:{color:l?i:null}},f.a.createElement("div",{dangerouslySetInnerHTML:{__html:e.getSVG(g)}}),f.a.createElement("span",{className:"emoji-mart-anchor-bar",style:{backgroundColor:i}}))})))}}]),t}(f.a.PureComponent),R=P;P.defaultProps={categories:[],onAnchorClick:function(){}};var I=function(e){function t(e){o()(this,t);var a=l(this,(t.__proto__||r(t)).call(this,e));return a.data=e.data,a.setContainerRef=a.setContainerRef.bind(a),a.setLabelRef=a.setLabelRef.bind(a),a}return c(t,e),u(t,[{key:"componentDidMount",value:function(){this.parent=this.container.parentNode,this.margin=0,this.minMargin=0,this.memoizeSize()}},{key:"shouldComponentUpdate",value:function(e,t){var a=this.props,i=a.name,r=a.perLine,n=a.native,o=a.hasStickyPosition,s=a.emojis,u=a.emojiProps,l=u.skin,g=u.size,c=u.set,_=e.perLine,f=e.native,d=e.hasStickyPosition,h=e.emojis,m=e.emojiProps,p=m.skin,F=m.size,b=m.set,v=!1;return"Recent"==i&&r!=_&&(v=!0),"Search"==i&&(v=!(s==h)),l==p&&g==F&&n==f&&c==b&&o==d||(v=!0),v}},{key:"memoizeSize",value:function(){var e=this.container.getBoundingClientRect(),t=e.top,a=e.height,i=this.parent.getBoundingClientRect().top,r=this.label.getBoundingClientRect().height;this.top=t-i+this.parent.scrollTop,this.maxMargin=0==a?0:a-r}},{key:"handleScroll",value:function(e){var t=e-this.top;if((t=(t=tthis.maxMargin?this.maxMargin:t)!=this.margin)return this.props.hasStickyPosition||(this.label.style.top=t+"px"),this.margin=t,!0}},{key:"getEmojis",value:function(){var e=this,t=this.props,a=t.name,i=t.emojis,r=t.recent,n=t.perLine;if("Recent"==a){var o=this.props.custom,s=r||S.get(n);if(s.length&&(i=s.map((function(e){var t=o.filter((function(t){return t.id===e}))[0];return t||e})).filter((function(t){return!!Object(B.b)(t,null,null,e.data)}))),0===i.length&&s.length>0)return null}return i&&(i=i.slice(0)),i}},{key:"updateDisplay",value:function(e){this.getEmojis()&&(this.container.style.display=e)}},{key:"setContainerRef",value:function(e){this.container=e}},{key:"setLabelRef",value:function(e){this.label=e}},{key:"render",value:function(){var e=this,t=this.props,a=t.id,r=t.name,n=t.hasStickyPosition,o=t.emojiProps,s=t.i18n,u=this.getEmojis(),l={},g={},c={};u||(c={display:"none"}),n||(l={height:28},g={position:"absolute"});var _=s.categories[a]||r;return f.a.createElement("div",{ref:this.setContainerRef,className:"emoji-mart-category "+(u&&!u.length?"emoji-mart-no-results":""),style:c},f.a.createElement("div",{style:l,"data-name":r,className:"emoji-mart-category-label"},f.a.createElement("span",{style:g,ref:this.setLabelRef},_)),u&&u.map((function(t){return Object(G.a)(Object(i.a)({emoji:t,data:e.data},o))})),u&&!u.length&&f.a.createElement("div",null,f.a.createElement("div",null,Object(G.a)(Object(i.a)({data:this.data},o,{size:38,emoji:"sleuth_or_spy",onOver:null,onLeave:null,onClick:null}))),f.a.createElement("div",{className:"emoji-mart-no-results-label"},s.notfound)))}}]),t}(f.a.Component),N=I;I.defaultProps={emojis:[],hasStickyPosition:!0};var L=function(e){function t(e){o()(this,t);var a=l(this,(t.__proto__||r(t)).call(this,e));return a.data=e.data,a.state={emoji:null},a}return c(t,e),u(t,[{key:"render",value:function(){var e=this.state.emoji,t=this.props,a=t.emojiProps,r=t.skinsProps,n=t.showSkinTones,o=t.title,s=t.emoji;if(e){var u=Object(B.b)(e,null,null,this.data),l=u.emoticons,g=[],c=[];return(void 0===l?[]:l).forEach((function(e){g.indexOf(e.toLowerCase())>=0||(g.push(e.toLowerCase()),c.push(e))})),f.a.createElement("div",{className:"emoji-mart-preview"},f.a.createElement("div",{className:"emoji-mart-preview-emoji"},Object(G.a)(Object(i.a)({key:e.id,emoji:e,data:this.data},a))),f.a.createElement("div",{className:"emoji-mart-preview-data"},f.a.createElement("div",{className:"emoji-mart-preview-name"},e.name),f.a.createElement("div",{className:"emoji-mart-preview-shortnames"},u.short_names.map((function(e){return f.a.createElement("span",{key:e,className:"emoji-mart-preview-shortname"},":",e,":")}))),f.a.createElement("div",{className:"emoji-mart-preview-emoticons"},c.map((function(e){return f.a.createElement("span",{key:e,className:"emoji-mart-preview-emoticon"},e)})))))}return f.a.createElement("div",{className:"emoji-mart-preview"},f.a.createElement("div",{className:"emoji-mart-preview-emoji"},s&&s.length&&Object(G.a)(Object(i.a)({emoji:s,data:this.data},a))),f.a.createElement("div",{className:"emoji-mart-preview-data"},f.a.createElement("span",{className:"emoji-mart-title-label"},o)),n&&f.a.createElement("div",{className:"emoji-mart-preview-skins"},f.a.createElement(K,r)))}}]),t}(f.a.PureComponent),H=L;L.defaultProps={showSkinTones:!0,onChange:function(){}};var W=function(){function e(t){o()(this,e),t.compressed&&Object(q.uncompress)(t),this.data=t||{},this.originalPool={},this.index={},this.emojis={},this.emoticons={},this.customEmojisList=[],this.buildIndex()}return u(e,[{key:"buildIndex",value:function(){var e=this,t=function(t){var a=e.data.emojis[t],i=a.short_names,r=a.emoticons,n=i[0];r&&r.forEach((function(t){e.emoticons[t]||(e.emoticons[t]=n)})),e.emojis[n]=Object(B.c)(n,null,null,e.data),e.originalPool[n]=a};for(var a in this.data.emojis)t(a)}},{key:"clearCustomEmojis",value:function(e){var t=this;this.customEmojisList.forEach((function(a){var i=a.id||a.short_names[0];delete e[i],delete t.emojis[i]}))}},{key:"addCustomToPool",value:function(e,t){var a=this;this.customEmojisList.length&&this.clearCustomEmojis(t),e.forEach((function(e){var i=e.id||e.short_names[0];i&&!t[i]&&(t[i]=Object(B.b)(e,null,null,a.data),a.emojis[i]=Object(B.c)(e,null,null,a.data))})),this.customEmojisList=e,this.index={}}},{key:"search",value:function(e){var t=this,a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=a.emojisToShowFilter,r=a.maxResults,n=a.include,o=a.exclude,s=a.custom,u=void 0===s?[]:s;this.customEmojisList!=u&&this.addCustomToPool(u,this.originalPool),r||(r=75),n||(n=[]),o||(o=[]);var l=null,g=this.originalPool;if(e.length){if("-"==e||"-1"==e)return[this.emojis[-1]];var c=e.toLowerCase().split(/[\s|,|\-|_]+/),_=[];if(c.length>2&&(c=[c[0],c[1]]),(n.length||o.length)&&(g={},this.data.categories.forEach((function(e){var a=!n||!n.length||n.indexOf(e.id)>-1,i=!(!o||!o.length)&&o.indexOf(e.id)>-1;a&&!i&&e.emojis.forEach((function(e){return g[e]=t.data.emojis[e]}))})),u.length)){var f=!n||!n.length||n.indexOf("custom")>-1,d=!(!o||!o.length)&&o.indexOf("custom")>-1;f&&!d&&this.addCustomToPool(u,g)}l=(_=c.map((function(e){for(var a=g,i=t.index,r=0,n=0;n1?B.d.apply(null,_):_.length?_[0]:[]}return l&&(i&&(l=l.filter((function(e){return i(g[e.id])}))),l&&l.length>r&&(l=l.slice(0,r))),l}}]),e}(),z=function(e){function t(e){o()(this,t);var a=l(this,(t.__proto__||r(t)).call(this,e));return a.data=e.data,a.emojiIndex=new W(a.data),a.setRef=a.setRef.bind(a),a.handleChange=a.handleChange.bind(a),a}return c(t,e),u(t,[{key:"handleChange",value:function(){var e=this.input.value;this.props.onSearch(this.emojiIndex.search(e,{emojisToShowFilter:this.props.emojisToShowFilter,maxResults:this.props.maxResults,include:this.props.include,exclude:this.props.exclude,custom:this.props.custom}))}},{key:"setRef",value:function(e){this.input=e}},{key:"clear",value:function(){this.input.value=""}},{key:"render",value:function(){var e=this.props,t=e.i18n,a=e.autoFocus;return f.a.createElement("div",{className:"emoji-mart-search"},f.a.createElement("input",{ref:this.setRef,type:"text",onChange:this.handleChange,placeholder:t.search,autoFocus:a}))}}]),t}(f.a.PureComponent),U=z;z.defaultProps={onSearch:function(){},maxResults:75,emojisToShowFilter:null,autoFocus:!1};var V=function(e){function t(e){o()(this,t);var a=l(this,(t.__proto__||r(t)).call(this,e));return a.state={opened:!1},a.handleClick=a.handleClick.bind(a),a}return c(t,e),u(t,[{key:"handleClick",value:function(e){var t=parseInt(e.currentTarget.getAttribute("data-skin")),a=this.props.onChange;this.state.opened?(this.setState({opened:!1}),t!=this.props.skin&&a(t)):this.setState({opened:!0})}},{key:"render",value:function(){for(var e=this.props.skin,t=this.state.opened,a=[],i=0;i<6;i++){var r=i+1,n=r==e;a.push(f.a.createElement("span",{key:"skin-tone-"+r,className:"emoji-mart-skin-swatch "+(n?"emoji-mart-skin-swatch-selected":"")},f.a.createElement("span",{onClick:this.handleClick,"data-skin":r,className:"emoji-mart-skin emoji-mart-skin-tone-"+r})))}return f.a.createElement("div",null,f.a.createElement("div",{className:"emoji-mart-skin-swatches "+(t?"emoji-mart-skin-swatches-opened":"")},a))}}]),t}(f.a.PureComponent),K=V;V.defaultProps={onChange:function(){}};a(1058);var G=a(1100),Y={search:"Search",notfound:"No Emoji Found",categories:{search:"Search Results",recent:"Frequently Used",people:"Smileys & People",nature:"Animals & Nature",foods:"Food & Drink",activity:"Activity",places:"Travel & Places",objects:"Objects",symbols:"Symbols",flags:"Flags",custom:"Custom"}},J=function(e){function t(e){o()(this,t);var a=l(this,(t.__proto__||r(t)).call(this,e));a.CUSTOM=[],a.RECENT_CATEGORY={id:"recent",name:"Recent",emojis:null},a.SEARCH_CATEGORY={id:"search",name:"Search",emojis:null,anchor:!1},e.data.compressed&&Object(q.uncompress)(e.data),a.data=e.data,a.i18n=Object(B.a)(Y,e.i18n),a.state={skin:e.skin||O.get("skin")||e.defaultSkin,firstRender:!0},a.categories=[];var n=[].concat(a.data.categories);if(e.custom.length>0){var s={},u=0;e.custom.forEach((function(e){s[e.customCategory]||(s[e.customCategory]={id:e.customCategory?"custom-"+e.customCategory:"custom",name:e.customCategory||"Custom",emojis:[],anchor:0===u},u++);var t=s[e.customCategory],r=Object(i.a)({},e,{id:e.short_names[0],custom:!0});t.emojis.push(r),a.CUSTOM.push(r)})),n.push.apply(n,F()(m()(s)))}a.hideRecent=!0,null!=e.include&&n.sort((function(t,a){return e.include.indexOf(t.id)>e.include.indexOf(a.id)?1:-1}));for(var g=0;g-1,f=!(!e.exclude||!e.exclude.length)&&e.exclude.indexOf(c.id)>-1;if(_&&!f)if(e.emojisToShowFilter){for(var d=[],h=c.emojis,p=0;p-1,k=!(!e.exclude||!e.exclude.length)&&e.exclude.indexOf(a.RECENT_CATEGORY.id)>-1;return y&&!k&&(a.hideRecent=!1,a.categories.unshift(a.RECENT_CATEGORY)),a.categories[0]&&(a.categories[0].first=!0),a.categories.unshift(a.SEARCH_CATEGORY),a.setAnchorsRef=a.setAnchorsRef.bind(a),a.handleAnchorClick=a.handleAnchorClick.bind(a),a.setSearchRef=a.setSearchRef.bind(a),a.handleSearch=a.handleSearch.bind(a),a.setScrollRef=a.setScrollRef.bind(a),a.handleScroll=a.handleScroll.bind(a),a.handleScrollPaint=a.handleScrollPaint.bind(a),a.handleEmojiOver=a.handleEmojiOver.bind(a),a.handleEmojiLeave=a.handleEmojiLeave.bind(a),a.handleEmojiClick=a.handleEmojiClick.bind(a),a.handleEmojiSelect=a.handleEmojiSelect.bind(a),a.setPreviewRef=a.setPreviewRef.bind(a),a.handleSkinChange=a.handleSkinChange.bind(a),a.handleKeyDown=a.handleKeyDown.bind(a),a}return c(t,e),u(t,[{key:"componentWillReceiveProps",value:function(e){e.skin?this.setState({skin:e.skin}):e.defaultSkin&&!O.get("skin")&&this.setState({skin:e.defaultSkin})}},{key:"componentDidMount",value:function(){var e=this;this.state.firstRender&&(this.testStickyPosition(),this.firstRenderTimeout=setTimeout((function(){e.setState({firstRender:!1})}),60))}},{key:"componentDidUpdate",value:function(){this.updateCategoriesSize(),this.handleScroll()}},{key:"componentWillUnmount",value:function(){this.SEARCH_CATEGORY.emojis=null,clearTimeout(this.leaveTimeout),clearTimeout(this.firstRenderTimeout)}},{key:"testStickyPosition",value:function(){var e=document.createElement("div");["","-webkit-","-ms-","-moz-","-o-"].forEach((function(t){return e.style.position=t+"sticky"})),this.hasStickyPosition=!!e.style.position.length}},{key:"handleEmojiOver",value:function(e){var t=this.preview;if(t){var a=this.CUSTOM.filter((function(t){return t.id===e.id}))[0];for(var i in a)a.hasOwnProperty(i)&&(e[i]=a[i]);t.setState({emoji:e}),clearTimeout(this.leaveTimeout)}}},{key:"handleEmojiLeave",value:function(e){var t=this.preview;t&&(this.leaveTimeout=setTimeout((function(){t.setState({emoji:null})}),16))}},{key:"handleEmojiClick",value:function(e,t){this.props.onClick(e,t),this.handleEmojiSelect(e)}},{key:"handleEmojiSelect",value:function(e){var t=this;this.props.onSelect(e),this.hideRecent||this.props.recent||S.add(e);var a=this.categoryRefs["category-1"];if(a){var i=a.maxMargin;a.forceUpdate(),window.requestAnimationFrame((function(){t.scroll&&(a.memoizeSize(),i!=a.maxMargin&&(t.updateCategoriesSize(),t.handleScrollPaint(),t.SEARCH_CATEGORY.emojis&&a.updateDisplay("none")))}))}}},{key:"handleScroll",value:function(){this.waitingForPaint||(this.waitingForPaint=!0,window.requestAnimationFrame(this.handleScrollPaint))}},{key:"handleScrollPaint",value:function(){if(this.waitingForPaint=!1,this.scroll){var e=null;if(this.SEARCH_CATEGORY.emojis)e=this.SEARCH_CATEGORY;else{for(var t=this.scroll.scrollTop,a=t>(this.scrollTop||0),i=0,r=0,n=this.categories.length;r0&&(i=u.top),l&&!e&&(e=s)}}t=this.scrollHeight&&(e=this.categories[this.categories.length-1])}if(e){var g=this.anchors,c=e.name;g.state.selected!=c&&g.setState({selected:c})}this.scrollTop=t}}},{key:"handleSearch",value:function(e){this.SEARCH_CATEGORY.emojis=e;for(var t=0,a=this.categories.length;t0||r.size>0)&&Object(o.a)("div",{className:"account__header__fields"},void 0,r.map((function(e,t){return Object(o.a)("dl",{},t,Object(o.a)("dt",{dangerouslySetInnerHTML:{__html:e.get("provider")}}),Object(o.a)("dd",{className:"verified"},void 0,Object(o.a)("a",{href:e.get("proof_url"),target:"_blank",rel:"noopener noreferrer"},void 0,Object(o.a)("span",{title:a.formatMessage(x.linkVerifiedOn,{date:a.formatDate(e.get("updated_at"),M)})},void 0,Object(o.a)(w.a,{id:"check",className:"verified__mark"}))),Object(o.a)("a",{href:e.get("profile_url"),target:"_blank",rel:"noopener noreferrer"},void 0,Object(o.a)("span",{dangerouslySetInnerHTML:{__html:" "+e.get("provider_username")}}))))})),h.map((function(e,t){return Object(o.a)("dl",{},t,Object(o.a)("dt",{dangerouslySetInnerHTML:{__html:e.get("name_emojified")},title:e.get("name")}),Object(o.a)("dd",{className:e.get("verified_at")&&"verified",title:e.get("value_plain")},void 0,e.get("verified_at")&&Object(o.a)("span",{title:a.formatMessage(x.linkVerifiedOn,{date:a.formatDate(e.get("verified_at"),M)})},void 0,Object(o.a)(w.a,{id:"check",className:"verified__mark"}))," ",Object(o.a)("span",{dangerouslySetInnerHTML:{__html:e.get("value_emojified")}})))}))),t.get("note").length>0&&"

"!==t.get("note")&&Object(o.a)("div",{className:"account__header__content",dangerouslySetInnerHTML:f})))))},a}(b.a),Object(f.a)(r,"propTypes",{account:h.a.map,identity_props:h.a.list,onFollow:p.a.func.isRequired,onBlock:p.a.func.isRequired,intl:p.a.object.isRequired,domain:p.a.string.isRequired}),i=n))||i,B=a(872);var q=Object(F.g)(C=function(e){Object(_.a)(a,e);var t;t=a;function a(){for(var t,a=arguments.length,i=new Array(a),r=0;r0||r.size>0)&&Object(o.a)("div",{className:"account__header__fields"},void 0,r.map((function(e,t){return Object(o.a)("dl",{},t,Object(o.a)("dt",{dangerouslySetInnerHTML:{__html:e.get("provider")}}),Object(o.a)("dd",{className:"verified"},void 0,Object(o.a)("a",{href:e.get("proof_url"),target:"_blank",rel:"noopener noreferrer"},void 0,Object(o.a)("span",{title:a.formatMessage(x.linkVerifiedOn,{date:a.formatDate(e.get("updated_at"),M)})},void 0,Object(o.a)(w.a,{id:"check",className:"verified__mark"}))),Object(o.a)("a",{href:e.get("profile_url"),target:"_blank",rel:"noopener noreferrer"},void 0,Object(o.a)("span",{dangerouslySetInnerHTML:{__html:" "+e.get("provider_username")}}))))})),h.map((function(e,t){return Object(o.a)("dl",{},t,Object(o.a)("dt",{dangerouslySetInnerHTML:{__html:e.get("name_emojified")},title:e.get("name")}),Object(o.a)("dd",{className:e.get("verified_at")&&"verified",title:e.get("value_plain")},void 0,e.get("verified_at")&&Object(o.a)("span",{title:a.formatMessage(x.linkVerifiedOn,{date:a.formatDate(e.get("verified_at"),M)})},void 0,Object(o.a)(w.a,{id:"check",className:"verified__mark"}))," ",Object(o.a)("span",{dangerouslySetInnerHTML:{__html:e.get("value_emojified")}})))}))),t.get("note").length>0&&"

"!==t.get("note")&&Object(o.a)("div",{className:"account__header__content",dangerouslySetInnerHTML:f})),Object(o.a)("div",{className:"account__header__extra__links"},void 0,Object(o.a)(E.a,{isActive:this.isStatusesPageActive,activeClassName:"active",to:"/accounts/"+t.get("id"),title:a.formatNumber(t.get("statuses_count"))},void 0,Object(o.a)("strong",{},void 0,Object(D.a)(t.get("statuses_count")))," ",Object(o.a)(F.b,{id:"account.posts",defaultMessage:"Toots"})),Object(o.a)(E.a,{exact:!0,activeClassName:"active",to:"/accounts/"+t.get("id")+"/following",title:a.formatNumber(t.get("following_count"))},void 0,Object(o.a)("strong",{},void 0,Object(D.a)(t.get("following_count")))," ",Object(o.a)(F.b,{id:"account.follows",defaultMessage:"Follows"})),Object(o.a)(E.a,{exact:!0,activeClassName:"active",to:"/accounts/"+t.get("id")+"/followers",title:a.formatNumber(t.get("followers_count"))},void 0,Object(o.a)("strong",{},void 0,Object(D.a)(t.get("followers_count")))," ",Object(o.a)(F.b,{id:"account.followers",defaultMessage:"Followers"}))))))},a}(v.a),Object(f.a)(r,"propTypes",{account:h.a.map,identity_props:h.a.list,onFollow:p.a.func.isRequired,onBlock:p.a.func.isRequired,intl:p.a.object.isRequired,domain:p.a.string.isRequired}),i=n))||i,B=a(779),q=a(122);var A=function(e){Object(_.a)(a,e);var t;t=a;function a(){for(var t,a=arguments.length,i=new Array(a),r=0;rnew Date)})).toArray(),f=t.get("search_index"),h=_.filter((function(e){return Object(s.g)([e]).test(f)}));e(Object(d.d)("CONFIRM",{message:[Object(i.a)(m.b,{id:"confirmations.unfilter",defaultMessage:"Information about this filtered toot"}),Object(i.a)("div",{className:"filtered-status-info"},void 0,Object(i.a)(O,{spoilerText:a.formatMessage(E.author)},void 0,Object(i.a)(v.a,{id:t.getIn(["account","id"])})),Object(i.a)(O,{spoilerText:a.formatMessage(E.matchingFilters,{count:h.size})},void 0,Object(i.a)("ul",{},void 0,h.map((function(e){return Object(i.a)("li",{},void 0,e.get("phrase"),!!F.b&&" ",!!F.b&&Object(i.a)("a",{target:"_blank",className:"filtered-status-edit-link",title:a.formatMessage(E.editFilter),href:Object(F.b)(e.get("id"))},void 0,Object(i.a)(D.a,{id:"pencil"})))})))))],confirm:a.formatMessage(E.unfilterConfirm),onConfirm:n}))}))},onReport:function(t){e(Object(f.k)(t.get("account"),t))},onMute:function(t){e(Object(c.g)(t))},onMuteConversation:function(t){t.get("muted")?e(Object(g.j)(t.get("id"))):e(Object(g.h)(t.get("id")))}}}))(n.a))},1090:function(e,t){e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},1091:function(e,t){e.exports=function(e){try{return!!e()}catch(e){return!0}}},1092:function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},1093:function(e,t,a){var i=a(1243),r=a(1144);e.exports=Object.keys||function(e){return i(e,r)}},1094:function(e,t,a){var i=a(1244),r=a(1095);e.exports=function(e){return i(r(e))}},1095:function(e,t){e.exports=function(e){if(null==e)throw TypeError("Can't call method on "+e);return e}},1096:function(e,t){var a=Math.ceil,i=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?i:a)(e)}},1097:function(e,t,a){var i=a(1141)("keys"),r=a(1143);e.exports=function(e){return i[e]||(i[e]=r(e))}},1098:function(e,t){e.exports={}},1099:function(e,t,a){var i=a(1095);e.exports=function(e){return Object(i(e))}},1100:function(e,t,a){"use strict";var i=a(3),r=a.n(i),n=(a(5),a(1066)),o=a(1076),s=a(1077),u=function(e){var t=e.emoji,a=e.skin,i=e.set,r=e.data;return Object(n.b)(t,a,i,r)},l=function(e){var t=u(e);return 100/51*t.sheet_x+"% "+100/51*t.sheet_y+"%"},g=function(e){var t=e.emoji,a=e.skin,i=e.set,r=e.data;return Object(n.c)(t,a,i,r)},c=function(e){return!isNaN(e-parseFloat(e))},_=function e(t){for(var a in t.data.compressed&&Object(o.uncompress)(t.data),e.defaultProps)null==t[a]&&null!=e.defaultProps[a]&&(t[a]=e.defaultProps[a]);var i=u(t);if(!i)return null;var s=i.unified,_=i.custom,f=i.short_names,d=i.colons,h=i.imageUrl,m={},p=t.children,F="emoji-mart-emoji",b=null;if(!s&&!_)return null;if(t.tooltip&&(b=f?":"+f[0]+":":d),t.native&&s)F+=" emoji-mart-emoji-native",m={fontSize:t.size},p=Object(n.f)(s),t.forceSize&&(m.display="inline-block",m.width=t.size,m.height=t.size);else if(_)F+=" emoji-mart-emoji-custom",m={width:t.size,height:t.size,display:"inline-block",backgroundImage:"url("+h+")",backgroundSize:"contain"};else{if(!(null==i["has_img_"+t.set]||i["has_img_"+t.set]))return t.fallback?t.fallback(i):null;m={width:t.size,height:t.size,display:"inline-block",backgroundImage:"url("+t.backgroundImageFn(t.set,t.sheetSize)+")",backgroundSize:"5200%",backgroundPosition:l(t)}}return t.html?""+(p||"")+"":r.a.createElement("span",{key:t.emoji.id||t.emoji,onClick:function(e){return function(e,t){t.onClick&&(0,t.onClick)(g(t),e)}(e,t)},onMouseEnter:function(e){return function(e,t){t.onOver&&(0,t.onOver)(g(t),e)}(e,t)},onMouseLeave:function(e){return function(e,t){t.onLeave&&(0,t.onLeave)(g(t),e)}(e,t)},title:b,className:F},r.a.createElement("span",{style:m},p))};_.defaultProps=s.a,t.a=_},1101:function(e,t,a){"use strict";a.d(t,"a",(function(){return c}));var i=a(0),r=a(2),n=(a(9),a(6),a(8)),o=a(1),s=a(3),u=a.n(s),l=a(307),g=a.n(l);var c=function(e){Object(n.a)(a,e);var t;t=a;function a(){for(var t,a=arguments.length,i=new Array(a),n=0;n",":->"],"n":["satisfied"]},"apple":{"a":"Red Apple","b":"1F34E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["fruit","mac","school"],"k":[7,16]},"flag-ad":{"a":"Andorra Flag","b":"1F1E6-1F1E9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[0,32]},"fox_face":{"a":"Fox Face","b":"1F98A","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["animal","nature","face"],"k":[42,34],"o":9},"confetti_ball":{"a":"Confetti Ball","b":"1F38A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["festival","party","birthday","circus"],"k":[8,29]},"bell":{"a":"Bell","b":"1F514","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sound","notification","christmas","xmas","chime"],"k":[27,22]},"mountain":{"a":"Mountain","b":"26F0-FE0F","c":"26F0","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["photo","nature","environment"],"k":[48,38],"o":5},"baby_symbol":{"a":"Baby Symbol","b":"1F6BC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["orange-square","child"],"k":[36,32]},"wc":{"a":"Water Closet","b":"1F6BE","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["toilet","restroom","blue-square"],"k":[36,34]},"wink":{"a":"Winking Face","b":"1F609","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","happy","mischievous","secret",";)","smile","eye"],"k":[30,33],"l":[";)",";-)"],"m":";)"},"no_bell":{"a":"Bell with Cancellation Stroke","b":"1F515","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sound","volume","mute","quiet","silent"],"k":[27,23]},"green_apple":{"a":"Green Apple","b":"1F34F","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["fruit","nature"],"k":[7,17]},"tanabata_tree":{"a":"Tanabata Tree","b":"1F38B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["plant","nature","branch","summer"],"k":[8,30]},"flag-ae":{"a":"United Arab Emirates Flag","b":"1F1E6-1F1EA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[0,33]},"volcano":{"a":"Volcano","b":"1F30B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["photo","nature","disaster"],"k":[6,3]},"cat":{"a":"Cat Face","b":"1F431","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","meow","nature","pet","kitten"],"k":[13,27]},"flag-af":{"a":"Afghanistan Flag","b":"1F1E6-1F1EB","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[0,34]},"musical_score":{"a":"Musical Score","b":"1F3BC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["treble","clef","compose"],"k":[9,22]},"blush":{"a":"Smiling Face with Smiling Eyes","b":"1F60A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","smile","happy","flushed","crush","embarrassed","shy","joy"],"k":[30,34],"m":":)"},"pear":{"a":"Pear","b":"1F350","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["fruit","nature","food"],"k":[7,18]},"bamboo":{"a":"Pine Decoration","b":"1F38D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["plant","nature","vegetable","panda","pine_decoration"],"k":[8,32]},"passport_control":{"a":"Passport Control","b":"1F6C2","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["custom","blue-square"],"k":[36,43]},"mount_fuji":{"a":"Mount Fuji","b":"1F5FB","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["photo","mountain","nature","japanese"],"k":[30,19]},"cat2":{"a":"Cat","b":"1F408","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","meow","pet","cats"],"k":[12,38]},"musical_note":{"a":"Musical Note","b":"1F3B5","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["score","tone","sound"],"k":[9,15]},"dolls":{"a":"Japanese Dolls","b":"1F38E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["japanese","toy","kimono"],"k":[8,33]},"lion_face":{"a":"Lion Face","b":"1F981","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,25],"o":8},"camping":{"a":"Camping","b":"1F3D5-FE0F","c":"1F3D5","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["photo","outdoors","tent"],"k":[11,38],"o":7},"flag-ag":{"a":"Antigua & Barbuda Flag","b":"1F1E6-1F1EC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[0,35]},"customs":{"a":"Customs","b":"1F6C3","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["passport","border","blue-square"],"k":[36,44]},"yum":{"a":"Face Savouring Delicious Food","b":"1F60B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["happy","joy","tongue","smile","face","silly","yummy","nom","delicious","savouring"],"k":[30,35]},"peach":{"a":"Peach","b":"1F351","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["fruit","nature","food"],"k":[7,19]},"tiger":{"a":"Tiger Face","b":"1F42F","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","cat","danger","wild","nature","roar"],"k":[13,25]},"notes":{"a":"Multiple Musical Notes","b":"1F3B6","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["music","score"],"k":[9,16]},"flags":{"a":"Carp Streamer","b":"1F38F","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["fish","japanese","koinobori","carp","banner"],"k":[8,34]},"beach_with_umbrella":{"a":"Beach with Umbrella","b":"1F3D6-FE0F","c":"1F3D6","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[11,39],"o":7},"cherries":{"a":"Cherries","b":"1F352","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","fruit"],"k":[7,20]},"flag-ai":{"a":"Anguilla Flag","b":"1F1E6-1F1EE","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[0,36]},"baggage_claim":{"a":"Baggage Claim","b":"1F6C4","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","airport","transport"],"k":[36,45]},"sunglasses":{"a":"Smiling Face with Sunglasses","b":"1F60E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","cool","smile","summer","beach","sunglass"],"k":[30,38],"l":["8)"]},"left_luggage":{"a":"Left Luggage","b":"1F6C5","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","travel"],"k":[36,46]},"wind_chime":{"a":"Wind Chime","b":"1F390","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["nature","ding","spring","bell"],"k":[8,35]},"strawberry":{"a":"Strawberry","b":"1F353","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["fruit","food","nature"],"k":[7,21]},"desert":{"a":"Desert","b":"1F3DC-FE0F","c":"1F3DC","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["photo","warm","saharah"],"k":[11,45],"o":7},"studio_microphone":{"a":"Studio Microphone","b":"1F399-FE0F","c":"1F399","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["sing","recording","artist","talkshow"],"k":[8,41],"o":7},"flag-al":{"a":"Albania Flag","b":"1F1E6-1F1F1","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[0,37]},"tiger2":{"a":"Tiger","b":"1F405","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature","roar"],"k":[12,35]},"heart_eyes":{"a":"Smiling Face with Heart-Shaped Eyes","b":"1F60D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","love","like","affection","valentines","infatuation","crush","heart"],"k":[30,37]},"desert_island":{"a":"Desert Island","b":"1F3DD-FE0F","c":"1F3DD","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["photo","tropical","mojito"],"k":[11,46],"o":7},"kiwifruit":{"a":"Kiwifruit","b":"1F95D","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,9],"o":9},"rice_scene":{"a":"Moon Viewing Ceremony","b":"1F391","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["photo","japan","asia","tsukimi"],"k":[8,36]},"kissing_heart":{"a":"Face Throwing a Kiss","b":"1F618","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","love","like","affection","valentines","infatuation","kiss"],"k":[30,48],"l":[":*",":-*"]},"warning":{"a":"Warning Sign","b":"26A0-FE0F","c":"26A0","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["exclamation","wip","alert","error","problem","issue"],"k":[48,20],"o":4},"flag-am":{"a":"Armenia Flag","b":"1F1E6-1F1F2","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[0,38]},"leopard":{"a":"Leopard","b":"1F406","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature"],"k":[12,36]},"level_slider":{"a":"Level Slider","b":"1F39A-FE0F","c":"1F39A","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["scale"],"k":[8,42],"o":7},"horse":{"a":"Horse Face","b":"1F434","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","brown","nature"],"k":[13,30]},"children_crossing":{"a":"Children Crossing","b":"1F6B8","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["school","warning","danger","sign","driving","yellow-diamond"],"k":[36,28]},"ribbon":{"a":"Ribbon","b":"1F380","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["decoration","pink","girl","bowtie"],"k":[8,14]},"national_park":{"a":"National Park","b":"1F3DE-FE0F","c":"1F3DE","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["photo","environment","nature"],"k":[11,47],"o":7},"control_knobs":{"a":"Control Knobs","b":"1F39B-FE0F","c":"1F39B","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["dial"],"k":[8,43],"o":7},"kissing":{"a":"Kissing Face","b":"1F617","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["love","like","face","3","valentines","infatuation","kiss"],"k":[30,47]},"tomato":{"a":"Tomato","b":"1F345","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["fruit","vegetable","nature","food"],"k":[7,7]},"flag-ao":{"a":"Angola Flag","b":"1F1E6-1F1F4","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[0,39]},"stadium":{"a":"Stadium","b":"1F3DF-FE0F","c":"1F3DF","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["photo","place","sports","concert","venue"],"k":[11,48],"o":7},"flag-aq":{"a":"Antarctica Flag","b":"1F1E6-1F1F6","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[0,40]},"gift":{"a":"Wrapped Present","b":"1F381","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["present","birthday","christmas","xmas"],"k":[8,15]},"no_entry":{"a":"No Entry","b":"26D4","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["limit","security","privacy","bad","denied","stop","circle"],"k":[48,35],"o":5},"kissing_smiling_eyes":{"a":"Kissing Face with Smiling Eyes","b":"1F619","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","affection","valentines","infatuation","kiss"],"k":[30,49]},"coconut":{"a":"Coconut","b":"1F965","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,17],"o":10},"racehorse":{"a":"Horse","b":"1F40E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","gamble","luck"],"k":[12,44]},"microphone":{"a":"Microphone","b":"1F3A4","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sound","music","PA","sing","talkshow"],"k":[8,50]},"classical_building":{"a":"Classical Building","b":"1F3DB-FE0F","c":"1F3DB","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["art","culture","history"],"k":[11,44],"o":7},"no_entry_sign":{"a":"No Entry Sign","b":"1F6AB","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["forbid","stop","limit","denied","disallow","circle"],"k":[35,16]},"reminder_ribbon":{"a":"Reminder Ribbon","b":"1F397-FE0F","c":"1F397","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["sports","cause","support","awareness"],"k":[8,40],"o":7},"kissing_closed_eyes":{"a":"Kissing Face with Closed Eyes","b":"1F61A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","love","like","affection","valentines","infatuation","kiss"],"k":[30,50]},"unicorn_face":{"a":"Unicorn Face","b":"1F984","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,28],"o":8},"flag-ar":{"a":"Argentina Flag","b":"1F1E6-1F1F7","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[0,41]},"headphones":{"a":"Headphone","b":"1F3A7","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["music","score","gadgets"],"k":[9,1]},"avocado":{"a":"Avocado","b":"1F951","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["fruit","food"],"k":[41,49],"o":9},"relaxed":{"a":"White Smiling Face","b":"263A-FE0F","c":"263A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","blush","massage","happiness"],"k":[47,41],"o":1},"zebra_face":{"a":"Zebra Face","b":"1F993","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,43],"o":10},"eggplant":{"a":"Aubergine","b":"1F346","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["vegetable","nature","food","aubergine"],"k":[7,8]},"radio":{"a":"Radio","b":"1F4FB","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["communication","music","podcast","program"],"k":[26,50]},"building_construction":{"a":"Building Construction","b":"1F3D7-FE0F","c":"1F3D7","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["wip","working","progress"],"k":[11,40],"o":7},"flag-as":{"a":"American Samoa Flag","b":"1F1E6-1F1F8","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[0,42]},"admission_tickets":{"a":"Admission Tickets","b":"1F39F-FE0F","c":"1F39F","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[8,45],"o":7},"no_bicycles":{"a":"No Bicycles","b":"1F6B3","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["cyclist","prohibited","circle"],"k":[35,24]},"no_smoking":{"a":"No Smoking Symbol","b":"1F6AD","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["cigarette","blue-square","smell","smoke"],"k":[35,18]},"slightly_smiling_face":{"a":"Slightly Smiling Face","b":"1F642","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","smile"],"k":[31,38],"l":[":)","(:",":-)"],"o":7},"flag-at":{"a":"Austria Flag","b":"1F1E6-1F1F9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[0,43]},"ticket":{"a":"Ticket","b":"1F3AB","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["event","concert","pass"],"k":[9,5]},"saxophone":{"a":"Saxophone","b":"1F3B7","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["music","instrument","jazz","blues"],"k":[9,17]},"deer":{"a":"Deer","b":"1F98C","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["animal","nature","horns","venison"],"k":[42,36],"o":9},"house_buildings":{"a":"House Buildings","b":"1F3D8-FE0F","c":"1F3D8","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[11,41],"o":7},"potato":{"a":"Potato","b":"1F954","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["food","tuber","vegatable","starch"],"k":[42,0],"o":9},"guitar":{"a":"Guitar","b":"1F3B8","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["music","instrument"],"k":[9,18]},"carrot":{"a":"Carrot","b":"1F955","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["vegetable","food","orange"],"k":[42,1],"o":9},"cityscape":{"a":"Cityscape","b":"1F3D9-FE0F","c":"1F3D9","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["photo","night life","urban"],"k":[11,42],"o":7},"flag-au":{"a":"Australia Flag","b":"1F1E6-1F1FA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[0,44]},"do_not_litter":{"a":"Do Not Litter Symbol","b":"1F6AF","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["trash","bin","garbage","circle"],"k":[35,20]},"hugging_face":{"a":"Hugging Face","b":"1F917","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[37,31],"o":8},"cow":{"a":"Cow Face","b":"1F42E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["beef","ox","animal","nature","moo","milk"],"k":[13,24]},"medal":{"a":"Medal","b":"1F396-FE0F","c":"1F396","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[8,39],"o":7},"musical_keyboard":{"a":"Musical Keyboard","b":"1F3B9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["piano","instrument","compose"],"k":[9,19]},"corn":{"a":"Ear of Maize","b":"1F33D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","vegetable","plant"],"k":[6,51]},"derelict_house_building":{"a":"Derelict House Building","b":"1F3DA-FE0F","c":"1F3DA","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[11,43],"o":7},"non-potable_water":{"a":"Non-Potable Water Symbol","b":"1F6B1","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["drink","faucet","tap","circle"],"k":[35,22]},"trophy":{"a":"Trophy","b":"1F3C6","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["win","award","contest","place","ftw","ceremony"],"k":[10,19]},"flag-aw":{"a":"Aruba Flag","b":"1F1E6-1F1FC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[0,45]},"star-struck":{"a":"Grinning Face with Star Eyes","b":"1F929","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[38,49],"n":["grinning_face_with_star_eyes"],"o":10},"ox":{"a":"Ox","b":"1F402","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","cow","beef"],"k":[12,32]},"trumpet":{"a":"Trumpet","b":"1F3BA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["music","brass"],"k":[9,20]},"hot_pepper":{"a":"Hot Pepper","b":"1F336-FE0F","c":"1F336","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["food","spicy","chilli","chili"],"k":[6,44],"o":7},"sports_medal":{"a":"Sports Medal","b":"1F3C5","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[10,18],"o":7},"flag-ax":{"a":"Åland Islands Flag","b":"1F1E6-1F1FD","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[0,46]},"water_buffalo":{"a":"Water Buffalo","b":"1F403","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature","ox","cow"],"k":[12,33]},"no_pedestrians":{"a":"No Pedestrians","b":"1F6B7","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["rules","crossing","walking","circle"],"k":[36,27]},"thinking_face":{"a":"Thinking Face","b":"1F914","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[37,28],"o":8},"house":{"a":"House Building","b":"1F3E0","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["building","home"],"k":[11,49]},"no_mobile_phones":{"a":"No Mobile Phones","b":"1F4F5","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["iphone","mute","circle"],"k":[26,44]},"flag-az":{"a":"Azerbaijan Flag","b":"1F1E6-1F1FF","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[0,47]},"first_place_medal":{"a":"First Place Medal","b":"1F947","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[41,42],"o":9},"house_with_garden":{"a":"House with Garden","b":"1F3E1","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["home","plant","nature"],"k":[11,50]},"violin":{"a":"Violin","b":"1F3BB","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["music","instrument","orchestra","symphony"],"k":[9,21]},"face_with_raised_eyebrow":{"a":"Face with One Eyebrow Raised","b":"1F928","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[38,48],"n":["face_with_one_eyebrow_raised"],"o":10},"cucumber":{"a":"Cucumber","b":"1F952","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["fruit","food","pickle"],"k":[41,50],"o":9},"cow2":{"a":"Cow","b":"1F404","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["beef","ox","animal","nature","moo","milk"],"k":[12,34]},"flag-ba":{"a":"Bosnia & Herzegovina Flag","b":"1F1E7-1F1E6","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[0,48]},"pig":{"a":"Pig Face","b":"1F437","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","oink","nature"],"k":[13,33]},"drum_with_drumsticks":{"a":"Drum with Drumsticks","b":"1F941","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[41,37],"o":9},"underage":{"a":"No One Under Eighteen Symbol","b":"1F51E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["18","drink","pub","night","minor","circle"],"k":[27,32]},"broccoli":{"a":"Broccoli","b":"1F966","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,18],"o":10},"office":{"a":"Office Building","b":"1F3E2","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["building","bureau","work"],"k":[11,51]},"second_place_medal":{"a":"Second Place Medal","b":"1F948","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[41,43],"o":9},"neutral_face":{"a":"Neutral Face","b":"1F610","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["indifference","meh",":|","neutral"],"k":[30,40],"l":[":|",":-|"]},"third_place_medal":{"a":"Third Place Medal","b":"1F949","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[41,44],"o":9},"mushroom":{"a":"Mushroom","b":"1F344","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["plant","vegetable"],"k":[7,6]},"flag-bb":{"a":"Barbados Flag","b":"1F1E7-1F1E7","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[0,49]},"radioactive_sign":{"a":"Radioactive Sign","b":"2622-FE0F","c":"2622","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[47,33],"o":1},"pig2":{"a":"Pig","b":"1F416","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature"],"k":[13,0]},"expressionless":{"a":"Expressionless Face","b":"1F611","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","indifferent","-_-","meh","deadpan"],"k":[30,41]},"iphone":{"a":"Mobile Phone","b":"1F4F1","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["technology","apple","gadgets","dial"],"k":[26,40]},"post_office":{"a":"Japanese Post Office","b":"1F3E3","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["building","envelope","communication"],"k":[12,0]},"european_post_office":{"a":"European Post Office","b":"1F3E4","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["building","email"],"k":[12,1]},"soccer":{"a":"Soccer Ball","b":"26BD","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sports","football"],"k":[48,26],"o":5},"boar":{"a":"Boar","b":"1F417","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature"],"k":[13,1]},"peanuts":{"a":"Peanuts","b":"1F95C","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["food","nut"],"k":[42,8],"o":9},"calling":{"a":"Mobile Phone with Rightwards Arrow at Left","b":"1F4F2","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["iphone","incoming"],"k":[26,41]},"biohazard_sign":{"a":"Biohazard Sign","b":"2623-FE0F","c":"2623","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[47,34],"o":1},"flag-bd":{"a":"Bangladesh Flag","b":"1F1E7-1F1E9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[0,50]},"no_mouth":{"a":"Face Without Mouth","b":"1F636","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","hellokitty"],"k":[31,26]},"face_with_rolling_eyes":{"a":"Face with Rolling Eyes","b":"1F644","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[31,40],"o":8},"phone":{"a":"Black Telephone","b":"260E-FE0F","c":"260E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["technology","communication","dial","telephone"],"k":[47,21],"n":["telephone"],"o":1},"pig_nose":{"a":"Pig Nose","b":"1F43D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","oink"],"k":[13,39]},"chestnut":{"a":"Chestnut","b":"1F330","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","squirrel"],"k":[6,38]},"arrow_up":{"a":"Upwards Black Arrow","b":"2B06-FE0F","c":"2B06","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","continue","top","direction"],"k":[50,18],"o":4},"hospital":{"a":"Hospital","b":"1F3E5","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["building","health","surgery","doctor"],"k":[12,2]},"flag-be":{"a":"Belgium Flag","b":"1F1E7-1F1EA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[0,51]},"baseball":{"a":"Baseball","b":"26BE","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sports","balls"],"k":[48,27],"o":5},"smirk":{"a":"Smirking Face","b":"1F60F","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","smile","mean","prank","smug","sarcasm"],"k":[30,39]},"arrow_upper_right":{"a":"North East Arrow","b":"2197-FE0F","c":"2197","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","point","direction","diagonal","northeast"],"k":[46,36],"o":1},"flag-bf":{"a":"Burkina Faso Flag","b":"1F1E7-1F1EB","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,0]},"basketball":{"a":"Basketball and Hoop","b":"1F3C0","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sports","balls","NBA"],"k":[9,26]},"ram":{"a":"Ram","b":"1F40F","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","sheep","nature"],"k":[12,45]},"bank":{"a":"Bank","b":"1F3E6","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["building","money","sales","cash","business","enterprise"],"k":[12,3]},"bread":{"a":"Bread","b":"1F35E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","wheat","breakfast","toast"],"k":[7,32]},"telephone_receiver":{"a":"Telephone Receiver","b":"1F4DE","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["technology","communication","dial"],"k":[26,21]},"croissant":{"a":"Croissant","b":"1F950","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["food","bread","french"],"k":[41,48],"o":9},"pager":{"a":"Pager","b":"1F4DF","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["bbcall","oldschool","90s"],"k":[26,22]},"sheep":{"a":"Sheep","b":"1F411","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature","wool","shipit"],"k":[12,47]},"arrow_right":{"a":"Black Rightwards Arrow","b":"27A1-FE0F","c":"27A1","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","next"],"k":[50,12],"o":1},"persevere":{"a":"Persevering Face","b":"1F623","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","sick","no","upset","oops"],"k":[31,7]},"flag-bg":{"a":"Bulgaria Flag","b":"1F1E7-1F1EC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,1]},"volleyball":{"a":"Volleyball","b":"1F3D0","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["sports","balls"],"k":[11,33],"o":8},"hotel":{"a":"Hotel","b":"1F3E8","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["building","accomodation","checkin"],"k":[12,5]},"arrow_lower_right":{"a":"South East Arrow","b":"2198-FE0F","c":"2198","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","direction","diagonal","southeast"],"k":[46,37],"o":1},"goat":{"a":"Goat","b":"1F410","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature"],"k":[12,46]},"flag-bh":{"a":"Bahrain Flag","b":"1F1E7-1F1ED","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,2]},"love_hotel":{"a":"Love Hotel","b":"1F3E9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["like","affection","dating"],"k":[12,6]},"disappointed_relieved":{"a":"Disappointed but Relieved Face","b":"1F625","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","phew","sweat","nervous"],"k":[31,9]},"baguette_bread":{"a":"Baguette Bread","b":"1F956","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["food","bread","french"],"k":[42,2],"o":9},"football":{"a":"American Football","b":"1F3C8","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sports","balls","NFL"],"k":[10,26]},"fax":{"a":"Fax Machine","b":"1F4E0","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["communication","technology"],"k":[26,23]},"convenience_store":{"a":"Convenience Store","b":"1F3EA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["building","shopping","groceries"],"k":[12,7]},"dromedary_camel":{"a":"Dromedary Camel","b":"1F42A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","hot","desert","hump"],"k":[13,20]},"arrow_down":{"a":"Downwards Black Arrow","b":"2B07-FE0F","c":"2B07","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","direction","bottom"],"k":[50,19],"o":4},"battery":{"a":"Battery","b":"1F50B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["power","energy","sustain"],"k":[27,13]},"rugby_football":{"a":"Rugby Football","b":"1F3C9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sports","team"],"k":[10,27]},"pretzel":{"a":"Pretzel","b":"1F968","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,20],"o":10},"open_mouth":{"a":"Face with Open Mouth","b":"1F62E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","surprise","impressed","wow","whoa",":O"],"k":[31,18],"l":[":o",":-o",":O",":-O"]},"flag-bi":{"a":"Burundi Flag","b":"1F1E7-1F1EE","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,3]},"flag-bj":{"a":"Benin Flag","b":"1F1E7-1F1EF","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,4]},"pancakes":{"a":"Pancakes","b":"1F95E","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["food","breakfast","flapjacks","hotcakes"],"k":[42,10],"o":9},"school":{"a":"School","b":"1F3EB","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["building","student","education","learn","teach"],"k":[12,8]},"tennis":{"a":"Tennis Racquet and Ball","b":"1F3BE","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sports","balls","green"],"k":[9,24]},"zipper_mouth_face":{"a":"Zipper-Mouth Face","b":"1F910","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["face","sealed","zipper","secret"],"k":[37,24],"o":8},"camel":{"a":"Bactrian Camel","b":"1F42B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature","hot","desert","hump"],"k":[13,21]},"arrow_lower_left":{"a":"South West Arrow","b":"2199-FE0F","c":"2199","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","direction","diagonal","southwest"],"k":[46,38],"o":1},"electric_plug":{"a":"Electric Plug","b":"1F50C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["charger","power"],"k":[27,14]},"cheese_wedge":{"a":"Cheese Wedge","b":"1F9C0","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,48],"o":8},"hushed":{"a":"Hushed Face","b":"1F62F","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","woo","shh"],"k":[31,19]},"computer":{"a":"Personal Computer","b":"1F4BB","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["technology","laptop","screen","display","monitor"],"k":[25,38]},"giraffe_face":{"a":"Giraffe Face","b":"1F992","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,42],"o":10},"8ball":{"a":"Billiards","b":"1F3B1","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["pool","hobby","game","luck","magic"],"k":[9,11]},"flag-bl":{"a":"St. Barthélemy Flag","b":"1F1E7-1F1F1","d":true,"e":false,"f":true,"g":true,"h":true,"i":true,"k":[1,5]},"arrow_left":{"a":"Leftwards Black Arrow","b":"2B05-FE0F","c":"2B05","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","previous","back"],"k":[50,17],"o":4},"department_store":{"a":"Department Store","b":"1F3EC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["building","shopping","mall"],"k":[12,9]},"meat_on_bone":{"a":"Meat on Bone","b":"1F356","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["good","food","drumstick"],"k":[7,24]},"arrow_upper_left":{"a":"North West Arrow","b":"2196-FE0F","c":"2196","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","point","direction","diagonal","northwest"],"k":[46,35],"o":1},"flag-bm":{"a":"Bermuda Flag","b":"1F1E7-1F1F2","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,6]},"sleepy":{"a":"Sleepy Face","b":"1F62A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","tired","rest","nap"],"k":[31,14]},"bowling":{"a":"Bowling","b":"1F3B3","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sports","fun","play"],"k":[9,13]},"factory":{"a":"Factory","b":"1F3ED","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["building","industry","pollution","smoke"],"k":[12,10]},"desktop_computer":{"a":"Desktop Computer","b":"1F5A5-FE0F","c":"1F5A5","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["technology","computing","screen"],"k":[29,51],"o":7},"elephant":{"a":"Elephant","b":"1F418","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature","nose","th","circus"],"k":[13,2]},"rhinoceros":{"a":"Rhinoceros","b":"1F98F","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["animal","nature","horn"],"k":[42,39],"o":9},"arrow_up_down":{"a":"Up Down Arrow","b":"2195-FE0F","c":"2195","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","direction","way","vertical"],"k":[46,34],"o":1},"cricket_bat_and_ball":{"a":"Cricket Bat and Ball","b":"1F3CF","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[11,32],"o":8},"printer":{"a":"Printer","b":"1F5A8-FE0F","c":"1F5A8","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["paper","ink"],"k":[30,0],"o":7},"poultry_leg":{"a":"Poultry Leg","b":"1F357","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","meat","drumstick","bird","chicken","turkey"],"k":[7,25]},"tired_face":{"a":"Tired Face","b":"1F62B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sick","whine","upset","frustrated"],"k":[31,15]},"japanese_castle":{"a":"Japanese Castle","b":"1F3EF","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["photo","building"],"k":[12,12]},"flag-bn":{"a":"Brunei Flag","b":"1F1E7-1F1F3","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[1,7]},"field_hockey_stick_and_ball":{"a":"Field Hockey Stick and Ball","b":"1F3D1","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[11,34],"o":8},"sleeping":{"a":"Sleeping Face","b":"1F634","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","tired","sleepy","night","zzz"],"k":[31,24]},"left_right_arrow":{"a":"Left Right Arrow","b":"2194-FE0F","c":"2194","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["shape","direction","horizontal","sideways"],"k":[46,33],"o":1},"keyboard":{"a":"Keyboard","b":"2328-FE0F","c":"2328","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["technology","computer","type","input","text"],"k":[46,43],"o":1},"european_castle":{"a":"European Castle","b":"1F3F0","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["building","royalty","history"],"k":[12,13]},"mouse":{"a":"Mouse Face","b":"1F42D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature","cheese_wedge","rodent"],"k":[13,23]},"flag-bo":{"a":"Bolivia Flag","b":"1F1E7-1F1F4","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,8]},"cut_of_meat":{"a":"Cut of Meat","b":"1F969","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,21],"o":10},"ice_hockey_stick_and_puck":{"a":"Ice Hockey Stick and Puck","b":"1F3D2","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[11,35],"o":8},"mouse2":{"a":"Mouse","b":"1F401","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature","rodent"],"k":[12,31]},"three_button_mouse":{"a":"Three Button Mouse","b":"1F5B1-FE0F","c":"1F5B1","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[30,1],"o":7},"leftwards_arrow_with_hook":{"a":"Leftwards Arrow with Hook","b":"21A9-FE0F","c":"21A9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["back","return","blue-square","undo","enter"],"k":[46,39],"o":1},"bacon":{"a":"Bacon","b":"1F953","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["food","breakfast","pork","pig","meat"],"k":[41,51],"o":9},"relieved":{"a":"Relieved Face","b":"1F60C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","relaxed","phew","massage","happiness"],"k":[30,36]},"flag-bq":{"a":"Caribbean Netherlands Flag","b":"1F1E7-1F1F6","d":true,"e":false,"f":true,"g":true,"h":true,"i":true,"k":[1,9]},"wedding":{"a":"Wedding","b":"1F492","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["love","like","affection","couple","marriage","bride","groom"],"k":[24,44]},"tokyo_tower":{"a":"Tokyo Tower","b":"1F5FC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["photo","japanese"],"k":[30,20]},"arrow_right_hook":{"a":"Rightwards Arrow with Hook","b":"21AA-FE0F","c":"21AA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","return","rotate","direction"],"k":[46,40],"o":1},"hamburger":{"a":"Hamburger","b":"1F354","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["meat","fast food","beef","cheeseburger","mcdonalds","burger king"],"k":[7,22]},"stuck_out_tongue":{"a":"Face with Stuck-out Tongue","b":"1F61B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","prank","childish","playful","mischievous","smile","tongue"],"k":[30,51],"l":[":p",":-p",":P",":-P",":b",":-b"],"m":":p"},"trackball":{"a":"Trackball","b":"1F5B2-FE0F","c":"1F5B2","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["technology","trackpad"],"k":[30,2],"o":7},"flag-br":{"a":"Brazil Flag","b":"1F1E7-1F1F7","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,10]},"rat":{"a":"Rat","b":"1F400","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","mouse","rodent"],"k":[12,30]},"table_tennis_paddle_and_ball":{"a":"Table Tennis Paddle and Ball","b":"1F3D3","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[11,36],"o":8},"minidisc":{"a":"Minidisc","b":"1F4BD","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["technology","record","data","disk","90s"],"k":[25,40]},"stuck_out_tongue_winking_eye":{"a":"Face with Stuck-out Tongue and Winking Eye","b":"1F61C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","prank","childish","playful","mischievous","smile","wink","tongue"],"k":[31,0],"l":[";p",";-p",";b",";-b",";P",";-P"],"m":";p"},"fries":{"a":"French Fries","b":"1F35F","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["chips","snack","fast food"],"k":[7,33]},"badminton_racquet_and_shuttlecock":{"a":"Badminton Racquet and Shuttlecock","b":"1F3F8","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[12,22],"o":8},"statue_of_liberty":{"a":"Statue of Liberty","b":"1F5FD","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["american","newyork"],"k":[30,21]},"flag-bs":{"a":"Bahamas Flag","b":"1F1E7-1F1F8","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,11]},"arrow_heading_up":{"a":"Arrow Pointing Rightwards Then Curving Upwards","b":"2934-FE0F","c":"2934","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","direction","top"],"k":[50,15],"o":3},"hamster":{"a":"Hamster Face","b":"1F439","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature"],"k":[13,35]},"stuck_out_tongue_closed_eyes":{"a":"Face with Stuck-out Tongue and Tightly-Closed Eyes","b":"1F61D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","prank","playful","mischievous","smile","tongue"],"k":[31,1]},"pizza":{"a":"Slice of Pizza","b":"1F355","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","party"],"k":[7,23]},"boxing_glove":{"a":"Boxing Glove","b":"1F94A","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["sports","fighting"],"k":[41,45],"o":9},"floppy_disk":{"a":"Floppy Disk","b":"1F4BE","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["oldschool","technology","save","90s","80s"],"k":[25,41]},"arrow_heading_down":{"a":"Arrow Pointing Rightwards Then Curving Downwards","b":"2935-FE0F","c":"2935","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","direction","bottom"],"k":[50,16],"o":3},"flag-bt":{"a":"Bhutan Flag","b":"1F1E7-1F1F9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,12]},"rabbit":{"a":"Rabbit Face","b":"1F430","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature","pet","spring","magic","bunny"],"k":[13,26]},"church":{"a":"Church","b":"26EA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["building","religion","christ"],"k":[48,37],"o":5},"drooling_face":{"a":"Drooling Face","b":"1F924","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["face"],"k":[38,27],"o":9},"flag-bv":{"a":"Bouvet Island Flag","b":"1F1E7-1F1FB","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,13]},"mosque":{"a":"Mosque","b":"1F54C","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["islam","worship","minaret"],"k":[28,15],"o":8},"rabbit2":{"a":"Rabbit","b":"1F407","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature","pet","magic","spring"],"k":[12,37]},"hotdog":{"a":"Hot Dog","b":"1F32D","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["food","frankfurter"],"k":[6,35],"o":8},"martial_arts_uniform":{"a":"Martial Arts Uniform","b":"1F94B","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["judo","karate","taekwondo"],"k":[41,46],"o":9},"arrows_clockwise":{"a":"Clockwise Downwards and Upwards Open Circle Arrows","b":"1F503","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sync","cycle","round","repeat"],"k":[27,5]},"cd":{"a":"Optical Disc","b":"1F4BF","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["technology","dvd","disk","disc","90s"],"k":[25,42]},"arrows_counterclockwise":{"a":"Anticlockwise Downwards and Upwards Open Circle Arrows","b":"1F504","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","sync","cycle"],"k":[27,6]},"sandwich":{"a":"Sandwich","b":"1F96A","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,22],"o":10},"chipmunk":{"a":"Chipmunk","b":"1F43F-FE0F","c":"1F43F","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["animal","nature","rodent","squirrel"],"k":[13,41],"o":7},"synagogue":{"a":"Synagogue","b":"1F54D","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["judaism","worship","temple","jewish"],"k":[28,16],"o":8},"unamused":{"a":"Unamused Face","b":"1F612","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["indifference","bored","straight face","serious","sarcasm"],"k":[30,42],"m":":("},"goal_net":{"a":"Goal Net","b":"1F945","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["sports"],"k":[41,41],"o":9},"flag-bw":{"a":"Botswana Flag","b":"1F1E7-1F1FC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,14]},"dvd":{"a":"Dvd","b":"1F4C0","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["cd","disk","disc"],"k":[25,43]},"hedgehog":{"a":"Hedgehog","b":"1F994","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,44],"o":10},"dart":{"a":"Direct Hit","b":"1F3AF","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["game","play","bar"],"k":[9,9]},"taco":{"a":"Taco","b":"1F32E","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["food","mexican"],"k":[6,36],"o":8},"back":{"a":"Back with Leftwards Arrow Above","b":"1F519","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["arrow","words","return"],"k":[27,27]},"flag-by":{"a":"Belarus Flag","b":"1F1E7-1F1FE","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,15]},"shinto_shrine":{"a":"Shinto Shrine","b":"26E9-FE0F","c":"26E9","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["temple","japan","kyoto"],"k":[48,36],"o":5},"movie_camera":{"a":"Movie Camera","b":"1F3A5","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["film","record"],"k":[8,51]},"sweat":{"a":"Face with Cold Sweat","b":"1F613","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","hot","sad","tired","exercise"],"k":[30,43]},"burrito":{"a":"Burrito","b":"1F32F","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["food","mexican"],"k":[6,37],"o":8},"flag-bz":{"a":"Belize Flag","b":"1F1E7-1F1FF","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,16]},"pensive":{"a":"Pensive Face","b":"1F614","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","sad","depressed","upset"],"k":[30,44]},"kaaba":{"a":"Kaaba","b":"1F54B","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["mecca","mosque","islam"],"k":[28,14],"o":8},"film_frames":{"a":"Film Frames","b":"1F39E-FE0F","c":"1F39E","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[8,44],"o":7},"bat":{"a":"Bat","b":"1F987","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["animal","nature","blind","vampire"],"k":[42,31],"o":9},"golf":{"a":"Flag in Hole","b":"26F3","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sports","business","flag","hole","summer"],"k":[48,41],"o":5},"end":{"a":"End with Leftwards Arrow Above","b":"1F51A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["words","arrow"],"k":[27,28]},"film_projector":{"a":"Film Projector","b":"1F4FD-FE0F","c":"1F4FD","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["video","tape","record","movie"],"k":[27,0],"o":7},"bear":{"a":"Bear Face","b":"1F43B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature","wild"],"k":[13,37]},"ice_skate":{"a":"Ice Skate","b":"26F8-FE0F","c":"26F8","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["sports"],"k":[48,45],"o":5},"fountain":{"a":"Fountain","b":"26F2","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["photo","summer","water","fresh"],"k":[48,40],"o":5},"confused":{"a":"Confused Face","b":"1F615","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","indifference","huh","weird","hmmm",":/"],"k":[30,45],"l":[":\\\\",":-\\\\",":/",":-/"]},"flag-ca":{"a":"Canada Flag","b":"1F1E8-1F1E6","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,17]},"on":{"a":"On with Exclamation Mark with Left Right Arrow Above","b":"1F51B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["arrow","words"],"k":[27,29]},"stuffed_flatbread":{"a":"Stuffed Flatbread","b":"1F959","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["food","flatbread","stuffed","gyro"],"k":[42,5],"o":9},"soon":{"a":"Soon with Rightwards Arrow Above","b":"1F51C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["arrow","words"],"k":[27,30]},"upside_down_face":{"a":"Upside-Down Face","b":"1F643","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["face","flipped","silly","smile"],"k":[31,39],"o":8},"fishing_pole_and_fish":{"a":"Fishing Pole and Fish","b":"1F3A3","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","hobby","summer"],"k":[8,49]},"tent":{"a":"Tent","b":"26FA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["photo","camping","outdoors"],"k":[49,12],"o":5},"clapper":{"a":"Clapper Board","b":"1F3AC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["movie","film","record"],"k":[9,6]},"egg":{"a":"Egg","b":"1F95A","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["food","chicken","breakfast"],"k":[42,6],"o":9},"flag-cc":{"a":"Cocos (keeling) Islands Flag","b":"1F1E8-1F1E8","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,18]},"koala":{"a":"Koala","b":"1F428","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature"],"k":[13,18]},"foggy":{"a":"Foggy","b":"1F301","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["photo","mountain"],"k":[5,45]},"tv":{"a":"Television","b":"1F4FA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["technology","program","oldschool","show","television"],"k":[26,49]},"panda_face":{"a":"Panda Face","b":"1F43C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature","panda"],"k":[13,38]},"fried_egg":{"a":"Cooking","b":"1F373","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","breakfast","kitchen","egg"],"k":[8,1],"n":["cooking"]},"top":{"a":"Top with Upwards Arrow Above","b":"1F51D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["words","blue-square"],"k":[27,31]},"flag-cd":{"a":"Congo - Kinshasa Flag","b":"1F1E8-1F1E9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,19]},"money_mouth_face":{"a":"Money-Mouth Face","b":"1F911","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["face","rich","dollar","money"],"k":[37,25],"o":8},"running_shirt_with_sash":{"a":"Running Shirt with Sash","b":"1F3BD","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["play","pageant"],"k":[9,23]},"astonished":{"a":"Astonished Face","b":"1F632","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","xox","surprised","poisoned"],"k":[31,22]},"feet":{"a":"Paw Prints","b":"1F43E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[13,40],"n":["paw_prints"]},"camera":{"a":"Camera","b":"1F4F7","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["gadgets","photography"],"k":[26,46]},"flag-cf":{"a":"Central African Republic Flag","b":"1F1E8-1F1EB","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,20]},"place_of_worship":{"a":"Place of Worship","b":"1F6D0","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["religion","church","temple","prayer"],"k":[37,5],"o":8},"night_with_stars":{"a":"Night with Stars","b":"1F303","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["evening","city","downtown"],"k":[5,47]},"ski":{"a":"Ski and Ski Boot","b":"1F3BF","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sports","winter","cold","snow"],"k":[9,25]},"shallow_pan_of_food":{"a":"Shallow Pan of Food","b":"1F958","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["food","cooking","casserole","paella"],"k":[42,4],"o":9},"camera_with_flash":{"a":"Camera with Flash","b":"1F4F8","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[26,47],"o":7},"sunrise_over_mountains":{"a":"Sunrise over Mountains","b":"1F304","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["view","vacation","photo"],"k":[5,48]},"turkey":{"a":"Turkey","b":"1F983","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["animal","bird"],"k":[42,27],"o":8},"white_frowning_face":{"a":"White Frowning Face","b":"2639-FE0F","c":"2639","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[47,40],"o":1},"flag-cg":{"a":"Congo - Brazzaville Flag","b":"1F1E8-1F1EC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,21]},"stew":{"a":"Pot of Food","b":"1F372","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","meat","soup"],"k":[8,0]},"sled":{"a":"Sled","b":"1F6F7","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[37,22],"o":10},"atom_symbol":{"a":"Atom Symbol","b":"269B-FE0F","c":"269B","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["science","physics","chemistry"],"k":[48,18],"o":4},"curling_stone":{"a":"Curling Stone","b":"1F94C","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[41,47],"o":10},"slightly_frowning_face":{"a":"Slightly Frowning Face","b":"1F641","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["face","frowning","disappointed","sad","upset"],"k":[31,37],"o":7},"sunrise":{"a":"Sunrise","b":"1F305","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["morning","view","vacation","photo"],"k":[5,49]},"om_symbol":{"a":"Om Symbol","b":"1F549-FE0F","c":"1F549","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[28,12],"o":7},"chicken":{"a":"Chicken","b":"1F414","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","cluck","nature","bird"],"k":[12,50]},"bowl_with_spoon":{"a":"Bowl with Spoon","b":"1F963","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,15],"o":10},"flag-ch":{"a":"Switzerland Flag","b":"1F1E8-1F1ED","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,22]},"video_camera":{"a":"Video Camera","b":"1F4F9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["film","record"],"k":[26,48]},"video_game":{"a":"Video Game","b":"1F3AE","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["play","console","PS4","controller"],"k":[9,8]},"rooster":{"a":"Rooster","b":"1F413","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature","chicken"],"k":[12,49]},"vhs":{"a":"Videocassette","b":"1F4FC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["record","video","oldschool","90s","80s"],"k":[26,51]},"city_sunset":{"a":"Cityscape at Dusk","b":"1F306","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["photo","evening","sky","buildings"],"k":[5,50]},"confounded":{"a":"Confounded Face","b":"1F616","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","confused","sick","unwell","oops",":S"],"k":[30,46]},"green_salad":{"a":"Green Salad","b":"1F957","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["food","healthy","lettuce"],"k":[42,3],"o":9},"star_of_david":{"a":"Star of David","b":"2721-FE0F","c":"2721","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["judaism"],"k":[49,47],"o":1},"flag-ci":{"a":"Côte D’ivoire Flag","b":"1F1E8-1F1EE","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,23]},"popcorn":{"a":"Popcorn","b":"1F37F","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["food","movie theater","films","snack"],"k":[8,13],"o":8},"city_sunrise":{"a":"Sunset over Buildings","b":"1F307","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["photo","good morning","dawn"],"k":[5,51]},"disappointed":{"a":"Disappointed Face","b":"1F61E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","sad","upset","depressed",":("],"k":[31,2],"l":["):",":(",":-("],"m":":("},"mag":{"a":"Left-Pointing Magnifying Glass","b":"1F50D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["search","zoom","find","detective"],"k":[27,15]},"hatching_chick":{"a":"Hatching Chick","b":"1F423","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","chicken","egg","born","baby","bird"],"k":[13,13]},"joystick":{"a":"Joystick","b":"1F579-FE0F","c":"1F579","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["game","play"],"k":[29,20],"o":7},"wheel_of_dharma":{"a":"Wheel of Dharma","b":"2638-FE0F","c":"2638","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["hinduism","buddhism","sikhism","jainism"],"k":[47,39],"o":1},"flag-ck":{"a":"Cook Islands Flag","b":"1F1E8-1F1F0","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,24]},"canned_food":{"a":"Canned Food","b":"1F96B","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,23],"o":10},"worried":{"a":"Worried Face","b":"1F61F","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","concern","nervous",":("],"k":[31,3]},"baby_chick":{"a":"Baby Chick","b":"1F424","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","chicken","bird"],"k":[13,14]},"flag-cl":{"a":"Chile Flag","b":"1F1E8-1F1F1","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,25]},"game_die":{"a":"Game Die","b":"1F3B2","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["dice","random","tabletop","play","luck"],"k":[9,12]},"mag_right":{"a":"Right-Pointing Magnifying Glass","b":"1F50E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["search","zoom","find","detective"],"k":[27,16]},"yin_yang":{"a":"Yin Yang","b":"262F-FE0F","c":"262F","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["balance"],"k":[47,38],"o":1},"bridge_at_night":{"a":"Bridge at Night","b":"1F309","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["photo","sanfrancisco"],"k":[6,1]},"spades":{"a":"Black Spade Suit","b":"2660-FE0F","c":"2660","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["poker","cards","suits","magic"],"k":[48,4],"o":1},"hatched_chick":{"a":"Front-Facing Baby Chick","b":"1F425","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","chicken","baby","bird"],"k":[13,15]},"flag-cm":{"a":"Cameroon Flag","b":"1F1E8-1F1F2","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,26]},"latin_cross":{"a":"Latin Cross","b":"271D-FE0F","c":"271D","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["christianity"],"k":[49,46],"o":1},"triumph":{"a":"Face with Look of Triumph","b":"1F624","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","gas","phew","proud","pride"],"k":[31,8]},"hotsprings":{"a":"Hot Springs","b":"2668-FE0F","c":"2668","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["bath","warm","relax"],"k":[48,8],"o":1},"bento":{"a":"Bento Box","b":"1F371","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","japanese","box"],"k":[7,51]},"microscope":{"a":"Microscope","b":"1F52C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["laboratory","experiment","zoomin","science","study"],"k":[27,46]},"cry":{"a":"Crying Face","b":"1F622","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","tears","sad","depressed","upset",":\'("],"k":[31,6],"l":[":\'("],"m":":\'("},"bird":{"a":"Bird","b":"1F426","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature","fly","tweet","spring"],"k":[13,16]},"cn":{"a":"China Flag","b":"1F1E8-1F1F3","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["china","chinese","prc","flag","country","nation","banner"],"k":[1,27],"n":["flag-cn"]},"telescope":{"a":"Telescope","b":"1F52D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["stars","space","zoom","science","astronomy"],"k":[27,47]},"rice_cracker":{"a":"Rice Cracker","b":"1F358","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","japanese"],"k":[7,26]},"hearts":{"a":"Black Heart Suit","b":"2665-FE0F","c":"2665","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["poker","cards","magic","suits"],"k":[48,6],"o":1},"orthodox_cross":{"a":"Orthodox Cross","b":"2626-FE0F","c":"2626","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["suppedaneum","religion"],"k":[47,35],"o":1},"milky_way":{"a":"Milky Way","b":"1F30C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["photo","space","stars"],"k":[6,4]},"rice_ball":{"a":"Rice Ball","b":"1F359","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","japanese"],"k":[7,27]},"satellite_antenna":{"a":"Satellite Antenna","b":"1F4E1","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[26,24]},"flag-co":{"a":"Colombia Flag","b":"1F1E8-1F1F4","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,28]},"carousel_horse":{"a":"Carousel Horse","b":"1F3A0","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["photo","carnival"],"k":[8,46]},"sob":{"a":"Loudly Crying Face","b":"1F62D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","cry","tears","sad","upset","depressed"],"k":[31,17],"m":":\'("},"diamonds":{"a":"Black Diamond Suit","b":"2666-FE0F","c":"2666","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["poker","cards","magic","suits"],"k":[48,7],"o":1},"star_and_crescent":{"a":"Star and Crescent","b":"262A-FE0F","c":"262A","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["islam"],"k":[47,36],"o":1},"penguin":{"a":"Penguin","b":"1F427","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature"],"k":[13,17]},"dove_of_peace":{"a":"Dove of Peace","b":"1F54A-FE0F","c":"1F54A","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[28,13],"o":7},"flag-cp":{"a":"Clipperton Island Flag","b":"1F1E8-1F1F5","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[1,29]},"ferris_wheel":{"a":"Ferris Wheel","b":"1F3A1","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["photo","carnival","londoneye"],"k":[8,47]},"clubs":{"a":"Black Club Suit","b":"2663-FE0F","c":"2663","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["poker","cards","magic","suits"],"k":[48,5],"o":1},"peace_symbol":{"a":"Peace Symbol","b":"262E-FE0F","c":"262E","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["hippie"],"k":[47,37],"o":1},"candle":{"a":"Candle","b":"1F56F-FE0F","c":"1F56F","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["fire","wax"],"k":[28,42],"o":7},"frowning":{"a":"Frowning Face with Open Mouth","b":"1F626","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","aw","what"],"k":[31,10]},"rice":{"a":"Cooked Rice","b":"1F35A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","china","asian"],"k":[7,28]},"flag-cr":{"a":"Costa Rica Flag","b":"1F1E8-1F1F7","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,30]},"roller_coaster":{"a":"Roller Coaster","b":"1F3A2","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["carnival","playground","photo","fun"],"k":[8,48]},"menorah_with_nine_branches":{"a":"Menorah with Nine Branches","b":"1F54E","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[28,17],"o":8},"black_joker":{"a":"Playing Card Black Joker","b":"1F0CF","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["poker","cards","game","play","magic"],"k":[0,15]},"eagle":{"a":"Eagle","b":"1F985","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["animal","nature","bird"],"k":[42,29],"o":9},"curry":{"a":"Curry and Rice","b":"1F35B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","spicy","hot","indian"],"k":[7,29]},"bulb":{"a":"Electric Light Bulb","b":"1F4A1","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["light","electricity","idea"],"k":[25,7]},"anguished":{"a":"Anguished Face","b":"1F627","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","stunned","nervous"],"k":[31,11],"l":["D:"]},"flag-cu":{"a":"Cuba Flag","b":"1F1E8-1F1FA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,31]},"barber":{"a":"Barber Pole","b":"1F488","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["hair","salon","style"],"k":[24,34]},"duck":{"a":"Duck","b":"1F986","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["animal","nature","bird","mallard"],"k":[42,30],"o":9},"six_pointed_star":{"a":"Six Pointed Star with Middle Dot","b":"1F52F","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["purple-square","religion","jewish","hexagram"],"k":[27,49]},"ramen":{"a":"Steaming Bowl","b":"1F35C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","japanese","noodle","chopsticks"],"k":[7,30]},"flashlight":{"a":"Electric Torch","b":"1F526","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["dark","camping","sight","night"],"k":[27,40]},"mahjong":{"a":"Mahjong Tile Red Dragon","b":"1F004","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["game","play","chinese","kanji"],"k":[0,14],"o":5},"fearful":{"a":"Fearful Face","b":"1F628","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","scared","terrified","nervous","oops","huh"],"k":[31,12]},"aries":{"a":"Aries","b":"2648","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sign","purple-square","zodiac","astrology"],"k":[47,44],"o":1},"spaghetti":{"a":"Spaghetti","b":"1F35D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","italian","noodle"],"k":[7,31]},"circus_tent":{"a":"Circus Tent","b":"1F3AA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["festival","carnival","party"],"k":[9,4]},"izakaya_lantern":{"a":"Izakaya Lantern","b":"1F3EE","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["light","paper","halloween","spooky"],"k":[12,11],"n":["lantern"]},"flag-cv":{"a":"Cape Verde Flag","b":"1F1E8-1F1FB","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,32]},"weary":{"a":"Weary Face","b":"1F629","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","tired","sleepy","sad","frustrated","upset"],"k":[31,13]},"flower_playing_cards":{"a":"Flower Playing Cards","b":"1F3B4","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["game","sunset","red"],"k":[9,14]},"owl":{"a":"Owl","b":"1F989","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["animal","nature","bird","hoot"],"k":[42,33],"o":9},"performing_arts":{"a":"Performing Arts","b":"1F3AD","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["acting","theater","drama"],"k":[9,7]},"frog":{"a":"Frog Face","b":"1F438","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature","croak","toad"],"k":[13,34]},"flag-cw":{"a":"Curaçao Flag","b":"1F1E8-1F1FC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,33]},"notebook_with_decorative_cover":{"a":"Notebook with Decorative Cover","b":"1F4D4","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["classroom","notes","record","paper","study"],"k":[26,11]},"exploding_head":{"a":"Shocked Face with Exploding Head","b":"1F92F","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[39,3],"n":["shocked_face_with_exploding_head"],"o":10},"taurus":{"a":"Taurus","b":"2649","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["purple-square","sign","zodiac","astrology"],"k":[47,45],"o":1},"sweet_potato":{"a":"Roasted Sweet Potato","b":"1F360","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","nature"],"k":[7,34]},"closed_book":{"a":"Closed Book","b":"1F4D5","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["read","library","knowledge","textbook","learn"],"k":[26,12]},"gemini":{"a":"Gemini","b":"264A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sign","zodiac","purple-square","astrology"],"k":[47,46],"o":1},"frame_with_picture":{"a":"Frame with Picture","b":"1F5BC-FE0F","c":"1F5BC","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[30,3],"o":7},"flag-cx":{"a":"Christmas Island Flag","b":"1F1E8-1F1FD","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,34]},"grimacing":{"a":"Grimacing Face","b":"1F62C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","grimace","teeth"],"k":[31,16]},"crocodile":{"a":"Crocodile","b":"1F40A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature","reptile","lizard","alligator"],"k":[12,40]},"oden":{"a":"Oden","b":"1F362","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","japanese"],"k":[7,36]},"flag-cy":{"a":"Cyprus Flag","b":"1F1E8-1F1FE","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,35]},"book":{"a":"Open Book","b":"1F4D6","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[26,13],"n":["open_book"]},"turtle":{"a":"Turtle","b":"1F422","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","slow","nature","tortoise"],"k":[13,12]},"art":{"a":"Artist Palette","b":"1F3A8","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["design","paint","draw","colors"],"k":[9,2]},"sushi":{"a":"Sushi","b":"1F363","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","fish","japanese","rice"],"k":[7,37]},"cold_sweat":{"a":"Face with Open Mouth and Cold Sweat","b":"1F630","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","nervous","sweat"],"k":[31,20]},"cancer":{"a":"Cancer","b":"264B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sign","zodiac","purple-square","astrology"],"k":[47,47],"o":1},"fried_shrimp":{"a":"Fried Shrimp","b":"1F364","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","animal","appetizer","summer"],"k":[7,38]},"slot_machine":{"a":"Slot Machine","b":"1F3B0","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["bet","gamble","vegas","fruit machine","luck","casino"],"k":[9,10]},"scream":{"a":"Face Screaming in Fear","b":"1F631","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","munch","scared","omg"],"k":[31,21]},"green_book":{"a":"Green Book","b":"1F4D7","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["read","library","knowledge","study"],"k":[26,14]},"leo":{"a":"Leo","b":"264C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sign","purple-square","zodiac","astrology"],"k":[47,48],"o":1},"flag-cz":{"a":"Czechia Flag","b":"1F1E8-1F1FF","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,36]},"lizard":{"a":"Lizard","b":"1F98E","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["animal","nature","reptile"],"k":[42,38],"o":9},"virgo":{"a":"Virgo","b":"264D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sign","zodiac","purple-square","astrology"],"k":[47,49],"o":1},"steam_locomotive":{"a":"Steam Locomotive","b":"1F682","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","vehicle","train"],"k":[34,10]},"de":{"a":"Germany Flag","b":"1F1E9-1F1EA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["german","nation","flag","country","banner"],"k":[1,37],"n":["flag-de"]},"flushed":{"a":"Flushed Face","b":"1F633","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","blush","shy","flattered"],"k":[31,23]},"blue_book":{"a":"Blue Book","b":"1F4D8","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["read","library","knowledge","learn","study"],"k":[26,15]},"snake":{"a":"Snake","b":"1F40D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","evil","nature","hiss","python"],"k":[12,43]},"fish_cake":{"a":"Fish Cake with Swirl Design","b":"1F365","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","japan","sea","beach","narutomaki","pink","swirl","kamaboko","surimi","ramen"],"k":[7,39]},"railway_car":{"a":"Railway Car","b":"1F683","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","vehicle"],"k":[34,11]},"dango":{"a":"Dango","b":"1F361","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","dessert","sweet","japanese","barbecue","meat"],"k":[7,35]},"orange_book":{"a":"Orange Book","b":"1F4D9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["read","library","knowledge","textbook","study"],"k":[26,16]},"libra":{"a":"Libra","b":"264E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sign","purple-square","zodiac","astrology"],"k":[47,50],"o":1},"dragon_face":{"a":"Dragon Face","b":"1F432","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","myth","nature","chinese","green"],"k":[13,28]},"flag-dg":{"a":"Diego Garcia Flag","b":"1F1E9-1F1EC","d":true,"e":false,"f":true,"g":true,"h":true,"i":true,"k":[1,38]},"zany_face":{"a":"Grinning Face with One Large and One Small Eye","b":"1F92A","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[38,50],"n":["grinning_face_with_one_large_and_one_small_eye"],"o":10},"books":{"a":"Books","b":"1F4DA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["literature","library","study"],"k":[26,17]},"dragon":{"a":"Dragon","b":"1F409","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","myth","nature","chinese","green"],"k":[12,39]},"flag-dj":{"a":"Djibouti Flag","b":"1F1E9-1F1EF","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,39]},"dumpling":{"a":"Dumpling","b":"1F95F","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,11],"o":10},"dizzy_face":{"a":"Dizzy Face","b":"1F635","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["spent","unconscious","xox","dizzy"],"k":[31,25]},"scorpius":{"a":"Scorpius","b":"264F","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sign","zodiac","purple-square","astrology","scorpio"],"k":[47,51],"o":1},"bullettrain_side":{"a":"High-Speed Train","b":"1F684","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","vehicle"],"k":[34,12]},"bullettrain_front":{"a":"High-Speed Train with Bullet Nose","b":"1F685","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","vehicle","speed","fast","public","travel"],"k":[34,13]},"notebook":{"a":"Notebook","b":"1F4D3","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["stationery","record","notes","paper","study"],"k":[26,10]},"fortune_cookie":{"a":"Fortune Cookie","b":"1F960","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,12],"o":10},"sagittarius":{"a":"Sagittarius","b":"2650","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sign","zodiac","purple-square","astrology"],"k":[48,0],"o":1},"sauropod":{"a":"Sauropod","b":"1F995","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,45],"o":10},"flag-dk":{"a":"Denmark Flag","b":"1F1E9-1F1F0","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,40]},"rage":{"a":"Pouting Face","b":"1F621","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["angry","mad","hate","despise"],"k":[31,5]},"ledger":{"a":"Ledger","b":"1F4D2","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["notes","paper"],"k":[26,9]},"angry":{"a":"Angry Face","b":"1F620","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["mad","face","annoyed","frustrated"],"k":[31,4],"l":[">:(",">:-("]},"t-rex":{"a":"T-Rex","b":"1F996","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,46],"o":10},"capricorn":{"a":"Capricorn","b":"2651","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sign","zodiac","purple-square","astrology"],"k":[48,1],"o":1},"takeout_box":{"a":"Takeout Box","b":"1F961","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,13],"o":10},"flag-dm":{"a":"Dominica Flag","b":"1F1E9-1F1F2","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,41]},"train2":{"a":"Train","b":"1F686","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","vehicle"],"k":[34,14]},"page_with_curl":{"a":"Page with Curl","b":"1F4C3","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["documents","office","paper"],"k":[25,46]},"whale":{"a":"Spouting Whale","b":"1F433","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature","sea","ocean"],"k":[13,29]},"face_with_symbols_on_mouth":{"a":"Serious Face with Symbols Covering Mouth","b":"1F92C","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[39,0],"n":["serious_face_with_symbols_covering_mouth"],"o":10},"flag-do":{"a":"Dominican Republic Flag","b":"1F1E9-1F1F4","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,42]},"metro":{"a":"Metro","b":"1F687","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","blue-square","mrt","underground","tube"],"k":[34,15]},"icecream":{"a":"Soft Ice Cream","b":"1F366","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","hot","dessert","summer"],"k":[7,40]},"aquarius":{"a":"Aquarius","b":"2652","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sign","purple-square","zodiac","astrology"],"k":[48,2],"o":1},"flag-dz":{"a":"Algeria Flag","b":"1F1E9-1F1FF","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,43]},"whale2":{"a":"Whale","b":"1F40B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature","sea","ocean"],"k":[12,41]},"mask":{"a":"Face with Medical Mask","b":"1F637","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","sick","ill","disease"],"k":[31,27]},"scroll":{"a":"Scroll","b":"1F4DC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["documents","ancient","history","paper"],"k":[26,19]},"shaved_ice":{"a":"Shaved Ice","b":"1F367","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["hot","dessert","summer"],"k":[7,41]},"pisces":{"a":"Pisces","b":"2653","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["purple-square","sign","zodiac","astrology"],"k":[48,3],"o":1},"light_rail":{"a":"Light Rail","b":"1F688","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","vehicle"],"k":[34,16]},"dolphin":{"a":"Dolphin","b":"1F42C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature","fish","sea","ocean","flipper","fins","beach"],"k":[13,22],"n":["flipper"]},"face_with_thermometer":{"a":"Face with Thermometer","b":"1F912","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["sick","temperature","thermometer","cold","fever"],"k":[37,26],"o":8},"flag-ea":{"a":"Ceuta & Melilla Flag","b":"1F1EA-1F1E6","d":true,"e":false,"f":true,"g":true,"h":true,"i":true,"k":[1,44]},"ophiuchus":{"a":"Ophiuchus","b":"26CE","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sign","purple-square","constellation","astrology"],"k":[48,31]},"station":{"a":"Station","b":"1F689","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","vehicle","public"],"k":[34,17]},"ice_cream":{"a":"Ice Cream","b":"1F368","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","hot","dessert"],"k":[7,42]},"page_facing_up":{"a":"Page Facing Up","b":"1F4C4","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["documents","office","paper","information"],"k":[25,47]},"doughnut":{"a":"Doughnut","b":"1F369","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","dessert","snack","sweet","donut"],"k":[7,43]},"face_with_head_bandage":{"a":"Face with Head-Bandage","b":"1F915","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["injured","clumsy","bandage","hurt"],"k":[37,29],"o":8},"fish":{"a":"Fish","b":"1F41F","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","food","nature"],"k":[13,9]},"newspaper":{"a":"Newspaper","b":"1F4F0","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["press","headline"],"k":[26,39]},"tram":{"a":"Tram","b":"1F68A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","vehicle"],"k":[34,18]},"flag-ec":{"a":"Ecuador Flag","b":"1F1EA-1F1E8","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,45]},"twisted_rightwards_arrows":{"a":"Twisted Rightwards Arrows","b":"1F500","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","shuffle","music","random"],"k":[27,2]},"flag-ee":{"a":"Estonia Flag","b":"1F1EA-1F1EA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,46]},"cookie":{"a":"Cookie","b":"1F36A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","snack","oreo","chocolate","sweet","dessert"],"k":[7,44]},"monorail":{"a":"Monorail","b":"1F69D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","vehicle"],"k":[34,37]},"tropical_fish":{"a":"Tropical Fish","b":"1F420","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","swim","ocean","beach","nemo"],"k":[13,10]},"rolled_up_newspaper":{"a":"Rolled Up Newspaper","b":"1F5DE-FE0F","c":"1F5DE","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[30,12],"o":7},"nauseated_face":{"a":"Nauseated Face","b":"1F922","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["face","vomit","gross","green","sick","throw up","ill"],"k":[38,25],"o":9},"repeat":{"a":"Clockwise Rightwards and Leftwards Open Circle Arrows","b":"1F501","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["loop","record"],"k":[27,3]},"bookmark_tabs":{"a":"Bookmark Tabs","b":"1F4D1","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["favorite","save","order","tidy"],"k":[26,8]},"repeat_one":{"a":"Clockwise Rightwards and Leftwards Open Circle Arrows with Circled One Overlay","b":"1F502","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","loop"],"k":[27,4]},"flag-eg":{"a":"Egypt Flag","b":"1F1EA-1F1EC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,47]},"mountain_railway":{"a":"Mountain Railway","b":"1F69E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","vehicle"],"k":[34,38]},"birthday":{"a":"Birthday Cake","b":"1F382","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","dessert","cake"],"k":[8,16]},"blowfish":{"a":"Blowfish","b":"1F421","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","nature","food","sea","ocean"],"k":[13,11]},"face_vomiting":{"a":"Face with Open Mouth Vomiting","b":"1F92E","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[39,2],"n":["face_with_open_mouth_vomiting"],"o":10},"arrow_forward":{"a":"Black Right-Pointing Triangle","b":"25B6-FE0F","c":"25B6","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","right","direction","play"],"k":[47,10],"o":1},"bookmark":{"a":"Bookmark","b":"1F516","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["favorite","label","save"],"k":[27,24]},"flag-eh":{"a":"Western Sahara Flag","b":"1F1EA-1F1ED","d":true,"e":false,"f":true,"g":true,"h":true,"i":true,"k":[1,48]},"shark":{"a":"Shark","b":"1F988","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["animal","nature","fish","sea","ocean","jaws","fins","beach"],"k":[42,32],"o":9},"train":{"a":"Tram Car","b":"1F68B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","vehicle","carriage","public","travel"],"k":[34,19]},"sneezing_face":{"a":"Sneezing Face","b":"1F927","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["face","gesundheit","sneeze","sick","allergy"],"k":[38,47],"o":9},"cake":{"a":"Shortcake","b":"1F370","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","dessert"],"k":[7,50]},"bus":{"a":"Bus","b":"1F68C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["car","vehicle","transportation"],"k":[34,20]},"pie":{"a":"Pie","b":"1F967","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,19],"o":10},"innocent":{"a":"Smiling Face with Halo","b":"1F607","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["face","angel","heaven","halo"],"k":[30,31]},"fast_forward":{"a":"Black Right-Pointing Double Triangle","b":"23E9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","play","speed","continue"],"k":[46,45]},"label":{"a":"Label","b":"1F3F7-FE0F","c":"1F3F7","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["sale","tag"],"k":[12,21],"o":7},"octopus":{"a":"Octopus","b":"1F419","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","creature","ocean","sea","nature","beach"],"k":[13,3]},"flag-er":{"a":"Eritrea Flag","b":"1F1EA-1F1F7","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,49]},"black_right_pointing_double_triangle_with_vertical_bar":{"a":"Black Right Pointing Double Triangle with Vertical Bar","b":"23ED-FE0F","c":"23ED","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[46,49]},"chocolate_bar":{"a":"Chocolate Bar","b":"1F36B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","snack","dessert","sweet"],"k":[7,45]},"oncoming_bus":{"a":"Oncoming Bus","b":"1F68D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["vehicle","transportation"],"k":[34,21]},"shell":{"a":"Spiral Shell","b":"1F41A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["nature","sea","beach"],"k":[13,4]},"face_with_cowboy_hat":{"a":"Face with Cowboy Hat","b":"1F920","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[38,23],"o":9},"moneybag":{"a":"Money Bag","b":"1F4B0","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["dollar","payment","coins","sale"],"k":[25,27]},"es":{"a":"Spain Flag","b":"1F1EA-1F1F8","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["spain","flag","nation","country","banner"],"k":[1,50],"n":["flag-es"]},"crab":{"a":"Crab","b":"1F980","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["animal","crustacean"],"k":[42,24],"o":8},"yen":{"a":"Banknote with Yen Sign","b":"1F4B4","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["money","sales","japanese","dollar","currency"],"k":[25,31]},"flag-et":{"a":"Ethiopia Flag","b":"1F1EA-1F1F9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[1,51]},"clown_face":{"a":"Clown Face","b":"1F921","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["face"],"k":[38,24],"o":9},"black_right_pointing_triangle_with_double_vertical_bar":{"a":"Black Right Pointing Triangle with Double Vertical Bar","b":"23EF-FE0F","c":"23EF","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[46,51]},"trolleybus":{"a":"Trolleybus","b":"1F68E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["bart","transportation","vehicle"],"k":[34,22]},"candy":{"a":"Candy","b":"1F36C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["snack","dessert","sweet","lolly"],"k":[7,46]},"lying_face":{"a":"Lying Face","b":"1F925","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["face","lie","pinocchio"],"k":[38,28],"o":9},"arrow_backward":{"a":"Black Left-Pointing Triangle","b":"25C0-FE0F","c":"25C0","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","left","direction"],"k":[47,11],"o":1},"dollar":{"a":"Banknote with Dollar Sign","b":"1F4B5","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["money","sales","bill","currency"],"k":[25,32]},"shrimp":{"a":"Shrimp","b":"1F990","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["animal","ocean","nature","seafood"],"k":[42,40],"o":9},"minibus":{"a":"Minibus","b":"1F690","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["vehicle","car","transportation"],"k":[34,24]},"flag-eu":{"a":"European Union Flag","b":"1F1EA-1F1FA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,0]},"lollipop":{"a":"Lollipop","b":"1F36D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","snack","candy","sweet"],"k":[7,47]},"squid":{"a":"Squid","b":"1F991","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["animal","nature","ocean","sea"],"k":[42,41],"o":9},"euro":{"a":"Banknote with Euro Sign","b":"1F4B6","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["money","sales","dollar","currency"],"k":[25,33]},"flag-fi":{"a":"Finland Flag","b":"1F1EB-1F1EE","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,1]},"ambulance":{"a":"Ambulance","b":"1F691","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["health","911","hospital"],"k":[34,25]},"custard":{"a":"Custard","b":"1F36E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["dessert","food"],"k":[7,48]},"shushing_face":{"a":"Face with Finger Covering Closed Lips","b":"1F92B","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[38,51],"n":["face_with_finger_covering_closed_lips"],"o":10},"rewind":{"a":"Black Left-Pointing Double Triangle","b":"23EA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["play","blue-square"],"k":[46,46]},"black_left_pointing_double_triangle_with_vertical_bar":{"a":"Black Left Pointing Double Triangle with Vertical Bar","b":"23EE-FE0F","c":"23EE","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[46,50]},"face_with_hand_over_mouth":{"a":"Smiling Face with Smiling Eyes and Hand Covering Mouth","b":"1F92D","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[39,1],"n":["smiling_face_with_smiling_eyes_and_hand_covering_mouth"],"o":10},"flag-fj":{"a":"Fiji Flag","b":"1F1EB-1F1EF","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,2]},"honey_pot":{"a":"Honey Pot","b":"1F36F","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["bees","sweet","kitchen"],"k":[7,49]},"snail":{"a":"Snail","b":"1F40C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["slow","animal","shell"],"k":[12,42]},"pound":{"a":"Banknote with Pound Sign","b":"1F4B7","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["british","sterling","money","sales","bills","uk","england","currency"],"k":[25,34]},"fire_engine":{"a":"Fire Engine","b":"1F692","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","cars","vehicle"],"k":[34,26]},"baby_bottle":{"a":"Baby Bottle","b":"1F37C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["food","container","milk"],"k":[8,10]},"flag-fk":{"a":"Falkland Islands Flag","b":"1F1EB-1F1F0","d":true,"e":false,"f":true,"g":true,"h":true,"i":true,"k":[2,3]},"butterfly":{"a":"Butterfly","b":"1F98B","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["animal","insect","nature","caterpillar"],"k":[42,35],"o":9},"money_with_wings":{"a":"Money with Wings","b":"1F4B8","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["dollar","bills","payment","sale"],"k":[25,35]},"face_with_monocle":{"a":"Face with Monocle","b":"1F9D0","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,49],"o":10},"police_car":{"a":"Police Car","b":"1F693","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["vehicle","cars","transportation","law","legal","enforcement"],"k":[34,27]},"arrow_up_small":{"a":"Up-Pointing Small Red Triangle","b":"1F53C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","triangle","direction","point","forward","top"],"k":[28,10]},"flag-fm":{"a":"Micronesia Flag","b":"1F1EB-1F1F2","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,4]},"glass_of_milk":{"a":"Glass of Milk","b":"1F95B","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,7],"o":9},"credit_card":{"a":"Credit Card","b":"1F4B3","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["money","sales","dollar","bill","payment","shopping"],"k":[25,30]},"oncoming_police_car":{"a":"Oncoming Police Car","b":"1F694","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["vehicle","law","legal","enforcement","911"],"k":[34,28]},"bug":{"a":"Bug","b":"1F41B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","insect","nature","worm"],"k":[13,5]},"nerd_face":{"a":"Nerd Face","b":"1F913","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["face","nerdy","geek","dork"],"k":[37,27],"o":8},"arrow_double_up":{"a":"Black Up-Pointing Double Triangle","b":"23EB","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","direction","top"],"k":[46,47]},"chart":{"a":"Chart with Upwards Trend and Yen Sign","b":"1F4B9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["green-square","graph","presentation","stats"],"k":[25,36]},"flag-fo":{"a":"Faroe Islands Flag","b":"1F1EB-1F1F4","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,5]},"ant":{"a":"Ant","b":"1F41C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","insect","nature","bug"],"k":[13,6]},"arrow_down_small":{"a":"Down-Pointing Small Red Triangle","b":"1F53D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","direction","bottom"],"k":[28,11]},"smiling_imp":{"a":"Smiling Face with Horns","b":"1F608","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["devil","horns"],"k":[30,32]},"taxi":{"a":"Taxi","b":"1F695","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["uber","vehicle","cars","transportation"],"k":[34,29]},"coffee":{"a":"Hot Beverage","b":"2615","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["beverage","caffeine","latte","espresso"],"k":[47,24],"o":4},"fr":{"a":"France Flag","b":"1F1EB-1F1F7","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["banner","flag","nation","france","french","country"],"k":[2,6],"n":["flag-fr"]},"oncoming_taxi":{"a":"Oncoming Taxi","b":"1F696","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["vehicle","cars","uber"],"k":[34,30]},"arrow_double_down":{"a":"Black Down-Pointing Double Triangle","b":"23EC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","direction","bottom"],"k":[46,48]},"imp":{"a":"Imp","b":"1F47F","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["devil","angry","horns"],"k":[22,51]},"currency_exchange":{"a":"Currency Exchange","b":"1F4B1","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["money","sales","dollar","travel"],"k":[25,28]},"tea":{"a":"Teacup Without Handle","b":"1F375","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["drink","bowl","breakfast","green","british"],"k":[8,3]},"bee":{"a":"Honeybee","b":"1F41D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[13,7],"n":["honeybee"]},"heavy_dollar_sign":{"a":"Heavy Dollar Sign","b":"1F4B2","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["money","sales","payment","currency","buck"],"k":[25,29]},"car":{"a":"Automobile","b":"1F697","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[34,31],"n":["red_car"]},"sake":{"a":"Sake Bottle and Cup","b":"1F376","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["wine","drink","drunk","beverage","japanese","alcohol","booze"],"k":[8,4]},"flag-ga":{"a":"Gabon Flag","b":"1F1EC-1F1E6","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,7]},"beetle":{"a":"Lady Beetle","b":"1F41E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","insect","nature","ladybug"],"k":[13,8]},"japanese_ogre":{"a":"Japanese Ogre","b":"1F479","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["monster","red","mask","halloween","scary","creepy","devil","demon","japanese","ogre"],"k":[22,40]},"double_vertical_bar":{"a":"Double Vertical Bar","b":"23F8-FE0F","c":"23F8","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[47,4],"o":7},"champagne":{"a":"Bottle with Popping Cork","b":"1F37E","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["drink","wine","bottle","celebration"],"k":[8,12],"o":8},"japanese_goblin":{"a":"Japanese Goblin","b":"1F47A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["red","evil","mask","monster","scary","creepy","japanese","goblin"],"k":[22,41]},"black_square_for_stop":{"a":"Black Square for Stop","b":"23F9-FE0F","c":"23F9","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[47,5],"o":7},"oncoming_automobile":{"a":"Oncoming Automobile","b":"1F698","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["car","vehicle","transportation"],"k":[34,32]},"email":{"a":"Envelope","b":"2709-FE0F","c":"2709","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["letter","postal","inbox","communication"],"k":[49,17],"n":["envelope"],"o":1},"cricket":{"a":"Cricket","b":"1F997","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["sports"],"k":[42,47],"o":10},"gb":{"a":"United Kingdom Flag","b":"1F1EC-1F1E7","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,8],"n":["uk","flag-gb"]},"black_circle_for_record":{"a":"Black Circle for Record","b":"23FA-FE0F","c":"23FA","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[47,6],"o":7},"flag-gd":{"a":"Grenada Flag","b":"1F1EC-1F1E9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,9]},"spider":{"a":"Spider","b":"1F577-FE0F","c":"1F577","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["animal","arachnid"],"k":[29,18],"o":7},"blue_car":{"a":"Recreational Vehicle","b":"1F699","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","vehicle"],"k":[34,33]},"skull":{"a":"Skull","b":"1F480","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["dead","skeleton","creepy","death"],"k":[23,0]},"e-mail":{"a":"E-Mail Symbol","b":"1F4E7","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["communication","inbox"],"k":[26,30]},"wine_glass":{"a":"Wine Glass","b":"1F377","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["drink","beverage","drunk","alcohol","booze"],"k":[8,5]},"spider_web":{"a":"Spider Web","b":"1F578-FE0F","c":"1F578","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["animal","insect","arachnid","silk"],"k":[29,19],"o":7},"cocktail":{"a":"Cocktail Glass","b":"1F378","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["drink","drunk","alcohol","beverage","booze","mojito"],"k":[8,6]},"skull_and_crossbones":{"a":"Skull and Crossbones","b":"2620-FE0F","c":"2620","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["poison","danger","deadly","scary","death","pirate","evil"],"k":[47,32],"o":1},"flag-ge":{"a":"Georgia Flag","b":"1F1EC-1F1EA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,10]},"eject":{"a":"Eject","b":"23CF-FE0F","c":"23CF","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[46,44],"o":4},"truck":{"a":"Delivery Truck","b":"1F69A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["cars","transportation"],"k":[34,34]},"incoming_envelope":{"a":"Incoming Envelope","b":"1F4E8","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["email","inbox"],"k":[26,31]},"tropical_drink":{"a":"Tropical Drink","b":"1F379","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["beverage","cocktail","summer","beach","alcohol","booze","mojito"],"k":[8,7]},"scorpion":{"a":"Scorpion","b":"1F982","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["animal","arachnid"],"k":[42,26],"o":8},"cinema":{"a":"Cinema","b":"1F3A6","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","record","film","movie","curtain","stage","theater"],"k":[9,0]},"articulated_lorry":{"a":"Articulated Lorry","b":"1F69B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["vehicle","cars","transportation","express"],"k":[34,35]},"envelope_with_arrow":{"a":"Envelope with Downwards Arrow Above","b":"1F4E9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["email","communication"],"k":[26,32]},"ghost":{"a":"Ghost","b":"1F47B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["halloween","spooky","scary"],"k":[22,42]},"flag-gf":{"a":"French Guiana Flag","b":"1F1EC-1F1EB","d":true,"e":false,"f":true,"g":true,"h":true,"i":true,"k":[2,11]},"bouquet":{"a":"Bouquet","b":"1F490","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["flowers","nature","spring"],"k":[24,42]},"tractor":{"a":"Tractor","b":"1F69C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["vehicle","car","farming","agriculture"],"k":[34,36]},"beer":{"a":"Beer Mug","b":"1F37A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],"k":[8,8]},"outbox_tray":{"a":"Outbox Tray","b":"1F4E4","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["inbox","email"],"k":[26,27]},"low_brightness":{"a":"Low Brightness Symbol","b":"1F505","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sun","afternoon","warm","summer"],"k":[27,7]},"alien":{"a":"Extraterrestrial Alien","b":"1F47D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["UFO","paul","weird","outer_space"],"k":[22,49]},"flag-gg":{"a":"Guernsey Flag","b":"1F1EC-1F1EC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,12]},"cherry_blossom":{"a":"Cherry Blossom","b":"1F338","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["nature","plant","spring","flower"],"k":[6,46]},"inbox_tray":{"a":"Inbox Tray","b":"1F4E5","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["email","documents"],"k":[26,28]},"flag-gh":{"a":"Ghana Flag","b":"1F1EC-1F1ED","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,13]},"bike":{"a":"Bicycle","b":"1F6B2","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sports","bicycle","exercise","hipster"],"k":[35,23]},"space_invader":{"a":"Alien Monster","b":"1F47E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["game","arcade","play"],"k":[22,50]},"beers":{"a":"Clinking Beer Mugs","b":"1F37B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],"k":[8,9]},"high_brightness":{"a":"High Brightness Symbol","b":"1F506","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sun","light"],"k":[27,8]},"package":{"a":"Package","b":"1F4E6","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["mail","gift","cardboard","box","moving"],"k":[26,29]},"scooter":{"a":"Scooter","b":"1F6F4","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[37,19],"o":9},"white_flower":{"a":"White Flower","b":"1F4AE","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["japanese","spring"],"k":[25,25]},"clinking_glasses":{"a":"Clinking Glasses","b":"1F942","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["beverage","drink","party","alcohol","celebrate","cheers"],"k":[41,38],"o":9},"robot_face":{"a":"Robot Face","b":"1F916","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[37,30],"o":8},"signal_strength":{"a":"Antenna with Bars","b":"1F4F6","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["blue-square","reception","phone","internet","connection","wifi","bluetooth","bars"],"k":[26,45]},"flag-gi":{"a":"Gibraltar Flag","b":"1F1EC-1F1EE","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,14]},"flag-gl":{"a":"Greenland Flag","b":"1F1EC-1F1F1","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,15]},"motor_scooter":{"a":"Motor Scooter","b":"1F6F5","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["vehicle","vespa","sasha"],"k":[37,20],"o":9},"mailbox":{"a":"Closed Mailbox with Raised Flag","b":"1F4EB","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["email","inbox","communication"],"k":[26,34]},"vibration_mode":{"a":"Vibration Mode","b":"1F4F3","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["orange-square","phone"],"k":[26,42]},"hankey":{"a":"Pile of Poo","b":"1F4A9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[25,15],"n":["poop","shit"]},"rosette":{"a":"Rosette","b":"1F3F5-FE0F","c":"1F3F5","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["flower","decoration","military"],"k":[12,20],"o":7},"tumbler_glass":{"a":"Tumbler Glass","b":"1F943","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["drink","beverage","drunk","alcohol","liquor","booze","bourbon","scotch","whisky","glass","shot"],"k":[41,39],"o":9},"cup_with_straw":{"a":"Cup with Straw","b":"1F964","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,16],"o":10},"flag-gm":{"a":"Gambia Flag","b":"1F1EC-1F1F2","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,16]},"mailbox_closed":{"a":"Closed Mailbox with Lowered Flag","b":"1F4EA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["email","communication","inbox"],"k":[26,33]},"mobile_phone_off":{"a":"Mobile Phone off","b":"1F4F4","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["mute","orange-square","silence","quiet"],"k":[26,43]},"busstop":{"a":"Bus Stop","b":"1F68F","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","wait"],"k":[34,23]},"smiley_cat":{"a":"Smiling Cat Face with Open Mouth","b":"1F63A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","cats","happy","smile"],"k":[31,30]},"rose":{"a":"Rose","b":"1F339","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["flowers","valentines","love","spring"],"k":[6,47]},"motorway":{"a":"Motorway","b":"1F6E3-FE0F","c":"1F6E3","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["road","cupertino","interstate","highway"],"k":[37,11],"o":7},"smile_cat":{"a":"Grinning Cat Face with Smiling Eyes","b":"1F638","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","cats","smile"],"k":[31,28]},"flag-gn":{"a":"Guinea Flag","b":"1F1EC-1F1F3","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,17]},"wilted_flower":{"a":"Wilted Flower","b":"1F940","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["plant","nature","flower"],"k":[41,36],"o":9},"mailbox_with_mail":{"a":"Open Mailbox with Raised Flag","b":"1F4EC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["email","inbox","communication"],"k":[26,35]},"chopsticks":{"a":"Chopsticks","b":"1F962","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,14],"o":10},"female_sign":{"a":"Female Sign","b":"2640-FE0F","c":"2640","d":false,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[47,42],"o":1},"mailbox_with_no_mail":{"a":"Open Mailbox with Lowered Flag","b":"1F4ED","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["email","inbox"],"k":[26,36]},"knife_fork_plate":{"a":"Knife Fork Plate","b":"1F37D-FE0F","c":"1F37D","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[8,11],"o":7},"hibiscus":{"a":"Hibiscus","b":"1F33A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["plant","vegetable","flowers","beach"],"k":[6,48]},"flag-gp":{"a":"Guadeloupe Flag","b":"1F1EC-1F1F5","d":true,"e":false,"f":true,"g":true,"h":true,"i":true,"k":[2,18]},"railway_track":{"a":"Railway Track","b":"1F6E4-FE0F","c":"1F6E4","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["train","transportation"],"k":[37,12],"o":7},"male_sign":{"a":"Male Sign","b":"2642-FE0F","c":"2642","d":false,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[47,43],"o":1},"joy_cat":{"a":"Cat Face with Tears of Joy","b":"1F639","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","cats","haha","happy","tears"],"k":[31,29]},"fuelpump":{"a":"Fuel Pump","b":"26FD","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["gas station","petroleum"],"k":[49,13],"o":5},"sunflower":{"a":"Sunflower","b":"1F33B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["nature","plant","fall"],"k":[6,49]},"postbox":{"a":"Postbox","b":"1F4EE","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["email","letter","envelope"],"k":[26,37]},"flag-gq":{"a":"Equatorial Guinea Flag","b":"1F1EC-1F1F6","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,19]},"heart_eyes_cat":{"a":"Smiling Cat Face with Heart-Shaped Eyes","b":"1F63B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","love","like","affection","cats","valentines","heart"],"k":[31,31]},"fork_and_knife":{"a":"Fork and Knife","b":"1F374","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["cutlery","kitchen"],"k":[8,2]},"medical_symbol":{"a":"Medical Symbol","b":"2695-FE0F","c":"2695","d":false,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[48,14],"n":["staff_of_aesculapius"],"o":4},"recycle":{"a":"Black Universal Recycling Symbol","b":"267B-FE0F","c":"267B","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["arrow","environment","garbage","trash"],"k":[48,9],"o":3},"spoon":{"a":"Spoon","b":"1F944","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["cutlery","kitchen","tableware"],"k":[41,40],"o":9},"blossom":{"a":"Blossom","b":"1F33C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["nature","flowers","yellow"],"k":[6,50]},"rotating_light":{"a":"Police Cars Revolving Light","b":"1F6A8","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["police","ambulance","911","emergency","alert","error","pinged","law","legal"],"k":[35,13]},"smirk_cat":{"a":"Cat Face with Wry Smile","b":"1F63C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","cats","smirk"],"k":[31,32]},"ballot_box_with_ballot":{"a":"Ballot Box with Ballot","b":"1F5F3-FE0F","c":"1F5F3","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[30,17],"o":7},"flag-gr":{"a":"Greece Flag","b":"1F1EC-1F1F7","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,20]},"kissing_cat":{"a":"Kissing Cat Face with Closed Eyes","b":"1F63D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","cats","kiss"],"k":[31,33]},"pencil2":{"a":"Pencil","b":"270F-FE0F","c":"270F","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["stationery","write","paper","writing","school","study"],"k":[49,42],"o":1},"traffic_light":{"a":"Horizontal Traffic Light","b":"1F6A5","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","signal"],"k":[35,10]},"fleur_de_lis":{"a":"Fleur De Lis","b":"269C-FE0F","c":"269C","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["decorative","scout"],"k":[48,19],"o":4},"tulip":{"a":"Tulip","b":"1F337","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["flowers","plant","nature","summer","spring"],"k":[6,45]},"hocho":{"a":"Hocho","b":"1F52A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["knife","blade","cutlery","kitchen","weapon"],"k":[27,44],"n":["knife"]},"flag-gs":{"a":"South Georgia & South Sandwich Islands Flag","b":"1F1EC-1F1F8","d":true,"e":false,"f":true,"g":true,"h":true,"i":true,"k":[2,21]},"seedling":{"a":"Seedling","b":"1F331","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["plant","nature","grass","lawn","spring"],"k":[6,39]},"amphora":{"a":"Amphora","b":"1F3FA","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["vase","jar"],"k":[12,24],"o":8},"scream_cat":{"a":"Weary Cat Face","b":"1F640","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","cats","munch","scared","scream"],"k":[31,36]},"vertical_traffic_light":{"a":"Vertical Traffic Light","b":"1F6A6","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","driving"],"k":[35,11]},"black_nib":{"a":"Black Nib","b":"2712-FE0F","c":"2712","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["pen","stationery","writing","write"],"k":[49,43],"o":1},"flag-gt":{"a":"Guatemala Flag","b":"1F1EC-1F1F9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,22]},"trident":{"a":"Trident Emblem","b":"1F531","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["weapon","spear"],"k":[27,51]},"flag-gu":{"a":"Guam Flag","b":"1F1EC-1F1FA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,23]},"name_badge":{"a":"Name Badge","b":"1F4DB","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["fire","forbid"],"k":[26,18]},"construction":{"a":"Construction Sign","b":"1F6A7","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["wip","progress","caution","warning"],"k":[35,12]},"lower_left_fountain_pen":{"a":"Lower Left Fountain Pen","b":"1F58B-FE0F","c":"1F58B","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[29,29],"o":7},"evergreen_tree":{"a":"Evergreen Tree","b":"1F332","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["plant","nature"],"k":[6,40]},"crying_cat_face":{"a":"Crying Cat Face","b":"1F63F","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","tears","weep","sad","cats","upset","cry"],"k":[31,35]},"flag-gw":{"a":"Guinea-Bissau Flag","b":"1F1EC-1F1FC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,24]},"lower_left_ballpoint_pen":{"a":"Lower Left Ballpoint Pen","b":"1F58A-FE0F","c":"1F58A","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[29,28],"o":7},"pouting_cat":{"a":"Pouting Cat Face","b":"1F63E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","cats"],"k":[31,34]},"deciduous_tree":{"a":"Deciduous Tree","b":"1F333","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["plant","nature"],"k":[6,41]},"octagonal_sign":{"a":"Octagonal Sign","b":"1F6D1","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[37,6],"o":9},"beginner":{"a":"Japanese Symbol for Beginner","b":"1F530","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["badge","shield"],"k":[27,50]},"flag-gy":{"a":"Guyana Flag","b":"1F1EC-1F1FE","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,25]},"lower_left_paintbrush":{"a":"Lower Left Paintbrush","b":"1F58C-FE0F","c":"1F58C","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[29,30],"o":7},"o":{"a":"Heavy Large Circle","b":"2B55","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["circle","round"],"k":[50,23],"o":5},"palm_tree":{"a":"Palm Tree","b":"1F334","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["plant","vegetable","nature","summer","beach","mojito","tropical"],"k":[6,42]},"anchor":{"a":"Anchor","b":"2693","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["ship","ferry","sea","boat"],"k":[48,12],"o":4},"see_no_evil":{"a":"See-No-Evil Monkey","b":"1F648","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["monkey","animal","nature","haha"],"k":[32,43]},"boat":{"a":"Sailboat","b":"26F5","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[48,43],"n":["sailboat"],"o":5},"white_check_mark":{"a":"White Heavy Check Mark","b":"2705","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["green-square","ok","agree","vote","election","answer","tick"],"k":[49,15]},"flag-hk":{"a":"Hong Kong Sar China Flag","b":"1F1ED-1F1F0","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,26]},"lower_left_crayon":{"a":"Lower Left Crayon","b":"1F58D-FE0F","c":"1F58D","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[29,31],"o":7},"hear_no_evil":{"a":"Hear-No-Evil Monkey","b":"1F649","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["animal","monkey","nature"],"k":[32,44]},"cactus":{"a":"Cactus","b":"1F335","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["vegetable","plant","nature"],"k":[6,43]},"ear_of_rice":{"a":"Ear of Rice","b":"1F33E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["nature","plant"],"k":[7,0]},"speak_no_evil":{"a":"Speak-No-Evil Monkey","b":"1F64A","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["monkey","animal","nature","omg"],"k":[32,45]},"flag-hm":{"a":"Heard & Mcdonald Islands Flag","b":"1F1ED-1F1F2","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,27]},"ballot_box_with_check":{"a":"Ballot Box with Check","b":"2611-FE0F","c":"2611","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["ok","agree","confirm","black-square","vote","election","yes","tick"],"k":[47,22],"o":1},"canoe":{"a":"Canoe","b":"1F6F6","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["boat","paddle","water","ship"],"k":[37,21],"o":9},"memo":{"a":"Memo","b":"1F4DD","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["write","documents","stationery","pencil","paper","writing","legal","exam","quiz","test","study","compose"],"k":[26,20],"n":["pencil"]},"herb":{"a":"Herb","b":"1F33F","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["vegetable","plant","medicine","weed","grass","lawn"],"k":[7,1]},"flag-hn":{"a":"Honduras Flag","b":"1F1ED-1F1F3","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,28]},"heavy_check_mark":{"a":"Heavy Check Mark","b":"2714-FE0F","c":"2714","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["ok","nike","answer","yes","tick"],"k":[49,44],"o":1},"briefcase":{"a":"Briefcase","b":"1F4BC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["business","documents","work","law","legal","job","career"],"k":[25,39]},"speedboat":{"a":"Speedboat","b":"1F6A4","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["ship","transportation","vehicle","summer"],"k":[35,9]},"baby":{"skin_variations":{"1F3FB":{"unified":"1F476-1F3FB","non_qualified":null,"image":"1f476-1f3fb.png","sheet_x":22,"sheet_y":11,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F476-1F3FC","non_qualified":null,"image":"1f476-1f3fc.png","sheet_x":22,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F476-1F3FD","non_qualified":null,"image":"1f476-1f3fd.png","sheet_x":22,"sheet_y":13,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F476-1F3FE","non_qualified":null,"image":"1f476-1f3fe.png","sheet_x":22,"sheet_y":14,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F476-1F3FF","non_qualified":null,"image":"1f476-1f3ff.png","sheet_x":22,"sheet_y":15,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true}},"a":"Baby","b":"1F476","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["child","boy","girl","toddler"],"k":[22,10]},"heavy_multiplication_x":{"a":"Heavy Multiplication X","b":"2716-FE0F","c":"2716","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["math","calculation"],"k":[49,45],"o":1},"child":{"skin_variations":{"1F3FB":{"unified":"1F9D2-1F3FB","non_qualified":null,"image":"1f9d2-1f3fb.png","sheet_x":43,"sheet_y":5,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F9D2-1F3FC","non_qualified":null,"image":"1f9d2-1f3fc.png","sheet_x":43,"sheet_y":6,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F9D2-1F3FD","non_qualified":null,"image":"1f9d2-1f3fd.png","sheet_x":43,"sheet_y":7,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F9D2-1F3FE","non_qualified":null,"image":"1f9d2-1f3fe.png","sheet_x":43,"sheet_y":8,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F9D2-1F3FF","non_qualified":null,"image":"1f9d2-1f3ff.png","sheet_x":43,"sheet_y":9,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false}},"a":"Child","b":"1F9D2","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[43,4],"o":10},"shamrock":{"a":"Shamrock","b":"2618-FE0F","c":"2618","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["vegetable","plant","nature","irish","clover"],"k":[47,25],"o":4},"passenger_ship":{"a":"Passenger Ship","b":"1F6F3-FE0F","c":"1F6F3","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["yacht","cruise","ferry"],"k":[37,18],"o":7},"flag-hr":{"a":"Croatia Flag","b":"1F1ED-1F1F7","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,29]},"file_folder":{"a":"File Folder","b":"1F4C1","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["documents","business","office"],"k":[25,44]},"x":{"a":"Cross Mark","b":"274C","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["no","delete","remove","cancel"],"k":[50,1]},"four_leaf_clover":{"a":"Four Leaf Clover","b":"1F340","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["vegetable","plant","nature","lucky","irish"],"k":[7,2]},"open_file_folder":{"a":"Open File Folder","b":"1F4C2","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["documents","load"],"k":[25,45]},"boy":{"skin_variations":{"1F3FB":{"unified":"1F466-1F3FB","non_qualified":null,"image":"1f466-1f3fb.png","sheet_x":15,"sheet_y":43,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F466-1F3FC","non_qualified":null,"image":"1f466-1f3fc.png","sheet_x":15,"sheet_y":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F466-1F3FD","non_qualified":null,"image":"1f466-1f3fd.png","sheet_x":15,"sheet_y":45,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F466-1F3FE","non_qualified":null,"image":"1f466-1f3fe.png","sheet_x":15,"sheet_y":46,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F466-1F3FF","non_qualified":null,"image":"1f466-1f3ff.png","sheet_x":15,"sheet_y":47,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true}},"a":"Boy","b":"1F466","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["man","male","guy","teenager"],"k":[15,42]},"ferry":{"a":"Ferry","b":"26F4-FE0F","c":"26F4","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["boat","ship","yacht"],"k":[48,42],"o":5},"flag-ht":{"a":"Haiti Flag","b":"1F1ED-1F1F9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,30]},"girl":{"skin_variations":{"1F3FB":{"unified":"1F467-1F3FB","non_qualified":null,"image":"1f467-1f3fb.png","sheet_x":15,"sheet_y":49,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F467-1F3FC","non_qualified":null,"image":"1f467-1f3fc.png","sheet_x":15,"sheet_y":50,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F467-1F3FD","non_qualified":null,"image":"1f467-1f3fd.png","sheet_x":15,"sheet_y":51,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F467-1F3FE","non_qualified":null,"image":"1f467-1f3fe.png","sheet_x":16,"sheet_y":0,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F467-1F3FF","non_qualified":null,"image":"1f467-1f3ff.png","sheet_x":16,"sheet_y":1,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true}},"a":"Girl","b":"1F467","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["female","woman","teenager"],"k":[15,48]},"negative_squared_cross_mark":{"a":"Negative Squared Cross Mark","b":"274E","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["x","green-square","no","deny"],"k":[50,2]},"flag-hu":{"a":"Hungary Flag","b":"1F1ED-1F1FA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,31]},"card_index_dividers":{"a":"Card Index Dividers","b":"1F5C2-FE0F","c":"1F5C2","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["organizing","business","stationery"],"k":[30,4],"o":7},"maple_leaf":{"a":"Maple Leaf","b":"1F341","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["nature","plant","vegetable","ca","fall"],"k":[7,3]},"motor_boat":{"a":"Motor Boat","b":"1F6E5-FE0F","c":"1F6E5","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["ship"],"k":[37,13],"o":7},"flag-ic":{"a":"Canary Islands Flag","b":"1F1EE-1F1E8","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,32]},"fallen_leaf":{"a":"Fallen Leaf","b":"1F342","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["nature","plant","vegetable","leaves"],"k":[7,4]},"adult":{"skin_variations":{"1F3FB":{"unified":"1F9D1-1F3FB","non_qualified":null,"image":"1f9d1-1f3fb.png","sheet_x":42,"sheet_y":51,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F9D1-1F3FC","non_qualified":null,"image":"1f9d1-1f3fc.png","sheet_x":43,"sheet_y":0,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F9D1-1F3FD","non_qualified":null,"image":"1f9d1-1f3fd.png","sheet_x":43,"sheet_y":1,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F9D1-1F3FE","non_qualified":null,"image":"1f9d1-1f3fe.png","sheet_x":43,"sheet_y":2,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F9D1-1F3FF","non_qualified":null,"image":"1f9d1-1f3ff.png","sheet_x":43,"sheet_y":3,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false}},"a":"Adult","b":"1F9D1","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[42,50],"o":10},"ship":{"a":"Ship","b":"1F6A2","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","titanic","deploy"],"k":[34,42]},"heavy_plus_sign":{"a":"Heavy Plus Sign","b":"2795","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["math","calculation","addition","more","increase"],"k":[50,9]},"date":{"a":"Calendar","b":"1F4C5","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["calendar","schedule"],"k":[25,48]},"man":{"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB","non_qualified":null,"image":"1f468-1f3fb.png","sheet_x":18,"sheet_y":12,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F468-1F3FC","non_qualified":null,"image":"1f468-1f3fc.png","sheet_x":18,"sheet_y":13,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F468-1F3FD","non_qualified":null,"image":"1f468-1f3fd.png","sheet_x":18,"sheet_y":14,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F468-1F3FE","non_qualified":null,"image":"1f468-1f3fe.png","sheet_x":18,"sheet_y":15,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F468-1F3FF","non_qualified":null,"image":"1f468-1f3ff.png","sheet_x":18,"sheet_y":16,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true}},"a":"Man","b":"1F468","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["mustache","father","dad","guy","classy","sir","moustache"],"k":[18,11]},"flag-id":{"a":"Indonesia Flag","b":"1F1EE-1F1E9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,33]},"leaves":{"a":"Leaf Fluttering in Wind","b":"1F343","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["nature","plant","tree","vegetable","grass","lawn","spring"],"k":[7,5]},"heavy_minus_sign":{"a":"Heavy Minus Sign","b":"2796","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["math","calculation","subtract","less"],"k":[50,10]},"calendar":{"a":"Tear-off Calendar","b":"1F4C6","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["schedule","date","planning"],"k":[25,49]},"airplane":{"a":"Airplane","b":"2708-FE0F","c":"2708","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["vehicle","transportation","flight","fly"],"k":[49,16],"o":1},"spiral_note_pad":{"a":"Spiral Note Pad","b":"1F5D2-FE0F","c":"1F5D2","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[30,8],"o":7},"heavy_division_sign":{"a":"Heavy Division Sign","b":"2797","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["divide","math","calculation"],"k":[50,11]},"small_airplane":{"a":"Small Airplane","b":"1F6E9-FE0F","c":"1F6E9","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"j":["flight","transportation","fly","vehicle"],"k":[37,14],"o":7},"woman":{"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB","non_qualified":null,"image":"1f469-1f3fb.png","sheet_x":20,"sheet_y":24,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F469-1F3FC","non_qualified":null,"image":"1f469-1f3fc.png","sheet_x":20,"sheet_y":25,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F469-1F3FD","non_qualified":null,"image":"1f469-1f3fd.png","sheet_x":20,"sheet_y":26,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F469-1F3FE","non_qualified":null,"image":"1f469-1f3fe.png","sheet_x":20,"sheet_y":27,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F469-1F3FF","non_qualified":null,"image":"1f469-1f3ff.png","sheet_x":20,"sheet_y":28,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true}},"a":"Woman","b":"1F469","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["female","girls","lady"],"k":[20,23]},"flag-ie":{"a":"Ireland Flag","b":"1F1EE-1F1EA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,34]},"curly_loop":{"a":"Curly Loop","b":"27B0","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["scribble","draw","shape","squiggle"],"k":[50,13]},"flag-il":{"a":"Israel Flag","b":"1F1EE-1F1F1","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,35]},"airplane_departure":{"a":"Airplane Departure","b":"1F6EB","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[37,15],"o":7},"spiral_calendar_pad":{"a":"Spiral Calendar Pad","b":"1F5D3-FE0F","c":"1F5D3","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[30,9],"o":7},"older_adult":{"skin_variations":{"1F3FB":{"unified":"1F9D3-1F3FB","non_qualified":null,"image":"1f9d3-1f3fb.png","sheet_x":43,"sheet_y":11,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F9D3-1F3FC","non_qualified":null,"image":"1f9d3-1f3fc.png","sheet_x":43,"sheet_y":12,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F9D3-1F3FD","non_qualified":null,"image":"1f9d3-1f3fd.png","sheet_x":43,"sheet_y":13,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F9D3-1F3FE","non_qualified":null,"image":"1f9d3-1f3fe.png","sheet_x":43,"sheet_y":14,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F9D3-1F3FF","non_qualified":null,"image":"1f9d3-1f3ff.png","sheet_x":43,"sheet_y":15,"added_in":"10.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false}},"a":"Older Adult","b":"1F9D3","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[43,10],"o":10},"airplane_arriving":{"a":"Airplane Arriving","b":"1F6EC","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[37,16],"o":7},"card_index":{"a":"Card Index","b":"1F4C7","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["business","stationery"],"k":[25,50]},"loop":{"a":"Double Curly Loop","b":"27BF","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["tape","cassette"],"k":[50,14]},"older_man":{"skin_variations":{"1F3FB":{"unified":"1F474-1F3FB","non_qualified":null,"image":"1f474-1f3fb.png","sheet_x":21,"sheet_y":51,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F474-1F3FC","non_qualified":null,"image":"1f474-1f3fc.png","sheet_x":22,"sheet_y":0,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F474-1F3FD","non_qualified":null,"image":"1f474-1f3fd.png","sheet_x":22,"sheet_y":1,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F474-1F3FE","non_qualified":null,"image":"1f474-1f3fe.png","sheet_x":22,"sheet_y":2,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F474-1F3FF","non_qualified":null,"image":"1f474-1f3ff.png","sheet_x":22,"sheet_y":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true}},"a":"Older Man","b":"1F474","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["human","male","men","old","elder","senior"],"k":[21,50]},"flag-im":{"a":"Isle of Man Flag","b":"1F1EE-1F1F2","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,36]},"flag-in":{"a":"India Flag","b":"1F1EE-1F1F3","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,37]},"chart_with_upwards_trend":{"a":"Chart with Upwards Trend","b":"1F4C8","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["graph","presentation","stats","recovery","business","economics","money","sales","good","success"],"k":[25,51]},"part_alternation_mark":{"a":"Part Alternation Mark","b":"303D-FE0F","c":"303D","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["graph","presentation","stats","business","economics","bad"],"k":[50,25],"o":3},"seat":{"a":"Seat","b":"1F4BA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["sit","airplane","transport","bus","flight","fly"],"k":[25,37]},"older_woman":{"skin_variations":{"1F3FB":{"unified":"1F475-1F3FB","non_qualified":null,"image":"1f475-1f3fb.png","sheet_x":22,"sheet_y":5,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FC":{"unified":"1F475-1F3FC","non_qualified":null,"image":"1f475-1f3fc.png","sheet_x":22,"sheet_y":6,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FD":{"unified":"1F475-1F3FD","non_qualified":null,"image":"1f475-1f3fd.png","sheet_x":22,"sheet_y":7,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FE":{"unified":"1F475-1F3FE","non_qualified":null,"image":"1f475-1f3fe.png","sheet_x":22,"sheet_y":8,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true},"1F3FF":{"unified":"1F475-1F3FF","non_qualified":null,"image":"1f475-1f3ff.png","sheet_x":22,"sheet_y":9,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true}},"a":"Older Woman","b":"1F475","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["human","female","women","lady","old","elder","senior"],"k":[22,4]},"eight_spoked_asterisk":{"a":"Eight Spoked Asterisk","b":"2733-FE0F","c":"2733","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["star","sparkle","green-square"],"k":[49,49],"o":1},"chart_with_downwards_trend":{"a":"Chart with Downwards Trend","b":"1F4C9","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["graph","presentation","stats","recession","business","economics","money","sales","bad","failure"],"k":[26,0]},"flag-io":{"a":"British Indian Ocean Territory Flag","b":"1F1EE-1F1F4","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,38]},"male-doctor":{"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-2695-FE0F","non_qualified":"1F468-1F3FB-200D-2695","image":"1f468-1f3fb-200d-2695-fe0f.png","sheet_x":17,"sheet_y":44,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-2695-FE0F","non_qualified":"1F468-1F3FC-200D-2695","image":"1f468-1f3fc-200d-2695-fe0f.png","sheet_x":17,"sheet_y":45,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-2695-FE0F","non_qualified":"1F468-1F3FD-200D-2695","image":"1f468-1f3fd-200d-2695-fe0f.png","sheet_x":17,"sheet_y":46,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-2695-FE0F","non_qualified":"1F468-1F3FE-200D-2695","image":"1f468-1f3fe-200d-2695-fe0f.png","sheet_x":17,"sheet_y":47,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-2695-FE0F","non_qualified":"1F468-1F3FF-200D-2695","image":"1f468-1f3ff-200d-2695-fe0f.png","sheet_x":17,"sheet_y":48,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":false,"has_img_messenger":false}},"a":"Male Doctor","b":"1F468-200D-2695-FE0F","c":"1F468-200D-2695","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[17,43]},"helicopter":{"a":"Helicopter","b":"1F681","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","vehicle","fly"],"k":[34,9]},"female-doctor":{"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-2695-FE0F","non_qualified":"1F469-1F3FB-200D-2695","image":"1f469-1f3fb-200d-2695-fe0f.png","sheet_x":20,"sheet_y":2,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-2695-FE0F","non_qualified":"1F469-1F3FC-200D-2695","image":"1f469-1f3fc-200d-2695-fe0f.png","sheet_x":20,"sheet_y":3,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-2695-FE0F","non_qualified":"1F469-1F3FD-200D-2695","image":"1f469-1f3fd-200d-2695-fe0f.png","sheet_x":20,"sheet_y":4,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-2695-FE0F","non_qualified":"1F469-1F3FE-200D-2695","image":"1f469-1f3fe-200d-2695-fe0f.png","sheet_x":20,"sheet_y":5,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":false,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-2695-FE0F","non_qualified":"1F469-1F3FF-200D-2695","image":"1f469-1f3ff-200d-2695-fe0f.png","sheet_x":20,"sheet_y":6,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":false,"has_img_messenger":false}},"a":"Female Doctor","b":"1F469-200D-2695-FE0F","c":"1F469-200D-2695","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[20,1]},"suspension_railway":{"a":"Suspension Railway","b":"1F69F","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["vehicle","transportation"],"k":[34,39]},"bar_chart":{"a":"Bar Chart","b":"1F4CA","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["graph","presentation","stats"],"k":[26,1]},"flag-iq":{"a":"Iraq Flag","b":"1F1EE-1F1F6","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,39]},"eight_pointed_black_star":{"a":"Eight Pointed Black Star","b":"2734-FE0F","c":"2734","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["orange-square","shape","polygon"],"k":[49,50],"o":1},"mountain_cableway":{"a":"Mountain Cableway","b":"1F6A0","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportation","vehicle","ski"],"k":[34,40]},"male-student":{"skin_variations":{"1F3FB":{"unified":"1F468-1F3FB-200D-1F393","non_qualified":null,"image":"1f468-1f3fb-200d-1f393.png","sheet_x":16,"sheet_y":15,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F468-1F3FC-200D-1F393","non_qualified":null,"image":"1f468-1f3fc-200d-1f393.png","sheet_x":16,"sheet_y":16,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F468-1F3FD-200D-1F393","non_qualified":null,"image":"1f468-1f3fd-200d-1f393.png","sheet_x":16,"sheet_y":17,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F468-1F3FE-200D-1F393","non_qualified":null,"image":"1f468-1f3fe-200d-1f393.png","sheet_x":16,"sheet_y":18,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F468-1F3FF-200D-1F393","non_qualified":null,"image":"1f468-1f3ff-200d-1f393.png","sheet_x":16,"sheet_y":19,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false}},"a":"Male Student","b":"1F468-200D-1F393","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[16,14]},"clipboard":{"a":"Clipboard","b":"1F4CB","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["stationery","documents"],"k":[26,2]},"flag-ir":{"a":"Iran Flag","b":"1F1EE-1F1F7","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"k":[2,40]},"sparkle":{"a":"Sparkle","b":"2747-FE0F","c":"2747","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["stars","green-square","awesome","good","fireworks"],"k":[50,0],"o":1},"female-student":{"skin_variations":{"1F3FB":{"unified":"1F469-1F3FB-200D-1F393","non_qualified":null,"image":"1f469-1f3fb-200d-1f393.png","sheet_x":18,"sheet_y":30,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FC":{"unified":"1F469-1F3FC-200D-1F393","non_qualified":null,"image":"1f469-1f3fc-200d-1f393.png","sheet_x":18,"sheet_y":31,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FD":{"unified":"1F469-1F3FD-200D-1F393","non_qualified":null,"image":"1f469-1f3fd-200d-1f393.png","sheet_x":18,"sheet_y":32,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FE":{"unified":"1F469-1F3FE-200D-1F393","non_qualified":null,"image":"1f469-1f3fe-200d-1f393.png","sheet_x":18,"sheet_y":33,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false},"1F3FF":{"unified":"1F469-1F3FF-200D-1F393","non_qualified":null,"image":"1f469-1f3ff-200d-1f393.png","sheet_x":18,"sheet_y":34,"added_in":"8.0","has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false}},"a":"Female Student","b":"1F469-200D-1F393","d":true,"e":true,"f":true,"g":true,"h":true,"i":false,"k":[18,29]},"pushpin":{"a":"Pushpin","b":"1F4CC","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["stationery","mark","here"],"k":[26,3]},"aerial_tramway":{"a":"Aerial Tramway","b":"1F6A1","d":true,"e":true,"f":true,"g":true,"h":true,"i":true,"j":["transportat