diff --git a/.gitignore b/.gitignore index 7d8d59e..a95459a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,26 @@ +*.FASL *.fasl -*.dx32fsl -*.dx64fsl -*.lx32fsl +*.lisp-temp +*.dfsl +*.pfsl +*.d64fsl +*.p64fsl *.lx64fsl -*.x86f -*~ -.#* \ No newline at end of file +*.lx32fsl +*.dx64fsl +*.dx32fsl +*.fx64fsl +*.fx32fsl +*.sx64fsl +*.sx32fsl +*.wx64fsl +*.wx32fsl +*.db +/bin/ +/storage/media/ +/storage/archive/ +/storage/snippets/ +/storage/pages/ +/static/images/favicon.* +/static/images/site-logo.* +/snapshots diff --git a/LICENSE b/LICENSE index 2071b23..05f6a1d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) +Copyright (c) 2022 Craig Oates Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.org b/README.org index 72a823f..8bcd817 100644 --- a/README.org +++ b/README.org @@ -1,9 +1,187 @@ -* Ritherdon Archive +* Nicola Ellis and Ritherdon Archive - An archive of Ritherdon. I need to speak to Nic more about what this - means. + This is an website, written in Common Lisp and built on top of the Caveman2 + framework. Its main intention is to be the digital archive for the work + produced by [[http://www.nicolaellis.com][Nicola Ellis]] during her time + working alongside [[https://ritherdon.co.uk/][Ritherdon]]. -* Project Summary + [[https://neandr.nicolaellis.com]] - This is a website written in Common Lisp and the Caveman2 framework. The - databased it uses in SQLite3 and Steel Bank Common Lisp (SBCL). +* Overview of Technology Used + + Below is a **non-exhaustive** list of the tech. used to build and run this + website: + + - [[https://lispcookbook.github.io/cl-cookbook/][Common Lisp]] + - [[https://www.quicklisp.org/beta/][Quicklisp]] + - [[Steel Bank Common Lisp][http://www.sbcl.org/]] (SBCL) + - [[https://github.com/fukamachi/caveman][Caveman2]] + - [[https://github.com/fukamachi/woo][woo]] (Common Lisp server behind Nginx) + - [[https://github.com/fukamachi/mito][Mito]] (ORM) + - [[https://github.com/fukamachi/sxql][SXQL]] (SQL Generator, used alongside Mito) + - [[https://www.sqlite.org/index.html][SQLite3]] + - [[https://github.com/mmontone/djula][Djula]] (Common Lisp port of the Django templating language) + - [[https://www.debian.org/][Debian 11]] + - [[https://www.nginx.com/][Nginx]] + - [[https://www.meilisearch.com/][Meilisearch]] (Website's Search engine) + + For a complete list of packages used by Common Lisp, look at the + [[/return-to-ritherdon/ritherdon-archive/src/branch/unstable/ritherdon-archive.asd][ritherdon-archive.asd]] file. + +* System Overview + + The complete system is broken into two services: + + 1. Ritherdon Archive (the main site) + 2. Meilisearch (the separate search system/service/instance) + + From an end-user's perspective, they shouldn't be able to tell the Meilisearch + service is part of the overall system. When an end-user uses the Search + features on the main site, the main site will make the requests to the + Meilisearch service. From there, the Meilisearch service will return its + results to the main site -- on the end-user's machine. You should see this + closed-loop in the diagram below. + + #+begin_src mermaid + graph TD + Request((Request)) --> Server + Server{Nginx} --> Archive + Server -.-> Meilisearch + Archive -. Search terms sent to server \n as their own requests .-> Request + Request -.-> Server + Meilisearch -. Results returned to Archive \n on clients machine .-> Archive + Archive --> Response((Response)) + #+end_src + + When it comes to the main site (Ritherdon Archive), it stores the archive data + in the =/storage= directory and the SQLite3 database. Both are kept + in-sync. by the main site -- as part of its feature-set. + + #+begin_src mermaid + graph TD + Request((Request \n /Response)) <--> Server + Server{Nginx} <--> Archive + Archive <-.-> DB[(Database)] + Archive <-.-> Storage[/Files in /storage directory/] + #+end_src + +* Installation + + To see what is being called, please read the [[/return-to-ritherdon/ritherdon-archive/src/branch/unstable/makefile][makefile]]. If you are unsure how + to set-up an environment for developing in Common Lisp, please use the + following link: + + - [[https://lispcookbook.github.io/cl-cookbook/getting-started.html][Common Lisp Cook Book: Getting Started]] + - [[https://docs.meilisearch.com/learn/getting_started/quick_start.html#setup-and-installation][Meilisearch Doc's]] (Install Guide) + + Otherwise, just use the makefile. + + #+begin_src bash + git clone https://git.abbether.net/return-to-ritherdon/ritherdon-archive.git + cd ritherdon-archive + sudo make install + make lisp-install + make quicklisp-add + make search-install # Installs Meilisearch. + #+end_src + + *Note:* The ~make search-install~ command adds the ~meilisearch~ binary to + =/usr/bin/=. If you want to uninstall Meilisearch, you will need to delete it + from =/usr/bin=. Run ~sudo rm /usr/bin/meilisearch~, to delete it. + +* Run System on Local Machine + + Because the system consists of two systems running in tandem, you will need to + have two terminals open to run them separately -- and see the logs for each + service. + +** Meilisearch + + Usually, you get this part of the system up and running before you get the + main site working -- mostly because of the tasks flow easier -- but it's not + essential to start this service first. + + #+begin_src bash + # Make sure meilisearch is added to your /usr/bin/ directory. + meilisearch --no-analytics + #+end_src + + If you enter =http://localhost:7700= in your browser, you should see the + meilisearch search page. Use =ctrl-c= to stop the service. + +** Main Site (Ritherdon Archive) + + To run the main site (Ritherdon Archive), start Steel Bank Common Lisp (SBCL) + by running ~rlwrap sbcl~ in your terminal. When SBCL has finished loading, run + the following, + + #+begin_src common-lisp + (ql:quicklisp :ritherdon-archive) + (search:set-filter-attributes) ; Configures the Meilisearch service. + (ritherdon-archive:start :server :woo) + #+end_src + + Then go to =http://localhost:5000= in your browser. + + To stop the program, enter ~(ritherdon-archive:stop)~ in SBCL. + +* Run System on (Prod.) Server + + This section builds on the one above (running on local machine). The main + difference is getting the system to run on Nginx and as a Systemd service. + + The first thing to do is replace the parts which say ~~ + and ~~ in the files in =/conf=. Those values are specific to + your deployment environment. At the time of writing, there should be four + files in =/conf=. They are: + + 1. =meilisearch.conf= (the config. file for Nginx) + 2. =meilisearch.service= (the .service file for Systemd) + 3. =ritherdon-archive.conf= (the config. file for Nginx) + 4. =ritherdon-archive.conf= (the .service file for Systemd) + + After you have entered your details into the =.conf= and =.service= files, + you can start to copy the files into their new locations. + +** Set-Up Meilisearch + + #+begin_src bash + # Nginx + sudo cp ~/ritherdon-archive/conf/meilisearch-prod.conf \ + /etc/nginx/sites-available/meilisearch-prod.conf + sudo ln -s /etc/nginx/sites-available/meilisearch.conf \ + /etc/nginx/sites-enabled/ + sudo systemctl restart nginx.service + + #Systemd + sudo cp ~/ritherdon-archive/conf/meilisearch.service \ + /etc/systemd/system/meilisearch.service + sudo systemctl daemon-reload + sudo systemctl enable meilisearch.service + sudo systemctl status meilisearch.service + #+end_src + +** Set-Up Ritherdon Archive (Main Site) + + #+begin_src bash + # Nginx + sudo cp ~/ritherdon-archive/conf/ritherdon-archive.conf \ + /etc/nginx/sites-available/ritherdon-archive.conf + sudo ln -s /etc/nginx/sites-available/ritherdon-archive.conf \ + /etc/nginx/sites-enabled/ + sudo systemctl restart nginx.service + + #Systemd + sudo cp ~/ritherdon-archive/conf/ritherdon-archive.service \ + /etc/systemd/system/ritherdon-archive.service + sudo systemctl daemon-reload + sudo systemctl enable ritherdon-archive.service + sudo systemctl status ritherdon-archive.service + #+end_src + +* A Note on Using Ritherdon Archive + + This README has focused only on the developer side of the project. This is + deliberate. I just haven't had the time to write any documentation on that + side of the site or is the budget there to do so. Hopefully, this will change + but at the time of writing (Nov. 2022), there is nothing in the repo's wiki. diff --git a/app.lisp b/app.lisp index 52983ed..ea7f69d 100644 --- a/app.lisp +++ b/app.lisp @@ -15,25 +15,32 @@ :*static-directory*)) (in-package :ritherdon-archive.app) -(builder - (:static - :path (lambda (path) - (if (ppcre:scan "^(?:/images/|/css/|/js/|/robot\\.txt$|/favicon\\.ico$)" path) - path - nil)) - :root *static-directory*) - (if (productionp) - nil - :accesslog) - (if (getf (config) :error-log) - `(:backtrace - :output ,(getf (config) :error-log)) - nil) - :session - (if (productionp) - nil - (lambda (app) - (lambda (env) - (let ((datafly:*trace-sql* t)) - (funcall app env))))) - *web*) +(funcall clack-errors:*clack-error-middleware* + ;; The funcall line above is added as part of the + ;; clack-errors set-up. Usually, the '(builder' line is the + ;; start of this block. + (builder + (:static + :path (lambda (path) + (if (ppcre:scan "^(?:/images/|/css/|/js/|/robot\\.txt$|/favicon\\.ico$)" path) + path + nil)) + :root *static-directory*) + (if (productionp) + nil + :accesslog) + (if (getf (config) :error-log) + `(:backtrace + :output ,(getf (config) :error-log)) + nil) + :session + (if (productionp) + nil + (lambda (app) + (lambda (env) + (let ((datafly:*trace-sql* t)) + (funcall app env))))) + *web*) + :debug (if (ritherdon-archive.config:productionp) + nil + t)) ; Added as part of clack-error-middleware. diff --git a/conf/meilisearch.conf b/conf/meilisearch.conf new file mode 100644 index 0000000..1b62afb --- /dev/null +++ b/conf/meilisearch.conf @@ -0,0 +1,8 @@ +server { + listen 80; + listen ; + server_name _; + location / { + proxy_pass http://127.0.0.1:7700; + } +} \ No newline at end of file diff --git a/conf/meilisearch.service b/conf/meilisearch.service new file mode 100644 index 0000000..9b2e89d --- /dev/null +++ b/conf/meilisearch.service @@ -0,0 +1,10 @@ +[Unit] +Description=Meilisearch +After=systemd-user-sessions.service + +[Service] +Type=simple +ExecStart=/usr/bin/meilisearch-beta --no-analytics --http-addr 127.0.0.1:7700 --env production --master-key + +[Install] +WantedBy=default.target diff --git a/conf/ritherdon-archive.conf b/conf/ritherdon-archive.conf new file mode 100644 index 0000000..d249591 --- /dev/null +++ b/conf/ritherdon-archive.conf @@ -0,0 +1,30 @@ +upstream woo { + server 127.0.0.1:5000; +} + +server { + listen 80; + server_name ; + + root ~/quicklisp/local-projects/ritherdon-archive/templates/; + + # General request handling this will match all locations + location / { + + # check if with it's a directory and there'a an index.html + # if so, rewrite the url to include it and stop processing rules. + if (-f $request_filename/index.html) { + rewrite ^(.*) $1/index.html break; + } + + # Define custom HTTP Headers to be used when proxying + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $host; + + # if the requested file does not exist then + # proxy to the woo server cluster + if (!-f $request_filename) { + proxy_pass http://woo; + } + } +} \ No newline at end of file diff --git a/conf/ritherdon-archive.service b/conf/ritherdon-archive.service new file mode 100644 index 0000000..33b8551 --- /dev/null +++ b/conf/ritherdon-archive.service @@ -0,0 +1,13 @@ +[Unit] +Description=Nicola Ellis and Ritherdon Archive website. +After = syslog.target network.target + +[Service] +ExecStart=/usr/bin/sbcl --eval '(ql:quickload :ritherdon-archive)' --eval '(setf (osicat:environment-variable "APP_ENV") "production")' --eval '(ritherdon-archive:main)' +Restart=always +RestartSec=10 +KillSignal=SIGINT +User= + +[Install] +WantedBy=multi-user.target diff --git a/db/schema.sql b/db/schema.sql deleted file mode 100644 index e69de29..0000000 diff --git a/hunchentoot-example/Makefile b/hunchentoot-example/Makefile new file mode 100644 index 0000000..74a2597 --- /dev/null +++ b/hunchentoot-example/Makefile @@ -0,0 +1,16 @@ +LISP ?= sbcl + +all: test + +run: + rlwrap $(LISP) --load run.lisp + +build: + $(LISP) --non-interactive \ + --load ritherdon-archive.asd \ + --eval '(ql:quickload :ritherdon-archive)' \ + --eval '(asdf:make :ritherdon-archive)' + +test: + $(LISP) --non-interactive \ + --load run-tests.lisp diff --git a/hunchentoot-example/README.md b/hunchentoot-example/README.md new file mode 100644 index 0000000..50ca3c8 --- /dev/null +++ b/hunchentoot-example/README.md @@ -0,0 +1,101 @@ +# ritherdon-archive + +Archive of Ritherdon and Nicola Ellis. + +# Usage + +Run from sources: + + make run + # aka sbcl --load run.lisp + +choose your lisp: + + LISP=ccl make run + +or build and run the binary: + +``` +$ make build +$ ./ritherdon-archive [name] +Hello [name] from ritherdon-archive +``` + +## Init config file + +Create a config file: + + cp config-example.lisp config.lisp + +You can override global variables (for example, the port, which can be +handy if you run the app from sources, without building a binary and +using the `--port` flag. + +The config file is `load`ed before the web server starts (see the `(main)`). + + +## Roswell integration + +Roswell is an implementation manager and [script launcher](https://github.com/roswell/roswell/wiki/Roswell-as-a-Scripting-Environment). + +A POC script is in the roswell/ directory. + +Your users can install the script with `craig/ritherdon-archive`. + +# Dev + +Load the .asd, quickload it then + +``` +CL-USER> (ritherdon-archive/web:start-app) +``` + +See also: + +- `web::load-config &key port load-init-p` + + +## Tests + +Tests are defined with [Fiveam](https://common-lisp.net/project/fiveam/docs/). + +Run them from the terminal with `make test`. You should see a failing test. + +```bash +$ make test +Running test suite TESTMAIN + Running test TEST1 f + Did 1 check. + Pass: 0 ( 0%) + Skip: 0 ( 0%) + Fail: 1 (100%) + + Failure Details: + -------------------------------- + TEST1 in TESTMAIN []: + +3 + + evaluated to + +3 + + which is not + += + + to + +2 + +Makefile:15: recipe for target 'test' failed + +$ echo $? +2 +``` + +On Slime, load the test package and run `run!`. + +--- + +Licence: BSD diff --git a/hunchentoot-example/README.org b/hunchentoot-example/README.org new file mode 100644 index 0000000..72a823f --- /dev/null +++ b/hunchentoot-example/README.org @@ -0,0 +1,9 @@ +* Ritherdon Archive + + An archive of Ritherdon. I need to speak to Nic more about what this + means. + +* Project Summary + + This is a website written in Common Lisp and the Caveman2 framework. The + databased it uses in SQLite3 and Steel Bank Common Lisp (SBCL). diff --git a/hunchentoot-example/bin/libz.so.1.2.11 b/hunchentoot-example/bin/libz.so.1.2.11 new file mode 100644 index 0000000..22fe000 Binary files /dev/null and b/hunchentoot-example/bin/libz.so.1.2.11 differ diff --git a/hunchentoot-example/bin/ritherdon-archive b/hunchentoot-example/bin/ritherdon-archive new file mode 100755 index 0000000..52febf4 Binary files /dev/null and b/hunchentoot-example/bin/ritherdon-archive differ diff --git a/hunchentoot-example/config-example.lisp b/hunchentoot-example/config-example.lisp new file mode 100644 index 0000000..f64f408 --- /dev/null +++ b/hunchentoot-example/config-example.lisp @@ -0,0 +1,12 @@ + +(in-package :ritherdon-archive) + +(in-package :ritherdon-archive/web) + +;; +;; To use an init configuration file: +;; cp config-example.lisp config.lisp +;; + +;; Override the port: +;; (setf *port* 4545) diff --git a/hunchentoot-example/ritherdon-archive-tests.asd b/hunchentoot-example/ritherdon-archive-tests.asd new file mode 100644 index 0000000..5c89eb5 --- /dev/null +++ b/hunchentoot-example/ritherdon-archive-tests.asd @@ -0,0 +1,18 @@ +(in-package :asdf-user) +(defsystem "ritherdon-archive-tests" + :description "Test suite for the ritherdon-archive system" + :author "Craig Oates " + :version "0.0.0" + :depends-on (:ritherdon-archive + :parachute) + :license "MIT" + :serial t + :components ((:module "tests" + :serial t + :components ((:file "packages") + (:file "test-ritherdon-archive")))) + :perform (test-op (op s) (symbol-call :parachute :test :tests)) + + ;; The following would not return the right exit code on error, but still 0. + ;; :perform (test-op (op _) (symbol-call :fiveam :run-all-tests)) + ) diff --git a/hunchentoot-example/ritherdon-archive.asd b/hunchentoot-example/ritherdon-archive.asd new file mode 100644 index 0000000..945e2e7 --- /dev/null +++ b/hunchentoot-example/ritherdon-archive.asd @@ -0,0 +1,89 @@ +(in-package :asdf-user) + +(defsystem "ritherdon-archive" + :author "Craig Oates " + :version "0.0.0" + :license "MIT" + :description "Archive of Ritherdon and Nicola Ellis." + :homepage "" + :bug-tracker "" + :source-control (:git "") + + ;; Dependencies. + :depends-on ( + ;; HTTP client + :dexador + + ;; templates + :djula + + ;; server, routing + :hunchentoot + :easy-routes + + ;; JSON + :cl-json + + ;; DB + :mito + :mito-auth + + ;; utilities + :access + :cl-ppcre + :cl-slug + :local-time + :local-time-duration + :log4cl + :str + + ;; scripting + :unix-opts + + ;; deployment + :deploy + + ;; development utilities + ) + + ;; Build a binary. + ;; :build-operation "program-op" ;; usual op to build a binary. + ;; Deploy: + :defsystem-depends-on (:deploy) + :build-operation "deploy-op" + :build-pathname "ritherdon-archive" + :entry-point "ritherdon-archive:run" + + ;; Project stucture. + :serial t + :components ((:module "src" + :components + ;; stand-alone packages. + ((:file "packages") + (:file "utils") + ;; they depend on the above. + ;; (:file "authentication") + (:file "web") + (:file "ritherdon-archive") + (:file "database"))) + + (:module "src/models" + :components + ((:file "models") + (:file "user"))) + + (:static-file "README.md"))) + +;; Deploy may not find libcrypto on your system. +;; But anyways, we won't ship it to rely instead +;; on its presence on the target OS. +(require :cl+ssl) ; sometimes necessary. +#+linux (deploy:define-library cl+ssl::libssl :dont-deploy T) +#+linux (deploy:define-library cl+ssl::libcrypto :dont-deploy T) + +;; ASDF wants to update itself and fails. +;; Yeah, it does that even when running the binary on my VPS O_o +;; Please, don't. +(deploy:define-hook (:deploy asdf) (directory) + #+asdf (asdf:clear-source-registry) + #+asdf (defun asdf:upgrade-asdf () NIL)) diff --git a/hunchentoot-example/roswell/README.md b/hunchentoot-example/roswell/README.md new file mode 100644 index 0000000..768d434 --- /dev/null +++ b/hunchentoot-example/roswell/README.md @@ -0,0 +1,37 @@ + +## How to use Roswell to build and share binaries + +From the project root: + +Run as a script: + + chmod +x roswell/ritherdon-archive.ros + ./roswell/ritherdon-archive.ros + +Build a binary: + + ros build roswell/ritherdon-archive.ros + +and run it: + + ./roswell/ritherdon-archive + +Or install it in ~/.roswell/bin: + + ros install roswell/ritherdon-archive.ros + +It creates the binary in ~/.roswell/bin/ +Run it: + + ~/.roswell/bin/ritherdon-archive [name]~& + +Your users can install the script with ros install craig/ritherdon-archive + +Use `+Q` if you don't have Quicklisp dependencies to save startup time. +Use `ros build --disable-compression` to save on startup time and loose on application size. + + +## See + +- https://github.com/roswell/roswell/wiki/ +- https://github.com/roswell/roswell/wiki/Reducing-Startup-Time \ No newline at end of file diff --git a/hunchentoot-example/roswell/ritherdon-archive.ros b/hunchentoot-example/roswell/ritherdon-archive.ros new file mode 100644 index 0000000..62c8e1e --- /dev/null +++ b/hunchentoot-example/roswell/ritherdon-archive.ros @@ -0,0 +1,28 @@ +#!/bin/sh +#|-*- mode:lisp -*-|# +#| +exec ros -Q -- $0 "$@" +|# + +;; use +Q if you don't have Quicklisp dependencies to save startup time. + +(defun help () + (format t "~&Usage: + + ritherdon-archive [name] + +")) + +;; XXX: this load does not load from everywhere +;; it doesn't work for to run as a script. +(load (truename "ritherdon-archive.asd")) +(ql:quickload "ritherdon-archive") + +(defun main (&rest argv) + "Optional name parameter." + (when (member "-h" argv :test #'equal) + ;; To parse command line arguments, use a third-party library such as + ;; unix-opts, defmain, adopt… + (help) + (uiop:quit)) + (ritherdon-archive::greet (first argv))) diff --git a/hunchentoot-example/run-tests.lisp b/hunchentoot-example/run-tests.lisp new file mode 100644 index 0000000..03d455c --- /dev/null +++ b/hunchentoot-example/run-tests.lisp @@ -0,0 +1,9 @@ + +(load "ritherdon-archive.asd") +(load "ritherdon-archive-tests.asd") + +(ql:quickload "ritherdon-archive-tests") + +(in-package :ritherdon-archive-tests) + +(uiop:quit (if (run-all-tests) 0 1)) diff --git a/hunchentoot-example/run.lisp b/hunchentoot-example/run.lisp new file mode 100644 index 0000000..dbfb21d --- /dev/null +++ b/hunchentoot-example/run.lisp @@ -0,0 +1,25 @@ +" +Usage: + +rlwrap sbcl --load run.lisp + +This loads the project's asd, loads the quicklisp dependencies, and +calls the main function. + +Then, we are given the lisp prompt. + +If you don't want to land in the REPL, you can (quit) below or call lisp with the --non-interactive flag. + +Another solution to run the app is to build and run a binary (see README). +" + +(load "ritherdon-archive.asd") + +(ql:quickload "ritherdon-archive") + +(in-package :ritherdon-archive) +(handler-case + (main) + (error (c) + (format *error-output* "~&An error occured: ~a~&" c) + (uiop:quit 1))) diff --git a/hunchentoot-example/scripts/create-user.sh b/hunchentoot-example/scripts/create-user.sh new file mode 100755 index 0000000..c0efaee --- /dev/null +++ b/hunchentoot-example/scripts/create-user.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# Create account so user can log-in to the website. Assumes you're using +# SQLilte3 as the database. + +# Moves to the location of the script (regardless of where the script +# was called from). +cd "$(dirname "$0")" +DATABASE="ritherdon-archive.db" + +read -p "Username: " USERNAME +read -p "Display Name: " DISPLAY_NAME +read -sp "Password: " USER_PASSWORD +echo +read -sp "Confirm Password: " PASSWORD_TEST +echo + +if [[ $USERNAME == "" ]] + || [[ $DISPLAY_NAME == "" ]] + || [[ $USER_PASSWORD == "" ]]; then + echo "[ERROR] Empty string used." +else + if [[ $USER_PASSWORD == $PASSWORD_TEST ]]; then + echo "[SUCCESS] Password verified." + if [ -e "../$DATABASE" ]; then + echo "[INFO] Database found. Adding user to it..." + SQL="INSERT INTO user (username,display_name,password,created_at,updated_at) \ + VALUES (\"$USERNAME\",\"$DISPLAY_NAME\",\"$USER_PASSWORD\",(datetime(\"now\")),NULL);" + cd ../ + sqlite3 $DATABASE "$SQL" + + else + echo "[ERROR] Cannot find database. Make sure you've ran make build." + exit + fi + else + echo "[ERROR] Passwords do not match." + fi +fi diff --git a/hunchentoot-example/src/database.lisp b/hunchentoot-example/src/database.lisp new file mode 100644 index 0000000..a90962e --- /dev/null +++ b/hunchentoot-example/src/database.lisp @@ -0,0 +1,30 @@ +(in-package :ritherdon-archive/models) +;;; +;;; DB connection, migrations. +;;; + +(defparameter *tables* '(product user) + "List of the DB tables that need to be checked for migrations.") + +(defun connect (&optional (db-name *db-name*)) + "Connect to the DB." + ;; *db* could be mito:*connection* + (log:debug "connecting to ~a~&" *db-name*) + (setf *db* (mito:connect-toplevel :sqlite3 :database-name db-name))) + +(defun ensure-tables-exist () + "Run SQL to create the missing tables." + (unless mito::*connection* + (connect)) + (mapcar #'mito:ensure-table-exists *tables*)) + +(defun migrate-all () + "Migrate the tables after we changed the class definition." + (mapcar #'mito:migrate-table *tables*)) + +;; +;; Entry points +;; +(defun init-db () + "Connect to the DB, run the required migrations and define a couple base user roles." + (ensure-tables-exist)) diff --git a/hunchentoot-example/src/models/models.lisp b/hunchentoot-example/src/models/models.lisp new file mode 100644 index 0000000..e7f720b --- /dev/null +++ b/hunchentoot-example/src/models/models.lisp @@ -0,0 +1,61 @@ +(in-package :ritherdon-archive/models) + +(defparameter *db-name* (asdf:system-relative-pathname :ritherdon-archive "ritherdon-archive.db")) + +(defparameter *db* nil + "DB connection object, returned by (connect).") + +;; After modification, run (migrate-all) +;; +;; - to create a date: (local-time:now) +;; " +(defclass product () + ((title + :accessor title + :initarg :title + :initform nil + :type string + :col-type (:varchar 128)) + + (reference + :accessor reference + :initarg :reference + :initform nil + :type (or string null) + :col-type (or (:varchar 128) :null)) + + (price + :accessor price + :initarg :price + ;; we don't the price to 0 (nil denotes a missing field) + :initform nil + :type (or integer null) + :col-type (or :float :null) + :documentation "Store prices as integers. $9.80 => 980") + + (quantity + :accessor quantity + :initform 1 + :type (or integer null) + :col-type (or (:integer) :null) + :documentation "Quantity in stock.")) + + (:metaclass mito:dao-table-class) + (:documentation "A product.")) + +(defun make-product (&key title reference price) + "Create a product instance. + It is not saved in the DB yet." + (make-instance 'product + :title title + :reference reference + :price price)) + +(defun select-products (&key (order :asc)) + (mito:select-dao 'product + (sxql:order-by `(,order :created-at)))) + +(defun find-by (key val) + "Find a product by slot. Example: (find-by :id xxx). Return only the first matching result." + (when val + (mito:find-dao 'product key val))) diff --git a/hunchentoot-example/src/models/user.lisp b/hunchentoot-example/src/models/user.lisp new file mode 100644 index 0000000..d531693 --- /dev/null +++ b/hunchentoot-example/src/models/user.lisp @@ -0,0 +1,26 @@ +(in-package :ritherdon-archive/models) + +(defclass user () + ((username + :accessor username + :initarg :username + :initform nil + :type (or string null) + :col-type :text) + + (display-name + :accessor display-name + :initarg :display-name + :initform nil + :type (or string null) + :col-type :text) + + (password + :accessor password + :initarg :password + :initform nil + :type (or string null) + :col-type :text)) + + (:metaclass mito:dao-table-class) + (:documentation "Account information for users to log-in to the website..")) diff --git a/hunchentoot-example/src/packages.lisp b/hunchentoot-example/src/packages.lisp new file mode 100644 index 0000000..0c1859d --- /dev/null +++ b/hunchentoot-example/src/packages.lisp @@ -0,0 +1,41 @@ +;;; +;;; define helper packages, +;;; the models, +;;; the web, +;;; and the base package that relies on all of them. +;;; + +(defpackage ritherdon-archive/utils + (:use :cl + :log4cl) + (:export #:format-date + #:i18n-load + #:_ + #:parse-iso-date) + (:documentation "Utilities that do not depend on models.")) + +(defpackage ritherdon-archive/models + (:use :cl) + (:export :connect + :make-product + :select-products + :find-by)) + +(defpackage ritherdon-archive/web + (:use :cl) + (:import-from :easy-routes + :defroute) + (:export :start-app + :stop-app) + (:local-nicknames (#:a #:alexandria) + (#:models #:ritherdon-archive/models) + (#:utils #:ritherdon-archive/utils))) + +(defpackage ritherdon-archive + (:use :cl + :log4cl) + (:export :main :run) + (:local-nicknames (#:a #:alexandria) + (#:models #:ritherdon-archive/models) + (#:web #:ritherdon-archive/web) + (#:utils #:ritherdon-archive/utils))) diff --git a/hunchentoot-example/src/ritherdon-archive.lisp b/hunchentoot-example/src/ritherdon-archive.lisp new file mode 100644 index 0000000..cff8488 --- /dev/null +++ b/hunchentoot-example/src/ritherdon-archive.lisp @@ -0,0 +1,105 @@ +(in-package :ritherdon-archive) + +;; Define your project functionality here... + +(defparameter +version+ "0.0.1") ;; xxx: read from .asd + +(defun print-system-info (&optional (stream t)) + ;; see also https://github.com/40ants/cl-info + (format stream "~&OS: ~a ~a~&" (software-type) (software-version)) + (format stream "~&Lisp: ~a ~a~&" (lisp-implementation-type) (lisp-implementation-version)) + #+asdf + (format stream "~&ASDF: ~a~&" (asdf:asdf-version)) + #-asdf + (format stream "NO ASDF!") + #+quicklisp + (format stream "~&Quicklisp: ~a~&" (ql-dist:all-dists)) + #-quicklisp + (format stream "!! Quicklisp is not installed !!")) + +(defun handle-parser-error (c) + "unix-opts error handler." + (format t "Argument error: ~a~&" (opts:option c))) + +(defun main () + "Parse basic CLI args, start our web app." + + (unless (uiop:file-exists-p models::*db-name*) + (uiop:format! t "Creating the database into ~a...~&" models::*db-name*) + (models::init-db)) + + (opts:define-opts + (:name :help + :description "print this help and exit." + :short #\h + :long "help") + + (:name :version + :description "print the version number and exit." + :short #\v + :long "version") + + (:name :verbose + :description "print debug info." + :short #\V + :long "verbose") + + (:name :port + :arg-parser #'parse-integer + :description "set the port for the web server. You can also use the XYZ_PORT environment variable." + :short #\p + :long "port")) + + (multiple-value-bind (options free-args) + (handler-bind ((error #'handle-parser-error)) + (opts:get-opts)) + + (format t "ritherdon-archive version ~a~&" +version+) + + (when (getf options :version) + (print-system-info) + (uiop:quit)) + + (when (getf options :help) + (opts:describe) + (uiop:quit)) + + (when (getf options :verbose) + (print-system-info)) + + (web::load-config) + + (web:start-app :port (or (getf options :port) + (ignore-errors (parse-integer (uiop:getenv "XYZ_PORT"))) + web::*port*)))) + +(defun run () + "Start our web app calling the MAIN function, and: + + - put the server thread on the foreground, so that Lisp doesn't quit + instantly, and our binary keeps running + - catch a couple errors: port in use, a user's C-c." + (handler-case + (progn + + (main) + + ;; That's only needed for the binary, not when running from sources + ;; (except if you run for Systemd…). + ;; Put the server thread on the foreground. + ;; Without this, the binary exits immediately. + (bt:join-thread + (find-if (lambda (th) + (search "hunchentoot" (bt:thread-name th))) + (bt:all-threads)))) + + ;; Catch some errors. + (usocket:address-in-use-error () + (format *error-output* "This port is already taken.~&")) + #+sbcl + (sb-sys:interactive-interrupt () + (format *error-output* "~&Bye!~&") + (uiop:quit)) + (error (c) + (format *error-output* "~&An error occured: ~a~&" c) + (uiop:quit 1)))) diff --git a/hunchentoot-example/src/static/css/main.css b/hunchentoot-example/src/static/css/main.css new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/hunchentoot-example/src/static/css/main.css @@ -0,0 +1 @@ + diff --git a/hunchentoot-example/src/static/js/ritherdon-archive.js b/hunchentoot-example/src/static/js/ritherdon-archive.js new file mode 100644 index 0000000..897d2f8 --- /dev/null +++ b/hunchentoot-example/src/static/js/ritherdon-archive.js @@ -0,0 +1,2 @@ + +console.log("Hello ritherdon-archive!"); diff --git a/hunchentoot-example/src/templates/404.html b/hunchentoot-example/src/templates/404.html new file mode 100644 index 0000000..59a93fc --- /dev/null +++ b/hunchentoot-example/src/templates/404.html @@ -0,0 +1 @@ +

404: Web Page Not Found

diff --git a/hunchentoot-example/src/templates/about.html b/hunchentoot-example/src/templates/about.html new file mode 100644 index 0000000..82f1a7c --- /dev/null +++ b/hunchentoot-example/src/templates/about.html @@ -0,0 +1,5 @@ +{% extends "base.html" %} + +{% block content %} +

About

+{% end block %} diff --git a/hunchentoot-example/src/templates/archive.html b/hunchentoot-example/src/templates/archive.html new file mode 100644 index 0000000..1bbd79f --- /dev/null +++ b/hunchentoot-example/src/templates/archive.html @@ -0,0 +1,6 @@ +{% extends "base.html" %} + +{% block content %} +

Archive

+ +{% end block %} diff --git a/hunchentoot-example/src/templates/base.html b/hunchentoot-example/src/templates/base.html new file mode 100644 index 0000000..b3a9fd6 --- /dev/null +++ b/hunchentoot-example/src/templates/base.html @@ -0,0 +1,15 @@ + + + + + {% block title %}{% endblock %} + + + + + + + + {% block content %} {% endblock %} + + diff --git a/hunchentoot-example/src/templates/dashboard.html b/hunchentoot-example/src/templates/dashboard.html new file mode 100644 index 0000000..b1bb783 --- /dev/null +++ b/hunchentoot-example/src/templates/dashboard.html @@ -0,0 +1,175 @@ +{% extends "base.html" %} + +{% block content %} + + + + +
+
+
+

+ Hello, Admin. +

+

+ I hope you are having a great day! +

+
+
+
+
+
+
+
+

{{ data.nb-titles }}

+

Nombre de titres

+
+
+
+
+

{{ data.nb-books }}

+

Nombre de livres

+
+
+
+
+

{{ data.nb-titles-negative }}

+

Titres en stock négatif

+
+
+
+
+

19

+

Exceptions

+
+
+
+
+
+
+
+
+

+ Events +

+ + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Lorum ipsum dolem aireAction
Lorum ipsum dolem aireAction
Lorum ipsum dolem aireAction
Lorum ipsum dolem aireAction
Lorum ipsum dolem aireAction
Lorum ipsum dolem aireAction
Lorum ipsum dolem aireAction
Lorum ipsum dolem aireAction
Lorum ipsum dolem aireAction
+
+
+ +
+
+
+
+
+

+ Inventory Search +

+ + + + + +
+
+
+
+ + + + + + + +
+
+
+
+
+
+

+ User Search +

+ + + + + +
+
+
+
+ + + + + + + +
+
+
+
+
+
+ +{% endblock %} + + diff --git a/hunchentoot-example/src/templates/home.html b/hunchentoot-example/src/templates/home.html new file mode 100644 index 0000000..91d3034 --- /dev/null +++ b/hunchentoot-example/src/templates/home.html @@ -0,0 +1,6 @@ +{% extends "base.html" %} + +{% block content %} +

Index

+ +{% end block %} diff --git a/hunchentoot-example/src/templates/login.html b/hunchentoot-example/src/templates/login.html new file mode 100644 index 0000000..4a46ec3 --- /dev/null +++ b/hunchentoot-example/src/templates/login.html @@ -0,0 +1,16 @@ +{% extends "base.html" %} +{% block title %}Nicola Ellis & Ritherdon Archive: Log-In{% endblock %} +{% block content %} +

Login

+
+ + + + + + + + + +
+{% endblock %} diff --git a/hunchentoot-example/src/utils.lisp b/hunchentoot-example/src/utils.lisp new file mode 100644 index 0000000..ae2f421 --- /dev/null +++ b/hunchentoot-example/src/utils.lisp @@ -0,0 +1,9 @@ +(in-package :ritherdon-archive/utils) + + +(defun format-date (date) + "Format the given date with the default date format (yyyy-mm-dd). Return a string." + (local-time:format-timestring nil date :format +date-y-m-d+)) + +(defun asciify (string) + (str:downcase (slug:asciify string))) diff --git a/hunchentoot-example/src/web.lisp b/hunchentoot-example/src/web.lisp new file mode 100644 index 0000000..255d806 --- /dev/null +++ b/hunchentoot-example/src/web.lisp @@ -0,0 +1,135 @@ +(in-package :ritherdon-archive/web) + +(defvar *server* nil + "Current instance of easy-acceptor.") + +(defparameter *port* 4242) + +;;; +;;; Djula filters. +;;; + +(djula:def-filter :price (val) + (format nil "~,2F" val)) + +;;; +;;; Load templates. +;;; +(djula:add-template-directory + (asdf:system-relative-pathname "ritherdon-archive" "src/templates/")) + +(defparameter +base.html+ (djula:compile-template* "base.html")) +(defparameter +404.html+ (djula:compile-template* "404.html")) + +;; Front-End Templates +(defparameter +index.html+ (djula:compile-template* "home.html")) +(defparameter +archive.html+ (djula:compile-template* "archive.html")) +(defparameter +about.html+ (djula:compile-template* "about.html")) +(defparameter +login.html+ (djula:compile-template* "login.html")) + +;; Back-End Templates +(defparameter +dashboard.html+ (djula:compile-template* "dashboard.html")) + +;;; +;;; Serve static assets +;;; +(defparameter *default-static-directory* "src/static/" + "The directory where to serve static assets from (STRING). If it starts with a slash, it is an absolute directory. Otherwise, it will be a subdirectory of where the system :abstock is installed. + Static assets are reachable under the /static/ prefix.") + +(defun serve-static-assets () + (push (hunchentoot:create-folder-dispatcher-and-handler + "/static/" (merge-pathnames *default-static-directory* + (asdf:system-source-directory :ritherdon-archive))) + hunchentoot:*dispatch-table*)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Routes. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Root route. +(defroute home-route ("/") () + (djula:render-template* +dashboard.html+ nil + :route "/")) + +(defroute login ("/login") () + (djula:render-template* +login.html+ nil)) + +(defroute card-page ("/product/:slug") + (&get raw) + "Show a product. + + Dev helper: if the URL parameter RAW is \"t\" (the string), then display the card object literally (with describe)." + ;; The product URL is of the form: /xyz-product-title where xyz is its pk. + (let* ((product-id (ignore-errors + (parse-integer (first (str:split "-" slug))))) + (product (when product-id + (models:find-by :id product-id)))) + (cond + ((null product-id) + (render-template* +404.html+ nil)) + (product + (render-template* +product-stock.html+ nil + :messages nil + :route "/product" + :product product + :raw raw)) + (t + (render-template* +404.html+ nil))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Start-up functions. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun find-config () + (cond + ((uiop:file-exists-p "config.lisp") + "config.lisp") + (t + nil))) + +(defun load-config () + "Load `config.lisp', situated at the project's root." + (let ((file (find-config))) + (if file + ;; One case of failure: a symbolic link exists, but + ;; the target file doesn't. + (progn + (uiop:format! t "Loading config file ~a…~&" file) + (load (uiop:native-namestring file))) + (format t "... no config file found.~&")))) + +(defun start-app (&key (port *port*) (load-config-p nil)) + "Start the Hunchentoot web server on port PORT (defaults to `*PORT*'), serve static assets. + + If LOAD-CONFIG-P is non nil, load the config file (this is normally done in the main function of run.lisp before)." + ;; You can use the find-port library to find an available port. + + ;; Load the config.lisp init file. + (if load-config-p + (load-config) + (uiop:format! t "Skipping config file.~&")) + + ;; Set up the DB. + (models:connect) + + ;; Start the server. + (uiop:format! t "Starting Hunchentoot on port ~a…~&" port) + (setf *server* (make-instance 'easy-routes:easy-routes-acceptor :port port)) + (hunchentoot:start *server*) + (serve-static-assets) + (uiop:format! t "~&Application started on port ~a.~&" port)) + +(defun stop-app () + ;; disconnect db ? + (hunchentoot:stop *server*)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Authentication functions. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun current-user () + (hunchentoot:session-value :user)) + +(defun logout () + (setf (hunchentoot:session-value :user) nil)) diff --git a/hunchentoot-example/tests/packages.lisp b/hunchentoot-example/tests/packages.lisp new file mode 100644 index 0000000..67a679e --- /dev/null +++ b/hunchentoot-example/tests/packages.lisp @@ -0,0 +1,8 @@ +(in-package :asdf-user) +(defpackage :ritherdon-archive-tests + (:use :common-lisp + :parachute + :ritherdon-archive)) + + +(in-package :ritherdon-archive-tests) diff --git a/hunchentoot-example/tests/test-ritherdon-archive.lisp b/hunchentoot-example/tests/test-ritherdon-archive.lisp new file mode 100644 index 0000000..e249fe7 --- /dev/null +++ b/hunchentoot-example/tests/test-ritherdon-archive.lisp @@ -0,0 +1,16 @@ +(in-package :ritherdon-archive-tests) + +#| parachute: https://shinmera.github.io/parachute/ +================================================================================ +Use the URL to access the documentation for parachute. +|# + +;; This was an example taken from the doc's for parachute. I'm going to keep it +;; here as a reference until I get comfortable with parachute. +(define-test reference-tests + (of-type integer 5) + (true (numberp 2/3)) + (false (numberp :keyword)) + (is-values (values 0 "1") + (= 0) + (equal "1"))) diff --git a/makefile b/makefile new file mode 100644 index 0000000..3dbfb57 --- /dev/null +++ b/makefile @@ -0,0 +1,44 @@ +LISP ?= sbcl + +help: + @echo 'Usage: make [command]' + @echo + @echo 'Commands to run on server:' + @echo ' install Install Debian packages and Quicklisp for website.' + @echo + @echo ' lisp-install Install Lisp environment, including Quicklisp.' + @echo + @echo ' quicklisp-add Add repo. to Quicklisp local-projects directory.' + @echo + @echo ' search-install Install Meilisearch instance.' + @echo + @echo 'Default target:' + @echo ' help Show this help message.' + +# Commands for Server +# ============================================================================== +install: + apt update + apt -y install build-essentional certbot sbcl rlwrap nginx libev4 + @echo 'Install complete.' + +lisp-install: + curl https://beta.quicklisp.org/quicklisp.lisp + sbcl --load "/usr/share/common-lisp/source/quicklisp/quicklisp.lisp" + sbcl --eval (quicklisp-quickstart:install) \ + --eval (ql:add-to-init-file) \ + --quit + @echo 'Lisp environment install complete.' + +quicklisp-add: + @echo 'Adding project to quicklisp...' + ln -s ~/ritherdon-archive ~/quicklisp/local-projects/ + @echo 'Added to quicklisp.' + +search-install: + @echo 'Installing and setting up Meilisearch instance...' + mkdir ~/meilisearch + cd ~/meilisearch + curl -L https://install.meilisearch.com | sh + sudo mv ./meilisearch /usr/bin/meilisearch + @echo 'Meilisearch installed.' diff --git a/ritherdon-archive-test.asd b/ritherdon-archive-test.asd deleted file mode 100644 index 0d9a068..0000000 --- a/ritherdon-archive-test.asd +++ /dev/null @@ -1,11 +0,0 @@ -(defsystem "ritherdon-archive-test" - :defsystem-depends-on ("prove-asdf") - :author "Craig Oates" - :license "MIT" - :depends-on ("ritherdon-archive" - "prove") - :components ((:module "tests" - :components - ((:test-file "ritherdon-archive")))) - :description "Test system for ritherdon-archive" - :perform (test-op (op c) (symbol-call :prove-asdf :run-test-system c))) diff --git a/ritherdon-archive.asd b/ritherdon-archive.asd index a874489..f10bd69 100644 --- a/ritherdon-archive.asd +++ b/ritherdon-archive.asd @@ -1,29 +1,88 @@ -(defsystem "ritherdon-archive" +(defsystem #:ritherdon-archive :version "0.1.0" :author "Craig Oates" :license "MIT" - :depends-on ("clack" - "lack" - "caveman2" - "envy" - "cl-ppcre" - "uiop" + :depends-on (#:clack + #:lack + #:caveman2 + #:envy + #:cl-ppcre + #:uiop ;; for @route annotation - "cl-syntax-annot" + #:cl-syntax-annot ;; HTML Template - "djula" + #:djula ;; for DB - "datafly" - "sxql") - :components ((:module "src" - :components - ((:file "main" :depends-on ("config" "view" "db")) - (:file "web" :depends-on ("view")) - (:file "view" :depends-on ("config")) - (:file "db" :depends-on ("config")) - (:file "config")))) - :description "A website to host Ritherdon's Archive." - :in-order-to ((test-op (test-op "ritherdon-archive-test")))) + #:datafly + #:sxql + + ;;; Additional Packages (after initial Caveman set-up) + #:woo ; Alternative server to Hunchentoot + #:clack-errors ; Error report (HTML/template views) + #:mito ; Database ORM + #:mito-auth ; Auth. with password hashing and salting + #:osicat ; Environment variables (dev/prod.) + #:ratify ; Utilites + #:trivia ; Pattern matching + #:plump ; Parsing (HTML/XML) + #:dexador ; HTTP client + #:clss ; DOM tree search based on CSS selectors + #:3bmd ; Markdown + #:cl-json ; JSON Parsing + #:cl-who ; Markup + #:sqlite ; Sqlite database ORM + #:hermetic ; Authentication + #:cl-fad ; Files and directories + #:xml-emitter ; XML Emitter for RSS Feed + #:serapeum ; Pagination + #:cl-slug ; Asciify and slugify strings + #:str ; String manipulation (easier than built-in) + #:copy-directory ; Copy Directories using Native cp + #:cl-diskspace ; Get Disk Info. + #:zip ; Zip and compression + ) + :pathname "src/" + ;; :serial t + :components (;; Caveman Files + (:file "config") + (:file "main") + (:file "db") + + ;; Ritherdon Archive Specific Files + (:file "app-constants") + (:file "models/user") + (:file "models/site-settings") + (:file "models/pages") + (:file "models/files") + (:file "models/archive") + (:file "status-codes") + (:file "storage") + (:file "utils") + (:file "auth") + (:file "validation") + (:file "nera") ; Database stuff + (:file "search") ; Meilisearch stuff + (:file "snapshot") ; Site back-up/snapshot stuff + ;; Caveman Files + (:file "view") + (:file "web")) + :description "The Nicola Ellis & Ritherdon Archive." + :build-operation "program-op" + :build-pathname "clinera" + :entry-point "ritherdon-archive:main" + :in-order-to ((test-op (test-op "ritherdon-archive/tests")))) + + +(defsystem #:ritherdon-archive/tests + :author "Craig Oates" + :license "MIT" + :depends-on (#:ritherdon-archive + #:parachute) + :components ((:module "tests" + :components + ((:file "tests")))) + :description "Test system for ritherdon-archive." + :perform (test-op (op c) (symbol-call :parachute :test :tests))) diff --git a/scripts/create-user.sh b/scripts/create-user.sh new file mode 100755 index 0000000..c0efaee --- /dev/null +++ b/scripts/create-user.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# Create account so user can log-in to the website. Assumes you're using +# SQLilte3 as the database. + +# Moves to the location of the script (regardless of where the script +# was called from). +cd "$(dirname "$0")" +DATABASE="ritherdon-archive.db" + +read -p "Username: " USERNAME +read -p "Display Name: " DISPLAY_NAME +read -sp "Password: " USER_PASSWORD +echo +read -sp "Confirm Password: " PASSWORD_TEST +echo + +if [[ $USERNAME == "" ]] + || [[ $DISPLAY_NAME == "" ]] + || [[ $USER_PASSWORD == "" ]]; then + echo "[ERROR] Empty string used." +else + if [[ $USER_PASSWORD == $PASSWORD_TEST ]]; then + echo "[SUCCESS] Password verified." + if [ -e "../$DATABASE" ]; then + echo "[INFO] Database found. Adding user to it..." + SQL="INSERT INTO user (username,display_name,password,created_at,updated_at) \ + VALUES (\"$USERNAME\",\"$DISPLAY_NAME\",\"$USER_PASSWORD\",(datetime(\"now\")),NULL);" + cd ../ + sqlite3 $DATABASE "$SQL" + + else + echo "[ERROR] Cannot find database. Make sure you've ran make build." + exit + fi + else + echo "[ERROR] Passwords do not match." + fi +fi diff --git a/src/app-constants.lisp b/src/app-constants.lisp new file mode 100644 index 0000000..09247aa --- /dev/null +++ b/src/app-constants.lisp @@ -0,0 +1,39 @@ +(defpackage #:app-constants + (:use #:cl) + (:export #:define-constant + #:+false+ + #:+true+)) + +(in-package #:app-constants) + +#| Switched to `DEFINE-CONSTANT' from `DEFCONSTANT'. +================================================================================ +Because this website uses Steel Bank Common Lisp (SBCL), I need to go through a +cycle of confirming changes to the constant values even though they have not +changed. This behaviour is explained in the SBCL Manual 2.1.3 2021-03 (Section +2.3.4 Defining Constants, page 5 (printed) page 13 (PDF)). The key part of the +section is, +'ANSI says that doing `DEFCONSTANT' of the same symbol more than once is +undefined unless the new value is eql to the old value.' +http://www.sbcl.org/manual/#Defining-Constants (this URL should provide the +latest information of the subject). +A workaround, provided by the SBCL Manual is to use the `DEFINE-CONSTANT' macro +instead of `DEFCONST'. By doing this, I can use Quickload to reload the code +(after a big change for example) and not have to repeat the cycle of 'updating' +the constants when they have not changed. +|# +(defmacro define-constant (name value &optional doc) + `(defconstant ,name (if (boundp ',name) (symbol-value ',name) ,value) + ,@(when doc (list doc)))) + +#| SQLite does not have Boolean value types. +================================================================================ +At the time of writing (February 2022), the website uses SQLite as its +database. So, I have made these constants to reduce hard-coded `1' +and/or `0' values when `TRUE' and `NIL'/`FALSE' values are want is +meant (in the code-base). +|# +(define-constant +false+ 0 + "An integer representing 'false' (for SQLite mostly).") +(define-constant +true+ 1 + "An integer representing 'true' (for SQLite mostly.") diff --git a/src/auth.lisp b/src/auth.lisp new file mode 100644 index 0000000..a5b1f33 --- /dev/null +++ b/src/auth.lisp @@ -0,0 +1,76 @@ +(defpackage #:auth + (:use #:cl + #:hermetic + #:sxql + ;; #:datafly + #:ningle + #:mito + #:app-constants + #:user) + (:import-from #:ritherdon-archive.db + #:connection-settings + #:db + #:with-connection) + (:export #:csrf-token + #:get-user-roles + #:get-current-user + #:flash-gethash + #:auth-user-data)) + +(in-package #:auth) + +(defun csrf-token () + "Cross-Site Request Forgery (CSRF) token." + (cdr (assoc "lack.session" + (lack.request:request-cookies ningle:*request*) + :test #'string=))) + +(hermetic:setup + ;; #' is needed. (hermetic:roles) generates infinite-loop when called + ;; otherwise -- 'roles' called in other parts of code-base. + ;; #' is shorthand for the 'function' operator (returns the function + ;; object associated with the name of the function which is supplied + ;; as an argument. Keep forgetting that. + :user-p #'(lambda (username) + (with-connection (db) + (mito:find-dao 'user::user :username username))) + :user-pass #'(lambda (username) + (user::password-of + (with-connection (db) + (mito:find-dao 'user::user :username username)))) + :user-roles #'(lambda (username) + (cons :logged-in + (let ((user (with-connection (db) + (mito:find-dao + 'user::user :username username)))) + (and user + (= (user::is-administrator-p user) +true+) + '(:administrator))))) + :session ningle:*session* + :denied (constantly '(400 (:content-type "text/plain") ("Authentication denied")))) + +(defun get-current-user() + "Returns the currently logged in user from the browser session." + (with-connection (db) + (mito:find-dao 'user :id (gethash :id ningle:*session*)))) + +(defun auth-user-data () + "Get usual session data for logged in `USER'." + `(:token ,(auth:csrf-token) + :roles ,(auth:get-user-roles) + :user ,(auth:get-current-user))) + +(defun get-user-roles() + "Returns a list of roles the current user has assigned to them. +This is mostly to check if the user is logged-in or has administration +privileges. You can then create if-blocks in the HTML templates and +control what the user can and cannot see or do." + (loop :for role :in (hermetic:roles) + :collect role + :collect t)) + +(defun flash-gethash (key table) + "Clears out the session hash." + (let ((value (gethash key table))) + (remhash key table) + value)) diff --git a/src/config.lisp b/src/config.lisp index 552f223..284d7dc 100644 --- a/src/config.lisp +++ b/src/config.lisp @@ -1,17 +1,19 @@ -(in-package :cl-user) -(defpackage ritherdon-archive.config - (:use :cl) - (:import-from :envy - :config-env-var - :defconfig) - (:export :config - :*application-root* - :*static-directory* - :*template-directory* - :appenv - :developmentp - :productionp)) -(in-package :ritherdon-archive.config) +(in-package #:cl-user) +(defpackage #:ritherdon-archive.config + (:use #:cl) + (:import-from #:envy + #:config-env-var + #:defconfig) + (:export #:config + #:*application-root* + #:*static-directory* + #:*template-directory* + #:appenv + #:developmentp + #:productionp + #:testp + #:database-name)) +(in-package #:ritherdon-archive.config) (setf (config-env-var) "APP_ENV") @@ -20,16 +22,25 @@ (defparameter *template-directory* (merge-pathnames #P"templates/" *application-root*)) (defconfig :common - `(:databases ((:maindb :sqlite3 :database-name ":memory:")))) + `(:application-root ,(asdf:component-pathname (asdf:find-system :ritherdon-archive)))) (defconfig |development| - '()) + `(:debug T + :databases + ((:maindb :sqlite3 + :database-name ,(merge-pathnames #P"db/nera-dev.db" + *application-root*))))) (defconfig |production| - '()) + `(:debug nil + :databases + ((:maindb :sqlite3 + :database-name ,(merge-pathnames #P"db/nera-prod.db" + *application-root*))))) -(defconfig |test| - '()) +(defconfig |staging| + `(:debug T + ,@|production|)) (defun config (&optional key) (envy:config #.(package-name *package*) key)) @@ -42,3 +53,14 @@ (defun productionp () (string= (appenv) "production")) + +(defun stagingp () + (string= (appenv) "staging")) + +(defun database-name () + (first (last (first (config :databases))))) + +;;; Use this to change the environment between "development" and +;;; "production". This change is mostly to specifiy which database the +;;; system will use. +(setf (osicat:environment-variable "APP_ENV") "development") diff --git a/src/db.lisp b/src/db.lisp index 6fcb587..db19016 100644 --- a/src/db.lisp +++ b/src/db.lisp @@ -1,15 +1,16 @@ -(in-package :cl-user) -(defpackage ritherdon-archive.db - (:use :cl) - (:import-from :ritherdon-archive.config - :config) - (:import-from :datafly - :*connection*) - (:import-from :cl-dbi - :connect-cached) - (:export :connection-settings - :db - :with-connection)) +(in-package #:cl-user) +(defpackage #:ritherdon-archive.db + (:use #:cl) + (:import-from #:ritherdon-archive.config + #:config) + (:import-from #:datafly + #:*connection*) + (:import-from #:cl-dbi + #:connect-cached) + (:export #:connection-settings + #:db + #:with-connection + #:init-db)) (in-package :ritherdon-archive.db) (defun connection-settings (&optional (db :maindb)) @@ -19,5 +20,5 @@ (apply #'connect-cached (connection-settings db))) (defmacro with-connection (conn &body body) - `(let ((*connection* ,conn)) + `(let ((mito:*connection* ,conn)) ,@body)) diff --git a/src/main.lisp b/src/main.lisp index a921a9f..7998566 100644 --- a/src/main.lisp +++ b/src/main.lisp @@ -1,13 +1,14 @@ -(in-package :cl-user) -(defpackage ritherdon-archive - (:use :cl) - (:import-from :ritherdon-archive.config - :config) - (:import-from :clack - :clackup) - (:export :start - :stop)) -(in-package :ritherdon-archive) +(in-package #:cl-user) +(defpackage #:ritherdon-archive + (:use #:cl) + (:import-from #:ritherdon-archive.config + #:config) + (:import-from #:clack + #:clackup) + (:export #:start + #:stop + #:main)) +(in-package #:ritherdon-archive) (defvar *appfile-path* (asdf:system-relative-pathname :ritherdon-archive #P"app.lisp")) @@ -28,3 +29,32 @@ (prog1 (clack:stop *handler*) (setf *handler* nil))) + +#| 'main' Function Used For Starting Server From Script (I.E. Live Deployment) +================================================================================ +https://lisp-journey.gitlab.io/web-dev/#building +The code below was taken from the URL above (with slight modifications). It's +main use is to make it easier to start the server via a script. +|# +(defun main (&key (port 5000)) + (start :server :woo ; hunchentoot or woo. + :port port + :debug (if (ritherdon-archive.config:productionp) + nil + t)) + ;; with bordeaux-threads + (handler-case (bt:join-thread + (find-if (lambda (th) + (search "woo" (bt:thread-name th))) + (bt:all-threads))) + (#+sbcl sb-sys:interactive-interrupt + #+ccl ccl:interrupt-signal-condition + #+clisp system::simple-interrupt-condition + #+ecl ext:interactive-interrupt + #+allegro excl:interrupt-signal + () (progn + (format *error-output* "Aborting.~&") + (clack:stop *handler*) + (uiop:quit 1)) ;; portable exit, included in ASDF, already loaded. + ;; for others, unhandled errors (we might want to do the same). + (error (c) (format t "Woops, an unknown error occured:~&~a~&" c))))) diff --git a/src/models/archive.lisp b/src/models/archive.lisp new file mode 100644 index 0000000..24588a8 --- /dev/null +++ b/src/models/archive.lisp @@ -0,0 +1,76 @@ +(in-package #:cl-user) +(defpackage #:archive + (:nicknames #:arc) + (:use #:cl + #:ritherdon-archive.db + #:app-constants + #:mito) + (:export #:archive-entry)) +(in-package #:archive) + +(defclass archive-entry () + ((title + :documentation "The title of the archive entry." + :col-type (or :text :null) + :initarg :title + :initform :null + :accessor title-of) + + (search-id + :documentation "The Id. used in the Meilisearch database." + :col-type (or :integer :null) + :initarg :search-id + :initform :null + :accessor search-id-of) + + (month + :documentation "The month the artwork was published." + :col-type (or :text :null) + :initarg :month + :initform :null + :accessor month-of) + + (year + :documentation "The year the artwork was published." + :col-type (or :integer :null) + :initarg :year + :initform :null + :accessor year-of) + + (slug + :documentation "The slug, used as part of the URL, to access the entry." + :col-type (or :text :null) + :initarg :slug + :initform :null + :accessor slug-of) + + (thumbnail-slug + :documentation "The name of the thumbnail, for particular entry." + :col-type (or :text :null) + :initarg :thumbnail-slug + :initform :null + :accessor thumbnail-slug-of) + + (thumbnail-file-type + :documentation "The file type of the thumbnail, used when serving image." + :col-type (or :text :null) + :initarg :thumbnail-file-type + :initform :null + :accessor thumbnail-file-type-of) + + (keywords + :documentation "Text for Meilisearch's filter options. An example + of how the keywords shold look is: 'art,welding,blue and + green,metal'. The 'blue and green' section is classed as one + keyword." + :col-type (or :text :null) + :initarg :keywords + :initform :null + :accessor keywords-of)) + + (:documentation "`ARCHIVE-ENTRY' represents the model used by Mito + to map database between the system and the 'archive_entry' table in + the database. This model contains data which is used more by the + Meilisearch instance attached to this website -- as a seperate + service.") + (:metaclass mito:dao-table-class)) diff --git a/src/models/files.lisp b/src/models/files.lisp new file mode 100644 index 0000000..9f79783 --- /dev/null +++ b/src/models/files.lisp @@ -0,0 +1,35 @@ +(in-package #:cl-user) +(defpackage #:files + (:use #:cl + #:ritherdon-archive.db + #:app-constants + #:mito) + (:export #:storage-file)) +(in-package #:files) + +(defclass storage-file () + ((name + :documentation "The filename of the file being stored in /storage/media." + :col-type (or :text :null) + :initarg :name + :initform :null + :accessor name-of) + + (slug + :documentation "The slugified version of the file's `NAME'. This is what is + used when constructing links and accessing the file from the browser." + :col-type (or :text :null) + :initarg :slug + :initform :null + :accessor slug-of) + + (file-type + :documentation "The MIME type of the file (E.G. 'image/png." + :col-type (or :text :null) + :initarg :file-type + :initform :null + :accessor file-type-of)) + + (:documentation "Model describing the 'storage_file' table in the database -- + used by Mito.") + (:metaclass mito:dao-table-class)) diff --git a/src/models/pages.lisp b/src/models/pages.lisp new file mode 100644 index 0000000..aa37763 --- /dev/null +++ b/src/models/pages.lisp @@ -0,0 +1,48 @@ +(in-package #:cl-user) +(defpackage #:pages + (:use #:cl + #:ritherdon-archive.db + #:mito + #:app-constants) + (:export #:page)) +(in-package #:pages) + +(defclass page () + ((title + :documentation "The title of the page." + :col-type (or :text :null) + :initarg :title + :initform :title + :accessor title-of) + + (slug + :documentation "The slugified version of the page `TITLE'. This is what is + used when constructing links and accessing the page from the browser." + :col-type (or :text :null) + :initarg :slug + :initform :null + :accessor slug-of) + + (enable-nav-menu + :documentation + "Boolean value stating if `PAGE' should be included on site's nav. menu." + :col-type (or :integer :null) + :initarg :enable-nav-menu + :initform +false+ ;SQLite 0 -> false 1 -> true. + :accessor enable-nav-menu-p) + + (can-delete + :documentation + "Specifies if the page can be deleted from the database. This is for + 'hard-coded' pages such as the 'archive' and 'pages'. The user won't make + these pages they come as part of the website which the use can add to the + nav. menu." + :col-type (or :integer :null) + :initarg :can-delete + :initform +false+ ;SQLite 0 -> false 1 -> true. + :accessor can-delete-p)) + + (:documentation "`PAGE' represents the meta-data for the pages made by the + `USER' which are stored in the database. The actual pages are stored in the + /storage/pages directory.") + (:metaclass mito:dao-table-class)) diff --git a/src/models/site-settings.lisp b/src/models/site-settings.lisp new file mode 100644 index 0000000..673c33c --- /dev/null +++ b/src/models/site-settings.lisp @@ -0,0 +1,50 @@ +(in-package #:cl-user) +(defpackage #:site-settings + (:use #:cl + #:ritherdon-archive.db + #:mito + #:app-constants) + (:export #:site-settings + #:nav-menu)) + +(in-package #:site-settings) + +(defclass site-settings () + ((enable-sign-up + :documentation "Allow non-registered users to create accounts." + :col-type (or :integer :null) + :initarg :enable-sign-up + :initform +true+ ; SQLite: 0 -> false 1 -> true. + :accessor enable-sign-up-p) + + (enable-site-logo + :documentation "Show site logo in website's header." + :col-type (or :integer :null) + :initarg :enable-site-logo + :initform +true+ ; SQLite: 0 -> false 1 -> true. + :accessor enable-site-logo-p) + + (site-name + :documentation "The name of the site, shown in website's header." + :col-type (or :text :null) + :initarg :site-name + :initform "NERA" + :accessor site-name-of) + + (home-page + :documentation "The page (found in /storage/pages) which is rendered for '/' defroute." + :col-type (or :text :null) + :initarg :home-page + :initform "home" + :accessor home-page-of) + + (search-url + :documentation "The URL for the Meilisearch instance this site calls out to + for it's search features." + :col-type (or :text :null) + :initarg :search-url + :initform "http://localhost:7700" ; Default Meilisearch URL. + :accessor search-url-of)) + + (:documentation "Model used to track the site-wide settings -- stored in the database.") + (:metaclass mito:dao-table-class)) diff --git a/src/models/user.lisp b/src/models/user.lisp new file mode 100644 index 0000000..fb1f5fb --- /dev/null +++ b/src/models/user.lisp @@ -0,0 +1,41 @@ +(defpackage #:user + (:use #:cl + #:ritherdon-archive.db + #:mito + #:app-constants) + (:export #:user)) +(in-package #:user) + +(defclass user () + ((username + :documentation "The name the user uses to log into the website." + :col-type :text + :initarg :username + :accessor username-of) + + (display-name + :documentation "The name used in the website GUI (the pretty name)." + :col-type :text + :initarg :display-name + :accessor display-name-of) + + (password + :documentation "The user's password." + :col-type :text + :initarg :password + :accessor password-of) + + (administrator + :documentation "States if user has admin. priveledges. At the time + of writing (11/09/2022), SQLite is the current database and it + does not have a Boolean datatype so '0' represents 'false' and '1' + represents 'true'. You will not come across '0' or '1' in the code + because of how mito maps the code to the database. But, you will + see it in the database if you view it directly." + :col-type :integer + :initarg :administrator + :initform +false+ ; SQLite: 0 -> false 1 -> true. + :accessor is-administrator-p)) + + (:documentation "The model used to describe the `USER' table in the database") + (:metaclass mito:dao-table-class)) diff --git a/src/nera.lisp b/src/nera.lisp new file mode 100644 index 0000000..063657f --- /dev/null +++ b/src/nera.lisp @@ -0,0 +1,416 @@ +(in-package #:cl-user) +(defpackage #:nera-db + (:nicknames #:nera) + (:use #:cl + #:app-constants + #:hermetic + #:ritherdon-archive.db + #:utils + #:validation + #:user + #:pages + #:files + #:site-settings + #:archive) + (:export #:init-db + #:update-user + #:get-user + #:get-user-id + #:delete-user + #:create-user + #:get-site-settings + #:migrate-all + #:get-all-users + #:update-enable-sign-on-settings + #:set-home-page + #:update-enable-site-logo-setting + #:update-site-name + #:update-search-url + #:create-page + #:update-page + #:get-page + #:delete-page + #:get-all-pages + #:nav-menu-slugs + #:update-nav-menu + #:system-data + #:add-storage-file + #:get-storage-file + #:get-all-storage-files + #:rename-storage-file + #:delete-storage-file + #:get-all-archive-entries + #:create-archive-entry + #:get-archive-entry + #:delete-archive-entry + #:update-archive-entry-property + #:latest-archive-editted-entries + #:latest-editted-pages + #:latest-storage-editted-files + #:update-single-nav-menu-item + #:get-newer-archive-entries + #:get-older-archive-entries)) +(in-package #:nera-db) + +(defparameter *tables* '(user site-settings page storage-file archive-entry) + "List of the DB tables that need to be checked for migrations and DB setup.") + +(defun init-db (request) + "Creates the database and creates Admin. in `USER' table." + (destructuring-bind + (&key site-name allow-sign-up show-site-logo username display-name + password search-url &allow-other-keys) + (utils:request-params request) + (with-connection (db) + ;; Add to the list to add more tables. + (mapcar #'mito:ensure-table-exists *tables*) + (mito:create-dao 'user + :username username + :display-name display-name + :password (hermetic::hash password) + :administrator +true+) + (mito:create-dao 'site-settings + :site-name site-name + :search-url search-url + :enable-sign-up (utils:checkbox-to-bool allow-sign-up) + :enable-site-logo (utils:checkbox-to-bool show-site-logo)) + (mito:create-dao 'page + :title "Home" + :slug "home" + :enable-nav-menu +true+ + :can-delete +true+) + (mito:create-dao 'page + :title "About" + :slug "about" + :enable-nav-menu +true+ + :can-delete +true+) + (mito:create-dao 'page + :title "Contact" + :slug "contact" + :enable-nav-menu +true+ + :can-delete +true+) + (mito:create-dao 'page + :title "Search" + :slug "search" + :enable-nav-menu +true+ + :can-delete +false+) + (mito:create-dao 'page + :title "Pages" + :slug "pages" + :enable-nav-menu +true+ + :can-delete +false+) + (mito:create-dao 'page + :title "Archive" + :slug "archive" + :enable-nav-menu +true+ + :can-delete +false+) + (mito:create-dao 'page + :title "Sign-Up" + :slug "sign-up" + :enable-nav-menu +true+ + :can-delete +false+) + (mito:create-dao 'page + :title "Log-In" + :slug "login" + :enable-nav-menu +true+ + :can-delete +false+)))) + +(defun ensure-tables-exist () + "Creates missing tables from the database." + (with-connection (db) + (mapcar #'mito:ensure-table-exists *tables*))) + +(defun migrate-all () + "Migrate the tables after we changed the class definition." + (with-connection (db) + (ensure-tables-exist) + (mapcar #'mito:migrate-table *tables*))) + +(defun create-user (username display-name password administrator) + "Add a new `USER' to the database." + (with-connection (db) + (mito:create-dao 'user + :username username + :display-name display-name + :administrator administrator + :password (hermetic::hash password)))) + +(defun delete-user (username) + "Deletes `USER' from the database." + (with-connection (db) + (mito:delete-by-values 'user:user :username username))) + +(defun update-user (username &key display-name new-password) + "Updates `USER' in database." + (with-connection (db) + (let ((user-to-update + (mito:find-dao 'user:user :username username))) + (if (not (validation:string-is-nil-or-empty? display-name)) + (setf (user::display-name-of user-to-update) display-name)) + (if (not (validation:string-is-nil-or-empty? new-password)) + (setf (user::password-of user-to-update) (hermetic::hash new-password))) + (mito:save-dao user-to-update)))) + +(defun get-user-id (username) + "Returns the Id. number of the specified `USERNAME' in the database." + (with-connection (db) + (mito:object-id + (mito:find-dao 'user :username username)))) + +(defun get-user (username) + "Returns a `USER' profile from the database." + (with-connection (db) + (mito:find-dao 'user :username username))) + +(defun get-all-users () + "Returns a list of all `USER' entries in the database." + (with-connection (db) + (mito:select-dao 'user + (sxql:order-by (:asc :display-name))))) + +(defun get-page (slug) + "Returns a `PAGE' from the database." + (with-connection (db) (mito:find-dao 'page :slug slug))) + +(defun get-all-pages () + "Returns a list of all `PAGE' entries in the database." + (with-connection (db) + (mito:select-dao 'page + (sxql:order-by (:asc :slug))))) + +(defun latest-editted-pages (amount &optional reverse) + "Gets the latest `AMOUNT' of edited entries from the database. +`REVERSE' is an optional parameter which puts the most recently +editted article entry as the first item in the list.." + (with-connection (db) + (mito:select-dao 'pages:page + (sxql:limit amount) + (if reverse + (sxql:order-by (:desc 'pages::updated-at)) + (sxql:order-by 'pages::updated-at))))) + +(defun create-page (title slug nav-menu can-delete) + "Add a new `PAGE' to the database." + (with-connection (db) + (mito:create-dao 'page :title title :slug slug + :enable-nav-menu nav-menu :can-delete can-delete))) + +(defun update-page (id title slug &optional nav-menu can-delete) + "Add a new `PAGE' to the database." + (with-connection (db) + (let ((page-to-update (mito:find-dao 'page :id id))) + (if (not (validation:string-is-nil-or-empty? title)) + (setf (pages::title-of page-to-update) title)) + (if (not (validation:string-is-nil-or-empty? slug)) + (setf (pages::slug-of page-to-update) slug)) + (if (not (null nav-menu)) + (setf (pages::enable-nav-menu-p page-to-update) nav-menu)) + (if (not (null can-delete)) + (setf (pages::can-delete-p page-to-update) can-delete)) + (mito:save-dao page-to-update)))) + +(defun delete-page (&key id slug) + "Delete `PAGE' from the database." + (with-connection (db) + (cond ((not slug) + (mito:delete-dao (mito:find-dao 'page :id id))) + ((not id) + (mito:delete-dao (mito:find-dao 'page :slug slug))) + (t nil)))) + +(defun get-site-settings () + "Gets the settings for the website from the database." + (with-connection (db) + (mito:find-dao 'site-settings))) + +(defun update-enable-sign-on-settings (value) + "Updates the 'Enable Sign Up' setting in the database with `VALUE'." + (with-connection (db) + (let ((settings-to-update (mito:find-dao 'site-settings))) + (setf (site-settings::enable-sign-up-p settings-to-update) + (utils:checkbox-to-bool value)) + (mito:save-dao settings-to-update)))) + +(defun update-enable-site-logo-setting (value) + "Updates the 'Enable Site Logo' setting in the database with `VALUE'." + (with-connection (db) + (let ((settings-to-update (mito:find-dao 'site-settings))) + (setf (site-settings::enable-site-logo-p settings-to-update) + (utils:checkbox-to-bool value)) + (mito:save-dao settings-to-update)))) + +(defun set-home-page (value) + "Sets the page (in /storage/pages) to be displayed on the sites home page." + (with-connection (db) + (let ((settings-to-update (mito:find-dao 'site-settings))) + (setf (site-settings::home-page-of settings-to-update) value) + (mito:save-dao settings-to-update)))) + +(defun update-search-url (search-url) + "Sets the page (in /storage/pages) to be displayed on the sites home page." + (with-connection (db) + (let ((settings-to-update (mito:find-dao 'site-settings))) + (setf (site-settings::search-url-of settings-to-update) search-url) + (mito:save-dao settings-to-update)))) + +(defun update-site-name (name) + "Updates the website's `SITE-NAME' the database." + (with-connection (db) + (let ((settings-to-update (mito:find-dao 'site-settings))) + (setf (site-settings::site-name-of settings-to-update) name) + (mito:save-dao settings-to-update)))) + +(defun update-nav-menu (selected-pages) + "Updates the `ENABLE-NAV-MENU' property in `PAGE' database." + (loop for page in selected-pages + do (with-connection (db) + (let ((page-to-update (mito:find-dao 'page :slug (car page)))) + (setf (pages::enable-nav-menu-p page-to-update) + (utils:checkbox-to-bool (cdr page))) + (mito:save-dao page-to-update))))) + +(defun update-single-nav-menu-item (slug show-in-nav) + "Toggles a single page from the navigation menu." + (with-connection (db) + (let ((page-to-update (mito:find-dao 'page :slug slug))) + (setf (pages::enable-nav-menu-p page-to-update) show-in-nav) + ;; (utils:checkbox-to-bool show-in-nav)) + (mito:save-dao page-to-update)))) + +(defun nav-menu-slugs () + (with-connection (db) + (mito:select-dao 'page + (sxql:where (:= :enable-nav-menu +true+))))) + +(defun system-data () + "Gets the website's settings and nav-menu from database." + (list (get-site-settings) (nav-menu-slugs))) + +(defun add-storage-file (filename slug file-type) + "Add a row to the 'storage_file' table in the database." + (with-connection (db) + (mito:create-dao 'storage-file + :name filename + :slug slug + :file-type file-type))) + +(defun get-storage-file (&key filename slug) + "Returns a `STORAGE-FILE' row from the database. `NIL' if nothing found." + (with-connection (db) + (if (null slug) + (mito:find-dao 'files:storage-file :name filename) + (mito:find-dao 'files:storage-file :slug slug)))) + +(defun latest-storage-editted-files (amount &optional reverse) + "Gets the latest `AMOUNT' of edited entries from the database. +`REVERSE' is an optional parameter which puts the most recently +editted article entry as the first item in the list.." + (with-connection (db) + (mito:select-dao 'storage-file + (sxql:limit amount) + (if reverse + (sxql:order-by (:desc 'storage::updated-at)) + (sxql:order-by 'storage::updated-at))))) + +(defun get-all-storage-files () + "Returns a list of all `STORAGE-FILES' entries in the database." + (with-connection (db) + (mito:select-dao 'storage-file + (sxql:order-by (:asc :name))))) + +(defun rename-storage-file (old-file-name new-file-name) + "Renames `STORAGE-FILE' in the database. +The `NAME' is renamed from `OLD-FILE-NAME' to `NEW-FILE-NAME' and the +slug is updated based on `NEW-FILE-NAME'." + (with-connection (db) + (let ((file-to-rename (mito:find-dao 'storage-file :name old-file-name))) + (setf (files::name-of file-to-rename) new-file-name + (files::slug-of file-to-rename) (utils:slugify new-file-name)) + (mito:save-dao file-to-rename)))) + +(defun delete-storage-file (&key name slug) + "Delete `STORAGE-FILE' from database." + (with-connection (db) + (if (null slug) + (mito:delete-by-values 'files:storage-file :name name) + (mito:delete-by-values 'files:storage-file :slug slug)))) + +(defun get-all-archive-entries () + "Returns a list of all `ARCHIVE-ENTRY' entries in the database." + (with-connection (db) + (mito:select-dao 'archive:archive-entry + (sxql:order-by (:desc :created-at))))) + +(defun create-archive-entry + (title search-id slug pub-month pub-year thumbnail-slug thumbnail-file-type keywords) + "Add a new `ARCHIVE-ENTRY' to the database." + (with-connection (db) + (mito:create-dao 'archive:archive-entry + :title title + :search-id search-id + :slug slug + :month pub-month + :year pub-year + :thumbnail-slug thumbnail-slug + :thumbnail-file-type thumbnail-file-type + :keywords keywords))) + +(defun get-archive-entry (&key id title slug) + "Returns a `ARCHIVE-ENTRY' from the database." + (with-connection (db) + (cond ((and (not title) (not slug)) + (mito:find-dao 'archive:archive-entry :id id)) + ((and (not id) (not slug)) + (mito:find-dao 'archive:archive-entry :title title)) + ((and (not id) (not title)) + (mito:find-dao 'archive:archive-entry :slug slug)) + (t nil)))) + +(defun latest-archive-editted-entries (amount &optional reverse) + "Gets the latest `AMOUNT' of edited entries from the database. +`REVERSE' is an optional parameter which puts the most recently +editted article entry as the first item in the list.." + (with-connection (db) + (mito:select-dao 'archive:archive-entry + (sxql:limit amount) + (if reverse + (sxql:order-by (:desc 'archive::updated-at)) + (sxql:order-by 'archive::updated-at))))) + +(defun update-archive-entry-property (&key slug property value) + "Updates an `ARCHIVE-ENTRY' entry in database. +An example of how to use this function is as follows (remove back-slashes): + +(nera:update-archive-entry-property + :slug \"edit-archive-test.html\" + :propery 'archive::keywords-of + :value \"test,image\")" + (with-connection (db) + (let ((entry-to-update + (mito:find-dao 'archive:archive-entry :slug slug))) + (eval `(setf (,property ,entry-to-update) ,value)) + (mito:save-dao entry-to-update)))) + +(defun delete-archive-entry (&key id slug) + "Delete `ARCHIVE-ENTRY' from the database." + (with-connection (db) + (cond ((not slug) + (mito:delete-dao (mito:find-dao 'archive:archive-entry :id id))) + ((not id) + (mito:delete-dao (mito:find-dao 'archive:archive-entry :slug slug)))))) + +(defun get-newer-archive-entries (id amount) + "Returns `AMOUNT' of `ARCHIVE-ENTRY' objects relative to `ID' in database." + (with-connection (db) + (mito:select-dao 'archive:archive-entry + (sxql:where (:> :id id)) + (sxql:order-by :id) + (sxql:limit amount)))) + +(defun get-older-archive-entries (id amount) + "Returns `AMOUNT' of `ARCHIVE-ENTRY' objects relative to `ID' in database." + (with-connection (db) + (mito:select-dao 'archive:archive-entry + (sxql:where (:< :id id)) + (sxql:order-by (:desc :id)) + (sxql:limit amount)))) diff --git a/src/search.lisp b/src/search.lisp new file mode 100644 index 0000000..47046eb --- /dev/null +++ b/src/search.lisp @@ -0,0 +1,185 @@ +(defpackage #:search + (:use #:cl + #:app-constants + #:archive + #:cl-json + #:local-time + #:utils + #:site-settings + #:nera) + (:import-from #:dexador + #:request) + (:export #:build-keywords-string + #:build-payload + #:delete-entry + #:find-entry + #:get-id + #:get-keywords + #:submit-entry + #:set-filter-attributes + #:delete-all-entries + #:create-dump + #:update-ranking-rules + #:repopulate-database + #:delete-index)) +(in-package #:search) + +;; Explains the "~{~A~^,~}" in the format call below. +;; https://stackoverflow.com/questions/8830888/whats-the-canonical-way-to-join-strings-in-a-list +(defun build-keywords-string (id) + "Gets the keywords for `ID' in meilisearch DB and formats into a string. +The string should look something like: 'art,blog post,testing,whatever'. One +thing to note is meilisearch uses the comma to separate and create tokens of the +string. So, the user can have spaces in their keywords but they cannot separate +the keywords with a space. 'art blog post' is classed as three tokens and +'art,blog post' is classes as two." + (format nil "~{~A~^,~}" (search:get-keywords (search:find-entry id)))) + +(defun build-payload (id-value title-value relative-path-value + thumbnail-path-value publish-month-value publish-year-value keywords-value) + "Creates a JSON object which reflects the schema in the meilsearch database. +Note: The JSON object to encoded as a string." + (cl-json:encode-json-to-string + `((("id" . ,id-value) + ("title" . ,title-value) + ("relative-path" . ,relative-path-value) + ("thumbnail-path" . ,thumbnail-path-value) + ("year" . ,publish-year-value) + ("month" . ,publish-month-value) + ("keywords" . ,(cl-ppcre:split "," keywords-value)))))) + +(defun build-search-url (path) + "Constructs the URL to connect to the meilisearch instance (beta or prod.) +The function will check to see which environment the current instance of this +site is running in and use the beta or prod. URL's to connect to meilisearch. +`PATH' is the relative path which this function will concatenate onto the end of +the base URL." + + ;; (if (ritherdon-archive.config:developmentp) + ;; (concatenate 'string "http://localhost:7700" path) + ;; ;; (utils:build-url-root) + ;; (concatenate 'string "https://www.nera.com" path)) + + (format nil "~a~a" (site-settings::search-url-of (nera:get-site-settings)) path)) + +(defun delete-entry (id) + "Deletes and entry from the meilisearch database based on its `ID'. +This does not affect this website's (nera) database -- only the meilisearch +one." + (dexador:request + (build-search-url + (format nil "/indexes/nera/documents/~a" id)); (get-id (find-entry id)))) + :method :delete + :use-connection-pool nil + :headers `(("Authorization" . ,(meilisearch-api-key))) + :verbose nil)) + + +(defun documents-total () + "Gets the total number of documents in the meilisearch database." + (rest + (second + (second + (assoc :indexes (cl-json:decode-json-from-string + (dexador:request (build-search-url "/stats") + :method :get + :use-connection-pool nil + :headers `(("Content-Type" . "application/json") + ("Authorization" . ,(meilisearch-api-key))) + :verbose nil))))))) + +(defun find-entry (title) + "Finds the entry in the meilisearch database by its `TITLE'." + (cl-json:decode-json-from-string + (dexador:request + (build-search-url "/indexes/nera/search") + :method :post + :use-connection-pool nil + :headers `(("Content-Type" . "application/json") + ("Authorization" . ,(meilisearch-api-key))) + :content (format nil "{ \"q\": \"~a\", \"limit\": 1 }" title) + :verbose nil))) + +(defun get-id (payload) + "Gets the id from the JSON `PAYLOAD', make sure limit is set to 1." + (rest (third (second (first payload))))) + +(defun get-keywords (payload) + "Get the keywords from the JSON `PAYLOAD'." + (rest (first (last (last (second (first payload))))))) + +(defun meilisearch-api-key () + "Returns either the beta or prod. API key for meilisearch. +The API key is determined based on which environment this website is +currently running in." + (if (ritherdon-archive.config:developmentp) + "Bearer meilisearch-beta-key" + "Bearer meilisearch-production-key-nera")) + +(defun submit-entry (payload) + "Adds a new article to the meilisearch database." + (dexador:request ;;"http://127.0.0.1:7700/indexes/nera/documents" + (build-search-url "/indexes/nera/documents") + :method :post + :use-connection-pool nil + :headers `(("Content-Type" . "application/json") + ("Authorization" . ,(meilisearch-api-key))) + :content payload + :verbose nil)) + +(defun set-filter-attributes () + "Sets the filter attributes in the Meilisearch database. +These values are hard-coded into the system because they are based on what Nic +has requested. She would like the filtering to consist on years and months." + (utils:run-bash-command + (format nil "curl -X PATCH \'~a\' -H \'Authorization: ~a\' -H \'Content-Type: application/json\' --data-binary \'{ \"filterableAttributes\": [ \"year\", \"month\", \"keywords\" ]}\'" + (build-search-url "/indexes/nera/settings") (meilisearch-api-key)))) + +(defun delete-all-entries () + "Deletes all the archive entries in the Meilisearch database -- not the DB." + (utils:run-bash-command + (format nil "curl -X DELETE \'~a\'" + (build-search-url "/indexes/nera/documents")))) + +(defun create-dump () + "Creates a dump of the Meilisearch database." + (utils:run-bash-command + (format nil "curl -X POST \'~a\'" (build-search-url "/dumps")))) + +(defun update-ranking-rules () + "Updates the way Meilisearch ranks and orders the search results. +The main intention for this function is to show the latest entries into the +database first (when no search term is entered by the user)." + (utils:run-bash-command + (format nil "curl -X PATCH \'~a\' -H \'Authorization: ~a\' -H \'Content-Type: application/json\' --data-binary \'[ \"words\", \"typo\", \"proximity\", \"attribute\", \"sort\", \"exactness\",\"rank:asc\", \"year:desc\" ]\'" + (build-search-url "/indexes/nera/settings") (meilisearch-api-key)))) + +(defun repopulate-database (archive-entries) + "Empties the Meilisearch database and populates it with `ARCHIVE-ENTRIES'." + (delete-all-entries) + (loop for entry in archive-entries + do + (submit-entry + (build-payload (archive::search-id-of entry) + (archive::title-of entry) + (format nil "view/archive/~a" + (archive::slug-of entry)) + (format nil "storage/thumb/archive/~a" + (archive::slug-of entry)) + (archive::month-of entry) + (archive::year-of entry) + (archive::keywords-of entry))))) + +(defun delete-index (index-name) + "Deletes `INDEX-NAME' in Meilisearch DB, doesn't need to be this project. +Because Meilisearch is a seperate service running alongside this website, it can +host searchable databases for other projects on the system. `INDEX-NAME' refers +to those other databases. + +I have not hard-coded this project's database name into this function out of +convenience. I can call this function from SLIME/SLY and clean-up my Meilisearch +dev. instance. It, also, helps if I've made botched this project's DB with an +incorrect name and need to quickly delete it." + (utils:run-bash-command + (format nil "curl -X DELETE \'~a\'" + (build-search-url (format nil "/indexes/~a" index-name))))) diff --git a/src/snapshot.lisp b/src/snapshot.lisp new file mode 100644 index 0000000..ea5e769 --- /dev/null +++ b/src/snapshot.lisp @@ -0,0 +1,62 @@ +(in-package #:cl-user) +(defpackage #:snapshot + (:use #:cl + #:utils + #:storage + #:nera) + (:export + #:take-snapshot + #:restore-from-snapshot + #:delete-snapshot + #:store-snapshot)) +(in-package #:snapshot) + +(defun take-snapshot () + "Takes a Snapshot of the website's data and stores it in /snapshots. +I've not included make a SQL dump of the Meilisearch database here because the +user can repopulate that database after they have restored this website. The +'repopulate' feature is built into the website already." + (let ((snapshot-directory + (format nil "~a_~a/" + (utils:slugify + (site-settings::site-name-of (nera:get-site-settings))) + (utils:create-timestamp-text)))) + (storage:ensure-raw-directory-exists + (format nil "snapshots/~a" snapshot-directory)) + (storage:copy-storage-directory + (format nil "snapshots/~a/storage/" snapshot-directory)) + (storage:copy-raw-directory + "db/" (format nil "snapshots/~a/db/" snapshot-directory)))) + +(defun restore-from-snapshot (snapshot-name) + "Deletes the data in /storage and the DB and replaces it with `SNAPSHOT-NAME'." + (storage:remove-raw-directory "storage/") + (storage:remove-raw-directory "db/") + (storage:copy-raw-directory (format nil "snapshots/~a/storage/" snapshot-name) "storage/") + (storage:copy-raw-directory (format nil "snapshots/~a/db/" snapshot-name) "db/")) + +(defun delete-snapshot (snapshot-name) + "Deletes the snapshot in the /snapshots directory with `SNAPSHOT-NAME'." + (storage:remove-raw-directory (format nil "snapshots/~a/" snapshot-name))) + +(defun store-snapshot (filename data) + "Unzips `SNAPSHOT-FILE' and stores it in /snapshots directory. + +The .zip file is deleted after it has been un-zipped. I did think about moving +the zipped version of the file into the /storage/media directory but there is +too much second guessing going on. I found I was uploading .zip files from the +/storage/media directory and I don't know if users will be uploading .zip files +they had just downloaded from /storage/media. If that is the case, then there +is: + +a.) No need to move it to /storage/madia; +b.) Extra work regarding checks for duplicate entries; and, +c.) I don't know if that is too much 'magic' for users and cause confusion. + +If the user is in a paniced state -- trying to restore their website, confusion +is the thing I want to keep to a minimum for them." + (storage:store-with-raw-path (format nil "snapshots/~a" filename) data) + (zip:unzip (storage:make-raw-path (format nil"snapshots/~a" filename)) + (storage:make-raw-path (format nil "snapshots/~a/" + (pathname-name filename)))) + (storage:remove-file-with-raw-path (format nil "snapshots/~a" filename))) diff --git a/src/status-codes.lisp b/src/status-codes.lisp new file mode 100644 index 0000000..e671687 --- /dev/null +++ b/src/status-codes.lisp @@ -0,0 +1,498 @@ +(in-package #:cl-user) +(defpackage #:status-codes + (:use #:cl + #:app-constants) + (:nicknames #:rfc2616-sec10) + (:export +continue+ + +switching-protocols+ + +ok+ + +created+ + +accepted+ + +non-authoritative-information+ + +no-content+ + +reset-content+ + +partial-content+ + +multiple-choices+ + +moved-permanently+ + +found+ + +see-other+ + +not-modified+ + +use-proxy+ + +temporary-redirect+ + +bad-request+ + +unauthorized+ + +payment-required+ + +forbidden+ + +not-found+ + +method-not-allowed+ + +not-acceptable+ + +proxy-authentication-required+ + +request-timeout+ + +conflict+ + +gone+ + +length-required+ + +precondition-failed+ + +request-entity-too-large+ + +request-uri-too-long+ + +unsupported-media-type+ + +requested-range-not-satisfiable+ + +expectation-failed+ + +internal-server-error+ + +not-implemented+ + +bad-gateway+ + +service-unavailable+ + +gateway-timeout+ + +http-version-not-supported+)) +(in-package #:status-codes) + +#| On Using `DEFINE-CONSTANT' Macro +================================================================================ +I've defined the `DEFINE-CONSTANT' in 'app-constants.lisp' I've explained the +reason why I've using it instead of `DEFCONSTANT' there. The short-story is +`DEFINE-CONSTANT' is easier to work with when using SBCL. +|# + +(define-constant +continue+ 100 + "The client SHOULD continue with its request. This interim response is + used to inform the client that the initial part of the request has + been received and has not yet been rejected by the server. The client + SHOULD continue by sending the remainder of the request or, if the + request has already been completed, ignore this response. The server + MUST send a final response after the request has been completed. See + section 8.2.3 for detailed discussion of the use and handling of this + status code.") +(define-constant +switching-PROTOCOLS+ 101 + "The server understands and is willing to comply with the client's + request, via the Upgrade message header field (section 14.42), for a + change in the application protocol being used on this connection. The + server will switch protocols to those defined by the response's + Upgrade header field immediately after the empty line which + terminates the 101 response. + The protocol SHOULD be switched only when it is advantageous to do + so. For example, switching to a newer version of HTTP is advantageous + over older versions, and switching to a real-time, synchronous + protocol might be advantageous when delivering resources that use + such features.") +(define-constant +ok+ 200 + "The request has succeeded. The information returned with the response + is dependent on the method used in the request, for example: + GET an entity corresponding to the requested resource is sent in + the response; + HEAD the entity-header fields corresponding to the requested + resource are sent in the response without any message-body; + POST an entity describing or containing the result of the action; + TRACE an entity containing the request message as received by the + end server.") +(define-constant +created+ 201 + "The request has been fulfilled and resulted in a new resource being + created. The newly created resource can be referenced by the URI(s) + returned in the entity of the response, with the most specific URI + for the resource given by a Location header field. The response + SHOULD include an entity containing a list of resource + characteristics and location(s) from which the user or user agent can + choose the one most appropriate. The entity format is specified by + the media type given in the Content-Type header field. The origin + server MUST create the resource before returning the 201 status code. + If the action cannot be carried out immediately, the server SHOULD + respond with 202 (Accepted) response instead. + A 201 response MAY contain an ETag response header field indicating + the current value of the entity tag for the requested variant just + created, see section 14.19.") +(define-constant +accepted+ 202 + "The request has been accepted for processing, but the processing has + not been completed. The request might or might not eventually be + acted upon, as it might be disallowed when processing actually takes + place. There is no facility for re-sending a status code from an + asynchronous operation such as this. + The 202 response is intentionally non-committal. Its purpose is to + allow a server to accept a request for some other process (perhaps a + batch-oriented process that is only run once per day) without + requiring that the user agent's connection to the server persist + until the process is completed. The entity returned with this + response SHOULD include an indication of the request's current status + and either a pointer to a status monitor or some estimate of when the + user can expect the request to be fulfilled.") +(define-constant +non-authoritative-information+ 203 + "The returned metainformation in the entity-header is not the + definitive set as available from the origin server, but is gathered + from a local or a third-party copy. The set presented MAY be a subset + or superset of the original version. For example, including local + annotation information about the resource might result in a superset + of the metainformation known by the origin server. Use of this + response code is not required and is only appropriate when the + response would otherwise be 200 (OK).") +(define-constant +no-content+ 204 + "The server has fulfilled the request but does not need to return an + entity-body, and might want to return updated metainformation. The + response MAY include new or updated metainformation in the form of + entity-headers, which if present SHOULD be associated with the + requested variant. + If the client is a user agent, it SHOULD NOT change its document view + from that which caused the request to be sent. This response is + primarily intended to allow input for actions to take place without + causing a change to the user agent's active document view, although + any new or updated metainformation SHOULD be applied to the document + currently in the user agent's active view. + The 204 response MUST NOT include a message-body, and thus is always + terminated by the first empty line after the header fields.") +(define-constant +reset-content+ 205 + "The server has fulfilled the request and the user agent SHOULD reset + the document view which caused the request to be sent. This response + is primarily intended to allow input for actions to take place via + user input, followed by a clearing of the form in which the input is + given so that the user can easily initiate another input action. The + response MUST NOT include an entity.") +(define-constant +partial-content+ 206 + "The server has fulfilled the partial GET request for the resource. + The request MUST have included a Range header field (section 14.35) + indicating the desired range, and MAY have included an If-Range + header field (section 14.27) to make the request conditional. + The response MUST include the following header fields: + - Either a Content-Range header field (section 14.16) indicating + the range included with this response, or a multipart/byteranges + Content-Type including Content-Range fields for each part. If a + Content-Length header field is present in the response, its + value MUST match the actual number of OCTETs transmitted in the + message-body. + - Date + - ETag and/or Content-Location, if the header would have been sent + in a 200 response to the same request + - Expires, Cache-Control, and/or Vary, if the field-value might + differ from that sent in any previous response for the same + variant + If the 206 response is the result of an If-Range request that used a + strong cache validator (see section 13.3.3), the response SHOULD NOT + include other entity-headers. If the response is the result of an + If-Range request that used a weak validator, the response MUST NOT + include other entity-headers; this prevents inconsistencies between + cached entity-bodies and updated headers. Otherwise, the response + MUST include all of the entity-headers that would have been returned + with a 200 (OK) response to the same request. + A cache MUST NOT combine a 206 response with other previously cached + content if the ETag or Last-Modified headers do not match exactly, + see 13.5.4. + A cache that does not support the Range and Content-Range headers + MUST NOT cache 206 (Partial) responses.") +(define-constant +multiple-choices+ 300 + "The requested resource corresponds to any one of a set of + representations, each with its own specific location, and agent- + driven negotiation information (section 12) is being provided so that + the user (or user agent) can select a preferred representation and + redirect its request to that location. + Unless it was a HEAD request, the response SHOULD include an entity + containing a list of resource characteristics and location(s) from + which the user or user agent can choose the one most appropriate. The + entity format is specified by the media type given in the Content- + Type header field. Depending upon the format and the capabilities of + the user agent, selection of the most appropriate choice MAY be + performed automatically. However, this specification does not define + any standard for such automatic selection. + If the server has a preferred choice of representation, it SHOULD + include the specific URI for that representation in the Location + field; user agents MAY use the Location field value for automatic + redirection. This response is cacheable unless indicated otherwise.") +(define-constant +moved-permanently+ 301 + "The requested resource has been assigned a new permanent URI and any + future references to this resource SHOULD use one of the returned + URIs. Clients with link editing capabilities ought to automatically + re-link references to the Request-URI to one or more of the new + references returned by the server, where possible. This response is + cacheable unless indicated otherwise. + The new permanent URI SHOULD be given by the Location field in the + response. Unless the request method was HEAD, the entity of the + response SHOULD contain a short hypertext note with a hyperlink to + the new URI(s). + If the 301 status code is received in response to a request other + than GET or HEAD, the user agent MUST NOT automatically redirect the + request unless it can be confirmed by the user, since this might + change the conditions under which the request was issued. + Note: When automatically redirecting a POST request after + receiving a 301 status code, some existing HTTP/1.0 user agents + will erroneously change it into a GET request.") +(define-constant +found+ 302 + "The requested resource resides temporarily under a different URI. + Since the redirection might be altered on occasion, the client SHOULD + continue to use the Request-URI for future requests. This response + is only cacheable if indicated by a Cache-Control or Expires header + field. + The temporary URI SHOULD be given by the Location field in the + response. Unless the request method was HEAD, the entity of the + response SHOULD contain a short hypertext note with a hyperlink to + the new URI(s). + If the 302 status code is received in response to a request other + than GET or HEAD, the user agent MUST NOT automatically redirect the + request unless it can be confirmed by the user, since this might + change the conditions under which the request was issued. + Note: RFC 1945 and RFC 2068 specify that the client is not allowed + to change the method on the redirected request. However, most + existing user agent implementations treat 302 as if it were a 303 + response, performing a GET on the Location field-value regardless + of the original request method. The status codes 303 and 307 have + been added for servers that wish to make unambiguously clear which + kind of reaction is expected of the client.") +(define-constant +see-other+ 303 + "The response to the request can be found under a different URI and + SHOULD be retrieved using a GET method on that resource. This method + exists primarily to allow the output of a POST-activated script to + redirect the user agent to a selected resource. The new URI is not a + substitute reference for the originally requested resource. The 303 + response MUST NOT be cached, but the response to the second + (redirected) request might be cacheable. + The different URI SHOULD be given by the Location field in the + response. Unless the request method was HEAD, the entity of the + response SHOULD contain a short hypertext note with a hyperlink to + the new URI(s). + Note: Many pre-HTTP/1.1 user agents do not understand the 303 + status. When interoperability with such clients is a concern, the + 302 status code may be used instead, since most user agents react + to a 302 response as described here for 303.") +(define-constant +not-modified+ 304 + "If the client has performed a conditional GET request and access is + allowed, but the document has not been modified, the server SHOULD + respond with this status code. The 304 response MUST NOT contain a + message-body, and thus is always terminated by the first empty line + after the header fields. + The response MUST include the following header fields: + - Date, unless its omission is required by section 14.18.1 + If a clockless origin server obeys these rules, and proxies and + clients add their own Date to any response received without one (as + already specified by [RFC 2068], section 14.19), caches will operate + correctly. + - ETag and/or Content-Location, if the header would have been sent + in a 200 response to the same request + - Expires, Cache-Control, and/or Vary, if the field-value might + differ from that sent in any previous response for the same + variant + If the conditional GET used a strong cache validator (see section + 13.3.3), the response SHOULD NOT include other entity-headers. + Otherwise (i.e., the conditional GET used a weak validator), the + response MUST NOT include other entity-headers; this prevents + inconsistencies between cached entity-bodies and updated headers. + If a 304 response indicates an entity not currently cached, then the + cache MUST disregard the response and repeat the request without the + conditional. + If a cache uses a received 304 response to update a cache entry, the + cache MUST update the entry to reflect any new field values given in + the response.") +(define-constant +use-proxy+ 305 + "The requested resource MUST be accessed through the proxy given by + the Location field. The Location field gives the URI of the proxy. + The recipient is expected to repeat this single request via the + proxy. 305 responses MUST only be generated by origin servers. + Note: RFC 2068 was not clear that 305 was intended to redirect a + single request, and to be generated by origin servers only. Not + observing these limitations has significant security consequences.") +(define-constant +temporary-redirect+ 307 + "The requested resource resides temporarily under a different URI. + Since the redirection MAY be altered on occasion, the client SHOULD + continue to use the Request-URI for future requests. This response + is only cacheable if indicated by a Cache-Control or Expires header + field. + The temporary URI SHOULD be given by the Location field in the + response. Unless the request method was HEAD, the entity of the + response SHOULD contain a short hypertext note with a hyperlink to + the new URI(s) , since many pre-HTTP/1.1 user agents do not + understand the 307 status. Therefore, the note SHOULD contain the + information necessary for a user to repeat the original request on + the new URI. + If the 307 status code is received in response to a request other + than GET or HEAD, the user agent MUST NOT automatically redirect the + request unless it can be confirmed by the user, since this might + change the conditions under which the request was issued.") +(define-constant +bad-request+ 400 + "The request could not be understood by the server due to malformed + syntax. The client SHOULD NOT repeat the request without + modifications.") +(define-constant +unauthorized+ 401 + "The request requires user authentication. The response MUST include a + WWW-Authenticate header field (section 14.47) containing a challenge + applicable to the requested resource. The client MAY repeat the + request with a suitable Authorization header field (section 14.8). If + the request already included Authorization credentials, then the 401 + response indicates that authorization has been refused for those + credentials. If the 401 response contains the same challenge as the + prior response, and the user agent has already attempted + authentication at least once, then the user SHOULD be presented the + entity that was given in the response, since that entity might + include relevant diagnostic information. HTTP access authentication + is explained in \"HTTP Authentication: Basic and Digest Access + Authentication\" [43].") +(define-constant +payment-required+ 402 + "This code is reserved for future use.") +(define-constant +forbidden+ 403 + "The server understood the request, but is refusing to fulfill it. + Authorization will not help and the request SHOULD NOT be repeated. + If the request method was not HEAD and the server wishes to make + public why the request has not been fulfilled, it SHOULD describe the + reason for the refusal in the entity. If the server does not wish to + make this information available to the client, the status code 404 + (Not Found) can be used instead.") +(define-constant +not-found+ 404 + "The server has not found anything matching the Request-URI. No + indication is given of whether the condition is temporary or + permanent. The 410 (Gone) status code SHOULD be used if the server + knows, through some internally configurable mechanism, that an old + resource is permanently unavailable and has no forwarding address. + This status code is commonly used when the server does not wish to + reveal exactly why the request has been refused, or when no other + response is applicable.") +(define-constant +method-not-allowed+ 405 + "The method specified in the Request-Line is not allowed for the + resource identified by the Request-URI. The response MUST include an + Allow header containing a list of valid methods for the requested + resource.") +(define-constant +not-acceptable+ 406 + "The resource identified by the request is only capable of generating + response entities which have content characteristics not acceptable + according to the accept headers sent in the request. + Unless it was a HEAD request, the response SHOULD include an entity + containing a list of available entity characteristics and location(s) + from which the user or user agent can choose the one most + appropriate. The entity format is specified by the media type given + in the Content-Type header field. Depending upon the format and the + capabilities of the user agent, selection of the most appropriate + choice MAY be performed automatically. However, this specification + does not define any standard for such automatic selection. + Note: HTTP/1.1 servers are allowed to return responses which are + not acceptable according to the accept headers sent in the + request. In some cases, this may even be preferable to sending a + 406 response. User agents are encouraged to inspect the headers of + an incoming response to determine if it is acceptable. + If the response could be unacceptable, a user agent SHOULD + temporarily stop receipt of more data and query the user for a + decision on further actions.") +(define-constant +proxy-authentication-required+ 407 + "This code is similar to 401 (Unauthorized), but indicates that the + client must first authenticate itself with the proxy. The proxy MUST + return a Proxy-Authenticate header field (section 14.33) containing a + challenge applicable to the proxy for the requested resource. The + client MAY repeat the request with a suitable Proxy-Authorization + header field (section 14.34). HTTP access authentication is explained + in \"HTTP Authentication: Basic and Digest Access Authentication\" + [43].") +(define-constant +request-timeout+ 408 + "The client did not produce a request within the time that the server + was prepared to wait. The client MAY repeat the request without + modifications at any later time.") +(define-constant +conflict+ 409 + "The request could not be completed due to a conflict with the current + state of the resource. This code is only allowed in situations where + it is expected that the user might be able to resolve the conflict + and resubmit the request. The response body SHOULD include enough + information for the user to recognize the source of the conflict. + Ideally, the response entity would include enough information for the + user or user agent to fix the problem; however, that might not be + possible and is not required. + Conflicts are most likely to occur in response to a PUT request. For + example, if versioning were being used and the entity being PUT + included changes to a resource which conflict with those made by an + earlier (third-party) request, the server might use the 409 response + to indicate that it can't complete the request. In this case, the + response entity would likely contain a list of the differences + between the two versions in a format defined by the response + Content-Type.") +(define-constant +gone+ 410 + "The requested resource is no longer available at the server and no + forwarding address is known. This condition is expected to be + considered permanent. Clients with link editing capabilities SHOULD + delete references to the Request-URI after user approval. If the + server does not know, or has no facility to determine, whether or not + the condition is permanent, the status code 404 (Not Found) SHOULD be + used instead. This response is cacheable unless indicated otherwise. + The 410 response is primarily intended to assist the task of web + maintenance by notifying the recipient that the resource is + intentionally unavailable and that the server owners desire that + remote links to that resource be removed. Such an event is common for + limited-time, promotional services and for resources belonging to + individuals no longer working at the server's site. It is not + necessary to mark all permanently unavailable resources as \"gone\" or + to keep the mark for any length of time -- that is left to the + discretion of the server owner.") +(define-constant +length-required+ 411 + "The server refuses to accept the request without a defined Content- + Length. The client MAY repeat the request if it adds a valid + Content-Length header field containing the length of the message-body + in the request message.") +(define-constant +precondition-failed+ 412 + "The precondition given in one or more of the request-header fields + evaluated to false when it was tested on the server. This response + code allows the client to place preconditions on the current resource + metainformation (header field data) and thus prevent the requested + method from being applied to a resource other than the one intended.") +(define-constant +request-entity-too-large+ 413 + "The server is refusing to process a request because the request + entity is larger than the server is willing or able to process. The + server MAY close the connection to prevent the client from continuing + the request. + If the condition is temporary, the server SHOULD include a Retry- + After header field to indicate that it is temporary and after what + time the client MAY try again.") +(define-constant +request-uri-too-long+ 414 + "The server is refusing to service the request because the Request-URI + is longer than the server is willing to interpret. This rare + condition is only likely to occur when a client has improperly + converted a POST request to a GET request with long query + information, when the client has descended into a URI \"black hole\" of + redirection (e.g., a redirected URI prefix that points to a suffix of + itself), or when the server is under attack by a client attempting to + exploit security holes present in some servers using fixed-length + buffers for reading or manipulating the Request-URI.") +(define-constant +unsupported-media-type+ 415 + "The server is refusing to service the request because the entity of + the request is in a format not supported by the requested resource + for the requested method.") +(define-constant +requested-range-not-satisfiable+ 416 + "A server SHOULD return a response with this status code if a request + included a Range request-header field (section 14.35), and none of + the range-specifier values in this field overlap the current extent + of the selected resource, and the request did not include an If-Range + request-header field. (For byte-ranges, this means that the first- + byte-pos of all of the byte-range-spec values were greater than the + current length of the selected resource.) + When this status code is returned for a byte-range request, the + response SHOULD include a Content-Range entity-header field + specifying the current length of the selected resource (see section + 14.16). This response MUST NOT use the multipart/byteranges content- + type.") +(define-constant +expectation-failed+ 417 + "The expectation given in an Expect request-header field (see section + 14.20) could not be met by this server, or, if the server is a proxy, + the server has unambiguous evidence that the request could not be met + by the next-hop server.") +(define-constant +internal-server-error+ 500 + "The server encountered an unexpected condition which prevented it + from fulfilling the request.") +(define-constant +not-implemented+ 501 + "The server does not support the functionality required to fulfill the + request. This is the appropriate response when the server does not + recognize the request method and is not capable of supporting it for + any resource.") +(define-constant +bad-gateway+ 502 + "The server, while acting as a gateway or proxy, received an invalid + response from the upstream server it accessed in attempting to + fulfill the request.") +(define-constant +service-unavailable+ 503 + "The server is currently unable to handle the request due to a + temporary overloading or maintenance of the server. The implication + is that this is a temporary condition which will be alleviated after + some delay. If known, the length of the delay MAY be indicated in a + Retry-After header. If no Retry-After is given, the client SHOULD + handle the response as it would for a 500 response. + Note: The existence of the 503 status code does not imply that a + server must use it when becoming overloaded. Some servers may wish + to simply refuse the connection.") +(define-constant +gateway-timeout+ 504 + "The server, while acting as a gateway or proxy, did not receive a + timely response from the upstream server specified by the URI (e.g. + HTTP, FTP, LDAP) or some other auxiliary server (e.g. DNS) it needed + to access in attempting to complete the request. + Note: Note to implementors: some deployed proxies are known to + return 400 or 500 when DNS lookups time out.") +(define-constant +http-version-not-supported+ 505 + "The server does not support, or refuses to support, the HTTP protocol + version that was used in the request message. The server is + indicating that it is unable or unwilling to complete the request + using the same major version as the client, as described in section + 3.1, other than with this error message. The response SHOULD contain + an entity describing why that version is not supported and what other + protocols are supported by that server.") diff --git a/src/storage.lisp b/src/storage.lisp new file mode 100644 index 0000000..bef3f50 --- /dev/null +++ b/src/storage.lisp @@ -0,0 +1,317 @@ +(in-package #:cl-user) +(defpackage #:storage + (:use #:cl + #:copy-directory) + (:export #:init-storage + #:directory-exists-p + #:ensure-directory-exists + #:file-exists-p + #:get-files-in-directory + #:get-file-names + #:make-path + #:open-file + #:open-binary-file + #:open-text-file + #:remove-directory + #:remove-file + #:rename-content-file + #:rename-directory + #:store-file + #:store-text + #:store-with-raw-path + #:store-text-with-raw-path + #:open-text-file-with-raw-path + #:store-test + #:remove-file-with-raw-path + #:make-raw-path + #:ensure-raw-directory-exists + #:remove-raw-directory + #:copy-storage-directory + #:copy-raw-directory + #:get-files-in-raw-directory + #:get-raw-subdirectories + #:raw-directory-exists?)) +(in-package #:storage) + +(defun init-storage () + "Copies the initial files into their default places. +This is used as part of the /run-set defroute in web.lisp file." + (ensure-directory-exists "" "pages") + (uiop:copy-file (make-path "" "default-assets" "about") + (make-path "" "pages" "about")) + + (uiop:copy-file (make-path "" "default-assets" "contact") + (make-path "" "pages" "contact")) + + (uiop:copy-file (make-path "" "default-assets" "home") + (make-path "" "pages" "home")) + + (uiop:copy-file (make-path "" "default-assets" "site-logo.png") + (merge-pathnames "static/images/site-logo.png" + ritherdon-archive.config:*application-root*)) + (uiop:copy-file (make-path "" "default-assets" "favicon.png") + (merge-pathnames "static/images/favicon.png" + ritherdon-archive.config:*application-root*)) + (ensure-directory-exists "" "snippets") + (uiop:copy-file (make-path "" "default-assets" "site-wide-snippet.html") + (make-path "" "snippets" "site-wide-snippet.html")) + ;; Nothing is added to /storage/media yet, this is just prep. work. + (ensure-directory-exists "" "media") + (ensure-raw-directory-exists "snapshots/")) + +(defun copy-storage-directory (target-path) + "Copies the contents of /storage directory to `TARGET-PATH'. +Make sure `TARGET-PATH' ends with a slash (E.G. snapshots/oct-2022/). Without +it, the system will assume you're trying to work with a file and throw an +error." + (copy-directory:copy (make-raw-path "storage/") (make-raw-path target-path))) + +(defun copy-raw-directory (source-path target-path) + "Copies a directory (`SOURCE-PATH') outside of /storage to `TARGET-PATH'." + (copy-directory:copy (make-raw-path source-path) (make-raw-path target-path))) + +(defun directory-exists-p (username directory) + "Checks to see if the specified diretory exists. +The directories path is returned if it does exist and `NIL' is +returned if the directory cannot be found." + (cl:probe-file (make-path username directory ""))) + +(defun ensure-raw-directory-exists (directory-path) + "Creates directory if it doesn't exist (use for working outside of /storage). +The directories path is returned if it does exist and `NIL' is returned if the +directory cannot be found." + (ensure-directories-exist (make-raw-path directory-path))) + +(defun ensure-directory-exists (username directory) + "The project's standardised way to call `ENSURE-DIRECTORY-EXISTS'. +If the directory exists, the full (absolute) path is +returned (equating to `T', otherwiser `NIL' it returned." + ;; The empty string for `SLUG' (3rd arg.) is used because + ;; `MAKE-PATH' can form paths for files. In this instance, only the + ;; directory needs to be formed. The empty string kinda acts like + ;; `NIL' but it is a bit of a hack, I will admit. + (ensure-directories-exist (make-path username directory ""))) + +(defun file-exists-p (username subdirectory slug) + "This project's standardised way to call `CL:PROBE-FILE'. +If the file exists, the full (absolute) path is returned (equates to +`T', otherwise `NIL' is returned." + (cl:probe-file (make-path username subdirectory slug))) + +(defun get-files-in-directory (username directory) + "Returns a list of paths for the files in `DIRECTORY' in the /storage directory. +`USERNAME' is the subdirectory in /storage. If you are not implementing or have +a need for creating sub-directories in /storage, pass in an empty string \"\" . +Full directory structure: /storage/`USERNAME'/`DIRECTORY' + +When empty string used for 'username': /storage/`DIRECTORY'" + (uiop:directory-files (make-path username directory ""))) + +(defun get-file-names (filenames) + "Returns a list of file names from a list of paths in `FILENAMES'. +Make sure you call `STORAGE:GET-FILES-IN-DIRECTORY' and pass as `FILENAMES' when +calling this function." + (mapcar #'(lambda (x) (file-namestring x)) filenames)) + +(defun get-raw-directories (directory-path) + "Returns a list of paths for the files in `DIRECTORY-PATH' outside /storage directory." + (cl-fad:list-directory (make-raw-path directory-path))) + +(defun raw-directory-exists? (directory-path) + "Checks to see if directory at `DIRECTORY-PATH' (no directory make if none found)." + (cl-fad:directory-exists-p (make-raw-path directory-path))) + +(defun get-directory-names (directory-names) + "Returns the final part of a directories absolute path in `DIRECTORY-NAMES'. +Make sure you use `GET-RAW-DIRECTORIES' to build the `DIRECTORY-NAMES' list." + (mapcar #'(lambda (x) (first (last (pathname-directory x)))) directory-names)) + +(defun make-path (username subdirectory slug) + "Forms the path used to save a file. +Storage path: +`*APPLICATION-ROOT*'/storage/`USERNAME'/`SUBDIRECTORY'/`SLUG' +Each user has their own directory in /storage. This is so I can build a media +manager at a later date -- I had not got around to writing it at the time I +implemented this function/feature. I decided to go with `USERNAME' and +not (user-)`ID' is because I wanted to easily identify the directories in +/storage." + (merge-pathnames (format nil "storage/~A/~A/~A" + username subdirectory slug) + ritherdon-archive.config:*application-root*)) + +(defun make-raw-path (path) + "Make a file/directory path outsite of the /storage directory." + (merge-pathnames path ritherdon-archive.config:*application-root*)) + +(defun open-binary-file (username subdirectory slug) + "Reads the file stored in the /storage directory." + (with-open-file (stream + (make-path username subdirectory slug) + :element-type '(unsigned-byte 8)) + (let* ((length (file-length stream)) + (buffer (make-array length + :element-type '(unsigned-byte 8)))) + (read-sequence buffer stream) + (values buffer length)))) + +(defun open-text-file (username subdirectory slug) + "Reads the text (.md) file stored in the /storage directory." + (with-open-file (stream (make-path username subdirectory slug)) + (let ((data (make-string (file-length stream)))) + (read-sequence data stream) + data))) + +(defun remove-raw-directory (directory-path) + "Removes directory at `DIRECTORY-PATH' when outside /storage directory." + (cl-fad:delete-directory-and-files (make-raw-path directory-path))) + +(defun remove-directory (username subdirectory) + "Deletes an directory in /storage. +Path template: `*APPLICATION-ROOT*'/storage/`USERNAME'/`SUBDIRECTORY'/' +- https://edicl.github.io/cl-fad/#delete-directory-and-files +- https://stackoverflow.com/questions/24350183/how-do-i-delete-a-directory-in-common-lisp +'cl-fad' (files and directories) is a wrapper package over the various +Common Lisp implementions to aid in keeping your Common Lisp code +portable. At the time of writing (February 2022), the website is using +Steel Bank Common Lisp (SBCL) but this allow you to use something else +if you want or need to switch." + (cl-fad:delete-directory-and-files (make-path username subdirectory ""))) + +(defun rename-directory (username original-directory new-directory) + "Renames a sub-directory in the /storage directory. +`USERNAME' is the directory holding the one which is to be +changed. `ORIGINAL-DIRECTORY' is the 'source' (in the usual Linux/Bash +CLI sense). `NEW-DIRECTORY' is the name the `ORIGINAL-DIRECTORY' will +be changed to. There are various examples of the path +structure/template in other comments in this file. Have a look +around (don't want to repeat myself)." + (rename-file (make-path username original-directory "") + (make-path username new-directory ""))) + +(defun remove-file (username subdirectory slug) + "Deletes the specified file, stored in the /storage directory. +Before calling this function, make sure the file exists. You should have +'file-exists-p' available to you -- within this (storage) package." + (delete-file (make-path username subdirectory slug))) + +(defun rename-content-file (username subdirectory old-slug new-slug) + "This project's standardised way to call `RENAME-FILE'." + (rename-file (make-path username subdirectory old-slug) + (make-path username subdirectory new-slug))) + +(defun store-file-old (username subdirectory filename data) + "OBSOLETE. USE `STORE-FILE'." + (let ((path (ensure-directories-exist + (make-path username subdirectory filename)))) + (cond ((or (string= (caddr data) "application/gzip") + (string= (caddr data) "application/zip") + (string= (caddr data) "application/epub+zip")) + (uiop:copy-file (slot-value (car data) 'pathname) path)) + (t (with-open-file (stream + path + :direction :output + :if-does-not-exist :create + :element-type '(unsigned-byte 8) + :if-exists :supersede) + (write-sequence (slot-value (car data) 'vector) stream)))))) + +(defun store-file (username subdirectory filename data) + "Stores the uploaded file to the /storage directory. +Storage path: `*APPLICATION-ROOT*'/storage/`USERNAME'/`SUBDIRECTORY'/`FILENAME' +`DATA' is the actual contents which will be written to the said path." + (let ((path (ensure-directories-exist + (make-path username subdirectory filename)))) + (cond ((equal (type-of (car data)) 'SB-SYS:FD-STREAM) + (uiop:copy-file (slot-value (car data) 'pathname) path)) + (t + (with-open-file (stream + path + :direction :output + :if-does-not-exist :create + :element-type '(unsigned-byte 8) + :if-exists :supersede) + (write-sequence (slot-value (car data) 'vector) stream)))))) + +(defun store-text (username subdirectory filename data) + "Stores the plain text to the /storage directory. +Storage path: `*APPLICATION-ROOT*'/storage/`USERNAME'/`SUBDIRECTORY'/`FILENAME' +`DATA' is the actual text/data which will be written to the said path." + (let ((path (ensure-directories-exist + (make-path username subdirectory filename)))) + (with-open-file (stream + path + :direction :output + :if-does-not-exist :create + :if-exists :supersede) + (format stream "~a~%" data)))) + +(defun store-with-raw-path (path data) + "Stores `DATA' at `PATH'. Use when storing data outsite of /storage directory." + (let ((path (ensure-directories-exist + (merge-pathnames path + ritherdon-archive.config::*application-root*)))) + (cond ((equal (type-of (car data)) 'SB-SYS:FD-STREAM) + (uiop:copy-file (slot-value (car data) 'pathname) path)) + (t + (with-open-file (stream + path + :direction :output + :element-type '(unsigned-byte 8) + :if-does-not-exist :create + :if-exists :supersede) + (write-sequence (slot-value (car data) 'vector) stream)))))) + +(defun store-text-with-raw-path (path data) + "Stores the plain text `DATA' at `PATH'. +Use when storing text outside of /storage direcory." + (let ((path (ensure-directories-exist + (merge-pathnames path + ritherdon-archive.config::*application-root*)))) + (with-open-file (stream + path + :direction :output + :if-does-not-exist :create + :if-exists :supersede) + (format stream "~a~%" data)))) + +(defun open-text-file-with-raw-path (file-path) + "Reads the text file stored in the at `PATH'. +Use when reading text outside the /storage directory." + (let ((path (ensure-directories-exist + (merge-pathnames file-path + ritherdon-archive.config::*application-root*)))) + (with-open-file (stream path) + (let ((data (make-string (file-length stream)))) + (read-sequence data stream) + data)))) + + +(defun remove-file-with-raw-path (file-path) + "Deletes the specified file, at `PATH', use this to delete file outsite of /storage. +Before calling this function, make sure the file exists. You should have +'file-exists-p' available to you -- within this (storage) package." + (delete-file (merge-pathnames file-path ritherdon-archive.config::*application-root*))) + +;;; PORTED FROM RAILS-TO-CAVEMAN PROJECT (expect it to be deleted) +;;; ============================================================================= + +(defun prin1-to-base64-string (object) + (cl-base64:string-to-base64-string (prin1-to-string object))) + +(defun read-from-base64-string(string) + (values (read-from-string + (cl-base64:base64-string-to-string string)))) + +;;; This function requires ImageMagick so you will need to install it +;;; with 'sudo apt install imagemagick' (assuming you are on a +;;; Debian-based system). +;; (defun convert (id subdirectory original-file converted-file) +;; (let ((command (format nil "convert -geometry ~A ~A ~A" +;; (file-size converted-file) +;; (make-storage-pathname id subdirectory original-file) +;; (make-storage-pathname id subdirectory converted-file)))) +;; (let ((message (nth-value 1 +;; (uiop:run-program command +;; :ignore-error-status t +;; :error-output :string)))) +;; (when message (error message))))) diff --git a/src/utils.lisp b/src/utils.lisp new file mode 100644 index 0000000..56d22a7 --- /dev/null +++ b/src/utils.lisp @@ -0,0 +1,200 @@ +(in-package #:cl-user) +(defpackage #:utils + (:use #:cl + #:caveman2 + #:log4cl + #:xml-emitter + #:app-constants + #:storage) + (:export #:request-params + #:separate-files-in-web-request + #:set-alert + #:get-alert + #:get-and-reset-alert + #:checkbox-to-bool + #:asciify + #:slugify + #:get-image-dimensions + #:run-bash-command + #:create-thumbnail + #:create-timestamp-id + #:format-filename + #:format-keywords + #:build-alert-string + #:month-number-to-name + #:build-url-root + #:build-url + #:create-timestamp-text) + (:documentation "Utilities that do not depend on models.")) + +(in-package #:utils) + +(defun asciify (string) + (str:downcase (slug:asciify string))) + +(defun slugify (string) + "Turns a string of text into a slug." + (str:downcase (slug:slugify string))) + +(defun format-filename (string) + "Changes the filename into the system's standard. +Replaces whitespace with '-' and changes everything to lowecase." + (str:replace-all " " "-" (asciify string))) + +(defun format-keywords (string) + "Formats the keywords used in the `ARCHIVE-ENTRY' class. +This is mostly just over-prep'ing the keywords assuming the user +enters them in the incorrect format. Meilisearch exects something like +'art,welding,green paint,ritherdon'. The comma is the seperator which +allows each 'keyword' to have (white-)spaces." + (str:replace-all ", " "," (asciify string))) + +(defun request-params (request) + (loop :for (key . value) :in request + :collect (let ((*package* (find-package :keyword))) + (read-from-string key)) + :collect value)) + +(defun separate-files-in-web-request (request &optional request-value) + "Creates a new list of 'upload' files from a web `REQUEST'. +You will mostly use this for processing a multi-file upload (HTML) +form. The standard value for the 'name' attribute in (file) input tag +in the HTML form is `CONTENT-FILES' but you can use a different +name. Just specify it in this function's `REQUEST-VALUE' argument." + (loop :for item :in request + if (or (string= "CONTENT-FILES" (car item)) + (string= request-value (car item))) + collect item)) + +(defun set-alert (message &optional alert-type) + "Sets the alert `MESSAGE' stored in session, provide info. to users. +The intention is store a `MESSAGE' across a redirect during a HTTP +POST request." + (cond ((string= "error" alert-type) + (setf (gethash :alert ningle:*session*) + (build-alert-string alert-type "vomit-cat.png" message))) + ((string= "success" alert-type) + (setf (gethash :alert ningle:*session*) + (build-alert-string alert-type "success-cat.png" message))) + ((string= "missing-data" alert-type) + (setf (gethash :alert ningle:*session*) + (build-alert-string alert-type "sherlock-cat.png" message))) + ((string= "invalid-data" alert-type) + (setf (gethash :alert ningle:*session*) + (build-alert-string alert-type "confused-cat.png" message))) + ((string= "created" alert-type) + (setf (gethash :alert ningle:*session*) + (build-alert-string alert-type "disco-cat.png" message))) + ((string= "warning" alert-type) + (setf (gethash :alert ningle:*session*) + (build-alert-string alert-type "workout-cat.png" message))) + (t (setf (gethash :alert ningle:*session*) message)))) + +(defun build-alert-string (alert-text src-image message) + (format nil + "

\"~a\"~a

" + alert-text + alert-text + src-image + message)) + +(defun get-alert () + "Get alert message from session data." + (gethash :alert ningle:*session*)) + +(defun get-and-reset-alert () + "Returns the `ALERT' message and clears its content from the session hash." + (let ((message (get-alert))) + (set-alert nil) + message)) + +(defun checkbox-to-bool (value) + "Converts a HTML Checkbox `VALUE' to a Boolean. +The `VALUE' will either be 'on' or 'off'. 'Boolean' in this instance +is assuming you are using SQLite and need to convert `VALUE' to an +integer/number. If you are needing a traditional Boolean value, DO NOT USE +THIS FUNCTION." + (cond ((or (string= "checked" value) (string= "on" value)) +true+) + ((or (string= "off" value) (null value)) +false+) + ((null value) +false+))) + +(defun get-image-dimensions (filepath) + "Uses Image Magick (via Bash) to get the resolution of an image as 'WxH'. +The `FILEPATH' must be already merged with +`ritherdon-archive.config::*application-root*' before you call this function." + (let* ((command + (format nil "identify -format \"%wx%h\" ~a" filepath)) + (out-message (uiop:run-program command :output :string + :ignore-error-status t + :error-output :string))) + out-message)) + +(defun run-bash-command (command) + "Runs the Bash command." + (uiop:run-program command :output :string + :ignore-error-status t + :error-output :string)) + +(defun create-thumbnail (storage-sub-directory file-name &optional (overwrite t)) + "Runs a Bash command to convert a file to a thumbnail in /storage/media dir. +The file is reduced to 512x512 pixels if bigger than that. A new file +is then created with a 'thumbnail-' pre-fix. This process relies on +Image Magick. So, it must be installed on the system for this function +to operate properly." + (run-bash-command + (format nil "convert ~a -resize 512x512\\> ~a" + (storage:file-exists-p "" storage-sub-directory file-name) + (if (eq overwrite t) + (storage:file-exists-p "" storage-sub-directory file-name) + (storage:make-path "" storage-sub-directory + (format nil "thumbnail-~a" file-name)))))) + +(defun create-timestamp-id () + "Creates a integer based on time the function is called, in YYYYMMDD format." + (multiple-value-bind + (second minute hour day month year) + (get-decoded-time) + (format nil "~d~2,'0d~d~2,'0d~2,'0d~2,'0d" year month day hour minute second))) + +(defun create-timestamp-text () + "Creates a text-based timestamp (value being the time function was called)." + (multiple-value-bind + (second minute hour day month year) + (get-decoded-time) + (format nil "~d-~2,'0d-~d_~2,'0d-~2,'0d-~2,'0d" year month day hour minute second))) + +(defun month-number-to-name (month-number) + "Converts `MONTHS-NUMBER' to its name (E.G. 1 to 'January')." + (cond ((= 1 month-number) "January") + ((= 2 month-number) "February") + ((= 3 month-number) "March") + ((= 4 month-number) "April") + ((= 5 month-number) "May") + ((= 6 month-number) "June") + ((= 7 month-number) "July") + ((= 8 month-number) "August") + ((= 9 month-number) "September") + ((= 10 month-number) "October") + ((= 11 month-number) "November") + ((= 12 month-number) "December") + (t nil))) + +(defun build-url (request) + "Concatenates parts of the web request to form the full URL the user requested." + (format nil "~a://~a~a~a" + (lack.request:request-uri-scheme request) + (lack.request:request-server-name request) + (if (string= "localhost" (lack.request:request-server-name request)) + (format nil ":~a" (lack.request:request-server-port request)) + "") + (lack.request:request-uri request))) + +(defun build-url-root (request) + "Concatenates parts of the web request to form site's root URL. +This is mostly used for generating the site map (XML file for crawlers)." + (format nil "~a://~a~a" + (lack.request:request-uri-scheme request) + (lack.request:request-server-name request) + (if (string= "localhost" (lack.request:request-server-name request)) + (format nil ":~a" (lack.request:request-server-port request)) + ""))) diff --git a/src/validation.lisp b/src/validation.lisp new file mode 100644 index 0000000..a87e671 --- /dev/null +++ b/src/validation.lisp @@ -0,0 +1,57 @@ +(in-package #:cl-user) +(defpackage #:validation + (:use #:cl + #:app-constants) + (:export #:has-static-assets-extention? + #:is-valid-favicon-type? + #:favicon-need-resizing? + #:string-is-nil-or-empty?) + (:documentation "Package for validating 'stuff'.")) +(in-package #:validation) + +(defun file-has-valid-static-assets-extention? (filename) + (cond ((or (string= "css" (pathname-type filename)) + (string= "js" (pathname-type filename)) + (string= "png" (pathname-type filename)) + (string= "ico" (pathname-type filename)) + (string= "gif" (pathname-type filename)) + (string= "jpg" (pathname-type filename)) + (string= "svg" (pathname-type filename)) + (string= "txt" (pathname-type filename))) + filename) + (t nil))) + +(defun file-is-valid-favicon-type? (filename) + "Returns path of file if `FILE' is a valid favicon. +Valid file types are 'ico', 'gif' and 'png'." + (cond ((or (string= "png" (pathname-type filename)) + (string= "ico" (pathname-type filename)) + (string= "gif" (pathname-type filename))) + filename) + (t nil))) + +(defun string-is-nil-or-empty? (string-to-test) + "Tests to see if `STRING-TO-TEST' is empty of just whitespace. +This is essentially the 'IsNullOrWhiteSpace' function I use in C#. It +expands the 'empty string' check to include a check to see if there is +string with just a '(white) space' in it." + (if (or (string= string-to-test " ") + (zerop (length string-to-test)) + (null string-to-test)) + t + nil)) + +(defun favicon-need-resizing? (dimensions) + "Checks to see if the `WIDTH' or `HEIGHT' are greater than 192x192 pixels. +`DIMENSIONS' is a cons list, with the `WIDTH' being first element and +`HEIGHT' being the second. If either of them are, then you look into +scaling down the image, using code in the `UTILS' package probably." + (cond ((or (< 192 (car dimensions)) (< 192 (cdr dimensions))) + t) ; True as in the dimensions are valid + (t ;; Bit confusing with the use of `T' here but its standard + ;; practice to end `COND' with a catch-all `T'. In this + ;; case, `T' here means the dimensions are invalid, as in + ;; 'yes' the favicon needs resizing. This is confusing + ;; Boolean logic but when you call this function, the + ;; return types make sense from that point-of-view. + nil))) diff --git a/src/view.lisp b/src/view.lisp index b6b8037..761ab7d 100644 --- a/src/view.lisp +++ b/src/view.lisp @@ -1,21 +1,21 @@ -(in-package :cl-user) -(defpackage ritherdon-archive.view - (:use :cl) - (:import-from :ritherdon-archive.config - :*template-directory*) - (:import-from :caveman2 - :*response* - :response-headers) - (:import-from :djula - :add-template-directory - :compile-template* - :render-template* - :*djula-execute-package*) - (:import-from :datafly - :encode-json) - (:export :render - :render-json)) -(in-package :ritherdon-archive.view) +(in-package #:cl-user) +(defpackage #:ritherdon-archive.view + (:use #:cl) + (:import-from #:ritherdon-archive.config + #:*template-directory*) + (:import-from #:caveman2 + #:*response* + #:response-headers) + (:import-from #:djula + #:add-template-directory + #:compile-template* + #:render-template* + #:*djula-execute-package*) + (:import-from #:datafly + :encode-json) + (:export #:render + #:render-json)) +(in-package #:ritherdon-archive.view) (djula:add-template-directory *template-directory*) @@ -34,18 +34,100 @@ (setf (getf (response-headers *response*) :content-type) "application/json") (encode-json object)) - ;; ;; Execute package definition (defpackage ritherdon-archive.djula - (:use :cl) - (:import-from :ritherdon-archive.config - :config - :appenv - :developmentp - :productionp) - (:import-from :caveman2 - :url-for)) + (:use #:cl + #:storage) + (:import-from #:files + #:storage-file) + (:import-from #:ritherdon-archive.config + #:config + #:appenv + #:developmentp + #:productionp) + (:import-from #:caveman2 + #:url-for)) + +;; Added 'in-package' line after default Caveman2 set-up. Needed for custom +;; functions. Not part of Caveman2 set-up. +(in-package #:ritherdon-archive.djula) (setf djula:*djula-execute-package* (find-package :ritherdon-archive.djula)) + +;; Custom filters and template code added below... +;; ============================================================================= + +;; This filter is for converting Integers used to store Boolean values +;; in a SQLite database. The intended place you will use this filter +;; is in the /software section. The most notable parts being the /add +;; and /edit sections. In the SQLite database, I have set: +;; - 0 => false +;; - 1 => true. +;; In this case, if the `VALUE' is not 1, it is always false (I.E. 0). +(djula:def-filter :integer-to-checkbox (value) + (format nil "~S" (if (= 1 value) "on" "off"))) + +(djula:def-filter :build-thumbnail-path (file) + (cond ((str:contains? "svg" (files::file-type-of file) :ignore-case t) + (format nil "/images/icons/svg.png")) + ((str:contains? "image" (files::file-type-of file) :ignore-case t) + (format nil "/storage/thumb/media/~a" (files::slug-of file))) + ((str:contains? "pdf" (files::file-type-of file) :ignore-case t) + (format nil "/images/icons/pdf.png")) + ((str:contains? "html" (files::file-type-of file) :ignore-case t) + (format nil "/images/icons/code.png")) + ((str:contains? "text" (files::file-type-of file) :ignore-case t) + (format nil "/images/icons/txt.png")) + ((str:contains? "css" (files::file-type-of file) :ignore-case t) + (format nil "/images/icons/code2.png")) + ((str:contains? "video" (files::file-type-of file) :ignore-case t) + (format nil "/images/icons/video.png")) + ((str:contains? "audio" (files::file-type-of file) :ignore-case t) + (format nil "/images/icons/audio.png")) + ((str:contains? "zip" (files::file-type-of file) :ignore-case t) + (format nil "/images/icons/archive.png")) + (t (format nil "/images/icons/file.png")))) + +(defun insert-snippet (snippet-name) + (if (storage:file-exists-p "" "snippets" snippet-name) + (format nil "~a" (storage:open-text-file "" "snippets" snippet-name)) + (format nil "" snippet-name))) + +(defun insert-dashboard-cat () + (let ((timestamp (local-time:now))) + (cond ((and (= (local-time:timestamp-day timestamp) 8) + (= (local-time:timestamp-month timestamp) 2)) + (format nil "/images/icons/birthday-cat.png")) + ((and (>= (local-time:timestamp-hour timestamp) 6) + (< (local-time:timestamp-hour timestamp) 10)) + (format nil "/images/icons/morning-cat.png")) + ((and (>= (local-time:timestamp-hour timestamp) 10) + (< (local-time:timestamp-hour timestamp) 12)) + (format nil "/images/icons/coffee-cat.png")) + ((and (>= (local-time:timestamp-hour timestamp) 12) + (< (local-time:timestamp-hour timestamp) 14)) + (format nil "/images/icons/dinner-cat.png")) + ((and (>= (local-time:timestamp-hour timestamp) 14) + (< (local-time:timestamp-hour timestamp) 18)) + (format nil "/images/icons/study-cat.png")) + ((and (>= (local-time:timestamp-hour timestamp) 18) + (< (local-time:timestamp-hour timestamp) 20)) + (cond + ;; Sunday + ((= (local-time:timestamp-day-of-week timestamp) 0) + (format nil "/images/icons/love-cat.png")) + ;; Monday - Friday + ((<= (local-time:timestamp-day-of-week timestamp) 5) + (format nil "/images/icons/workout-cat.png")) + ;; Saturday + ((= (local-time:timestamp-day-of-week timestamp) 6) + (format nil "/images/icons/rock-star-cat.png")))) + ((and (>= (local-time:timestamp-hour timestamp) 20) + (< (local-time:timestamp-hour timestamp) 22)) + (format nil "/images/icons/dinner-cat.png")) + ((and (>= (local-time:timestamp-hour timestamp) 22) + (< (local-time:timestamp-hour timestamp) 24)) + (format nil "/images/icons/bed-time-cat.png")) + (t (format nil "/images/icons/default-cat.png"))))) diff --git a/src/web.lisp b/src/web.lisp index 1cc7130..211d82f 100644 --- a/src/web.lisp +++ b/src/web.lisp @@ -1,14 +1,27 @@ -(in-package :cl-user) -(defpackage ritherdon-archive.web - (:use :cl - :caveman2 - :ritherdon-archive.config - :ritherdon-archive.view - :ritherdon-archive.db - :datafly - :sxql) - (:export :*web*)) -(in-package :ritherdon-archive.web) +(in-package #:cl-user) +(defpackage #:ritherdon-archive.web + (:use #:cl + #:caveman2 + #:ritherdon-archive.config + #:ritherdon-archive.view + #:ritherdon-archive.db + #:datafly + #:sxql + #:cl-pass + #:app-constants + #:status-codes ; (HTTP Status Codes) + #:hermetic + #:auth + #:utils + #:validation + #:user + #:zip + #:nera-db + #:files + #:search + #:snapshot) + (:export #:*web*)) +(in-package #:ritherdon-archive.web) ;; for @route annotation (syntax:use-syntax :annot) @@ -24,7 +37,1819 @@ ;; Routing rules (defroute "/" () - (render #P"index.html")) + (cond ((not (uiop:file-exists-p (ritherdon-archive.config:database-name))) + (redirect "/setup")) + ((string= "archive" (site-settings::home-page-of (nera:get-site-settings))) + (redirect "/archive")) + ((string= "login" (site-settings::home-page-of (nera:get-site-settings))) + (redirect "/login")) + ((string= "pages" (site-settings::home-page-of (nera:get-site-settings))) + (redirect "/pages")) + ((string= "search" (site-settings::home-page-of (nera:get-site-settings))) + (redirect "/search")) + ((string= "sign-up" (site-settings::home-page-of (nera:get-site-settings))) + (redirect "/sign-up")) + (t (render #P"index.html" + (append (if (hermetic:logged-in-p) + (auth:auth-user-data)) + `(:alert ,(utils:get-and-reset-alert) + :nav-menu ,(nera:nav-menu-slugs) + :system-data ,(nera:system-data) + :content ,(storage:open-text-file + "" "pages" + (site-settings::home-page-of + (nera:get-site-settings))))))))) + +(defroute "/setup" () + ;; If there is no database, there is no user, hence no more checks. + (cond ((not (uiop:file-exists-p (ritherdon-archive.config:database-name))) + (render #P"initial-setup.html" `(:token ,(auth:csrf-token)))) + (t `(,+service-unavailable+ (:location "/"))))) + +(defroute ("/run-setup" :method :POST) () + (destructuring-bind (&key authenticity-token &allow-other-keys) + (utils:request-params + (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + ((uiop:file-exists-p (ritherdon-archive.config:database-name)) + `(,+service-unavailable+ (:location "/"))) + (t (nera-db:init-db + (lack.request:request-body-parameters ningle:*request*)) + (storage:init-storage) + ;; Redirect to /setup-complete? + (utils:set-alert "All set-up. Log-in to continue." "created") + (redirect "/login"))))) + +(defroute ("/sign-up" :method :GET) () + (if (= +false+ (site-settings::enable-sign-up-p (nera:get-site-settings))) + (progn + (utils:set-alert "This feature has been disabled." "warning") + (redirect "/")) + (hermetic:auth (:logged-in) + ;; Hermetic Authorised (Logged in users can't sign-up). + (progn + (utils:set-alert + "You need to be signed out to create a new account." + "warning") + (redirect "/dashboard")) + ;; Hermetic Not Authorised + (let ((alert (utils:get-and-reset-alert))) + (render "sign-up.html" + `(:token ,(auth:csrf-token) + :system-data ,(nera:system-data) + :alert ,alert)))))) + +(defroute ("/sign-up" :method :POST) () + (destructuring-bind + (&key username display-name password password-check + authenticity-token &allow-other-keys) + (utils:request-params + (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + ((not (null (nera:get-user username))) + (utils:set-alert "Username already taken." "warning") + (redirect "/sign-up")) + ((not (string= password password-check)) + (utils:set-alert "Passwords don't match." "invalid-data") + (redirect "/sign-up")) + ((find t (mapcar + #'validation:string-is-nil-or-empty? + `(,username ,display-name ,password))) + (utils:set-alert "Incomplete form. Please fill out every section." + "missing-data") + (redirect "/sign-up")) + (t (hermetic:auth + (:logged-in) + ;; Authorised (Logged in user can't sign-up). + (progn (utils:set-alert "Logged in users are not allowed to create account." + "warning") + (redirect "/dashboard")) + ;; Not Authorised + (progn + (nera-db:create-user username display-name password +false+) + (utils:set-alert "Account created." "created") + (redirect "/login"))))))) + +(defroute ("/login" :method :GET) () + (hermetic:auth (:logged-in) + ;; Authorised + (redirect "/dashboard") + ;; Not Authorised + (let ((alert (utils:get-and-reset-alert))) + (render "user/log-in.html" + `(:token ,(auth:csrf-token) + :system-data ,(nera:system-data) + :alert ,alert))))) + +(defroute ("/login" :method :POST) () + (destructuring-bind + (&key username password authenticity-token &allow-other-keys) + (utils:request-params + (lack.request:request-body-parameters ningle:*request*)) + (if (not (string= authenticity-token (csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied")) + (let ((params (list :|username| username :|password| password))) + (hermetic:login + params + ;; Successful log-in attempt. + (progn + (setf + ;; Set session Id. to the logged in user. + (gethash :id ningle:*session*) (nera:get-user-id username) + ;; Set the users password (for session) + (gethash :password ningle:*session*) password) + (redirect "/dashboard")) + ;; Failed log-in attempt. + (progn (utils:set-alert "Incorrect details provided." + "invalid-data") + (redirect "/login")) + ;; No user found. + (progn (utils:set-alert "Can't find that user." + "missing-data") + (redirect "/login"))))))) + +(defroute ("/logout" :method :POST) () + (destructuring-bind + (&key authenticity-token &allow-other-keys) + (utils:request-params + (lack.request:request-body-parameters ningle:*request*)) + (if (not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied")) + (hermetic:auth (:logged-in) + (hermetic:logout + ;; Successful log-out. + (progn (auth:flash-gethash :id ningle:*session*) + (redirect "/")) + ;; Failed log-out + (progn (utils:set-alert "Error: Unable to log out." + "error") + (redirect "/"))))))) + +(defroute ("/dashboard" :method :GET) () + (hermetic:auth (:logged-in) + ;; Authorised + (let ((alert (utils:get-and-reset-alert))) + (render #P"user/dashboard.html" + (append (auth:auth-user-data) + `(:alert ,alert + :storage-files + ,(nera:latest-storage-editted-files 5 t) + :pages ,(nera:latest-editted-pages 5 t) + :archive-entries + ,(nera::latest-archive-editted-entries 5 t) + :disk-info + ,(first (diskspace:list-all-disk-info t)) + :system-data ,(nera:system-data))))) + ;; Not Authorised + (progn (utils:set-alert "You are not logged in." "error") + (redirect "/login")))) + +(defroute ("/site-settings" :method :GET) () + (hermetic:auth + (:administrator) + ;; Authorised + (render #P"user/site-settings.html" + (append (auth:auth-user-data) + `(:alert ,(utils:get-and-reset-alert) + :pages ,(nera:get-all-pages) + :system-data ,(nera:system-data) + :site-wide-snippet ,(storage:open-text-file + "" "snippets" "site-wide-snippet.html") + ;; Should this be replaced by `SYSTEM-DATA'? + :settings ,(nera:get-site-settings)))) + ;; Not Authorised + (progn + (utils:set-alert "You are not authorised to view this page." "error") + (redirect "/login")))) + +(defroute ("/site-settings/update-sign-up" :method :POST) () + (destructuring-bind + (&key enable-sign-up authenticity-token &allow-other-keys) + (utils:request-params + (lack.request:request-body-parameters ningle:*request*)) + (if (not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied")) + (hermetic:auth (:administrator) + ;; Authorised + (progn + (nera:update-enable-sign-on-settings enable-sign-up) + (utils:set-alert "Enable Sign-Up setting updated." "success") + (redirect "/site-settings")) + ;; Not Authorised + (progn + (utils:set-alert "You are not authorised to view this page." + "error") + (redirect "/login")))))) + +(defroute ("/site-settings/update-nav-menu" :method :POST) (&key _parsed) + (destructuring-bind + (&key authenticity-token &allow-other-keys) + (utils:request-params + (lack.request:request-body-parameters ningle:*request*)) + (if (not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied")) + (hermetic:auth (:administrator) + ;; Authorised + (progn + (nera:update-nav-menu (cdr (assoc "NAV-MENU" _parsed :test #'string=))) + (utils:set-alert "Nav. menu updated." "success") + (redirect "/site-settings")) + ;; Not Authorised + (progn + (utils:set-alert "You are not authorised to view this page." + "error") + (redirect "/login")))))) + +(defroute ("/site-settings/update-home-page" :method :POST) () + (destructuring-bind + (&key set-home-page authenticity-token &allow-other-keys) + (utils:request-params + (lack.request:request-body-parameters ningle:*request*)) + (if (not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied")) + (hermetic:auth (:administrator) + ;; Authorised + (cond ((or (string= set-home-page "Select Page") + (validation:string-is-nil-or-empty? set-home-page)) + (utils:set-alert "No value provided. Home page not changed." + "missing-data") + (redirect "/site-settings")) + (t + (nera:set-home-page set-home-page) + (utils:set-alert "Home page set." "success") + (redirect "/site-settings"))) + ;; Not Authorised + (progn + (utils:set-alert "You are not authorised to view this page." + "error") + (redirect "/login")))))) + +(defroute ("/site-settings/update-site-name" :method :POST) () + (destructuring-bind + (&key site-name authenticity-token &allow-other-keys) + (utils:request-params + (lack.request:request-body-parameters ningle:*request*)) + (if (not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied")) + (hermetic:auth (:administrator) + ;; Authorised + (cond ((validation:string-is-nil-or-empty? site-name) + (utils:set-alert "No value provided. Site name not changed." + "missing-data") + (redirect "/site-settings")) + (t + (nera:update-site-name site-name) + (utils:set-alert "Site name updated." "success") + (redirect "/site-settings"))) + ;; Not Authorised + (progn + (utils:set-alert "You are not authorised to view this page." + "error") + (redirect "/login")))))) + +(defroute ("/site-settings/update-code-snippet" :method :POST) () + (destructuring-bind + (&key code-snippet authenticity-token &allow-other-keys) + (utils:request-params + (lack.request:request-body-parameters ningle:*request*)) + (if (not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied")) + (hermetic:auth (:administrator) + ;; Authorised + (progn + (storage:store-text + "" "snippets" "site-wide-snippet.html" code-snippet) + (utils:set-alert "Site-Wide snippet updated." "success") + (redirect "/site-settings")) + ;; Not Authorised + (progn + (utils:set-alert "You are not authorised to view this page." + "error") + (redirect "/login")))))) + +(defroute ("/site-settings/update-favicon" :method :POST) () + (destructuring-bind + (&key favicon-file authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (if (not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied")) + (hermetic:auth + (:administrator) + ;; Authorised + (cond ((validation:string-is-nil-or-empty? (cadr favicon-file)) + (utils:set-alert "No file provided. Favicon not uploaded." + "missing-data") + (redirect "/site-settings")) + ((not (str:contains? + "image" (caddr favicon-file) :ignore-case t)) + (utils:set-alert "Uploaded file is not an image." "invalid-data") + (redirect "/site-settings")) + (t (storage:store-with-raw-path + "static/images/favicon.png" favicon-file) + (utils:set-alert "Favicon saved." "success") + (utils:run-bash-command + (format nil "convert ~a -resize 192x192\\> ~a" + (merge-pathnames + #P"static/images/favicon.png" + ritherdon-archive.config:*application-root*) + (merge-pathnames + #P"static/images/favicon.png" + ritherdon-archive.config:*application-root*))) + (redirect "/site-settings"))) + ;; Not Authorised + (progn + (utils:set-alert "You are not authorised to view this page." "error") + (redirect "/login")))))) + +(defroute ("/site-settings/update-enable-site-logo" :method :POST) () + (destructuring-bind + (&key enable-site-logo authenticity-token &allow-other-keys) + (utils:request-params + (lack.request:request-body-parameters ningle:*request*)) + (if (not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied")) + (hermetic:auth (:administrator) + ;; Authorised + (progn + (nera:update-enable-site-logo-setting enable-site-logo) + (utils:set-alert "Enable Site Logo setting saved." + "success") + (redirect "/site-settings")) + ;; Not Authorised + (progn + (utils:set-alert + "You are not authorised to view this page." "error") + (redirect "/login")))))) + +(defroute ("/site-settings/update-site-logo" :method :POST) () + (destructuring-bind + (&key site-logo authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (if (not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied")) + (hermetic:auth + (:administrator) + ;; Authorised + (cond ((validation:string-is-nil-or-empty? (cadr site-logo)) + (utils:set-alert "No file provided. Site logo not uploaded." + "missing-data") + (redirect "/site-settings")) + ((not (str:contains? + "image" (caddr site-logo) :ignore-case t)) + (utils:set-alert "Uploaded file is not an image." "invalid-data") + (redirect "/site-settings")) + (t (storage:store-with-raw-path + "static/images/site-logo.png" site-logo) + (utils:set-alert "Site logo saved." "success") + (utils:run-bash-command + (format nil "convert ~a -resize 500x500\\> ~a" + (merge-pathnames + #P"static/images/site-logo.png" + ritherdon-archive.config:*application-root*) + (merge-pathnames + #P"static/images/site-logo.png" + ritherdon-archive.config:*application-root*))) + (redirect "/site-settings"))) + ;; Not Authorised + (progn + (utils:set-alert "You are not authorised to view this page." + "error") + (redirect "/login")))))) + +(defroute ("/site-settings/update-search-url" :method :POST) () + (destructuring-bind + (&key search-url authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (if (not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied")) + (hermetic:auth + (:administrator) + ;; Authorised + (cond ((validation:string-is-nil-or-empty? search-url) + (utils:set-alert "No Search URL provided." "missing-data") + (redirect "/site-settings")) + (t (nera:update-search-url search-url) + (utils:set-alert "Search URL updated." "success") + (redirect "/site-settings"))) + ;; Not Authorised + (progn + (utils:set-alert "You are not authorised to view this page." + "error") + (redirect "/login")))))) + +(defroute ("/users" :method :GET) () + (hermetic:auth (:administrator) + ;; Authorised + (let ((alert (utils:get-and-reset-alert))) + (render #P"user/index.html" + (append (auth:auth-user-data) + `(:alert ,alert + :system-data ,(nera:system-data) + :users ,(nera:get-all-users))))) + ;; Not Authorised + (progn + (utils:set-alert "You are not authorised to view this page." + "error") + (redirect "/login")))) + +(defroute ("/user/admin/create" :method :POST) () + (destructuring-bind + (&key username display-name password password-check + authenticity-token &allow-other-keys) + (utils:request-params + (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + ((not (string= password password-check)) + (utils:set-alert "Passwords don't match." "invalid-data") + (redirect "/users")) + ((find t (mapcar + #'validation:string-is-nil-or-empty? + `(,username ,display-name ,password))) + (utils:set-alert "Incomplete form. Please fill out every section." + "missing-data") + (redirect "/users")) + ((not (null (nera:get-user username))) + (utils:set-alert "Username already taken." "warning") + (redirect "/users")) + (t (hermetic:auth + (:administrator) + ;; Authorised + (progn + (nera-db:create-user username display-name password +false+) + (utils:set-alert "Account created." "created") + (redirect "/users")) + ;; Not Authorised + (progn + (utils:set-alert "You are not authorised to view that page." + "error") + (redirect "/"))))))) + +(defroute ("/user/edit" :method :GET) () + (hermetic:auth (:logged-in) + ;; Authorised + (let ((alert (utils:get-and-reset-alert))) + (render #P"user/edit.html" + (append (auth:auth-user-data) + `(:alert ,alert + :system-data ,(nera:system-data))))) + ;; Not Authorised + (progn (utils:set-alert "You are not logged in." "error") + (redirect "/login")))) + +(defroute ("/user/edit/display-name" :method :POST) () + (destructuring-bind + (&key display-name authenticity-token &allow-other-keys) + (utils:request-params + (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:logged-in) + ;; Authorised + (cond ((validation:string-is-nil-or-empty? display-name) + (utils:set-alert "Display name not entered." "missing-data") + (redirect "/user/edit")) + (t (nera-db:update-user + (user::username-of (auth:get-current-user)) + :display-name display-name :new-password nil) + (utils:set-alert "Display name updated." "success") + (redirect "/dashboard"))) + ;; Not Authorised + (progn (utils:set-alert "You are not logged in." "error") + (redirect "/login"))))))) + +(defroute ("/user/edit/password" :method :POST) () + (destructuring-bind + (&key new-password password-check authenticity-token &allow-other-keys) + (utils:request-params + (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:logged-in) + ;; Authorised + (cond ((find t (mapcar + #'validation:string-is-nil-or-empty? + `(,new-password ,password-check))) + (utils:set-alert + "Missing new password data. Make sure both password boxes are filled out." + "missing-data") + (redirect "/user/edit")) + ((not (string= new-password password-check)) + (utils:set-alert "Passwords don't match." "invalid-data") + (redirect "/user/edit")) + (t (nera-db:update-user + (user::username-of (auth:get-current-user)) + :display-name nil :new-password new-password) + (utils:set-alert "Password updated." "success") + (redirect "/dashboard"))) + ;; Not Authorised + (progn (utils:set-alert "You are not logged in." "error") + (redirect "/login"))))))) + +(defroute ("/user/admin/edit-password" :method :POST) () + (destructuring-bind + (&key username password authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:administrator) + ;; Authorised + (cond ((validation:string-is-nil-or-empty? username) + (utils:set-alert "Username not provided. No change made." + "missing-data") + (redirect "/users")) + ((validation:string-is-nil-or-empty? password) + (utils:set-alert "Password not provided. No change made." + "missing-data") + (redirect "/users")) + ((null (nera:get-user username)) + (utils:set-alert "Unable to find user. Unable to delete account" + "invalid-data") + (redirect "/users")) + (t (nera:update-user + (user::username-of (nera:get-user username)) + :new-password password) + (utils:set-alert "Password changed." "success") + (redirect "/users"))) + ;; Not Authorised + (progn (utils:set-alert "You are not authorised to view that page." + "error") + (redirect "/"))))))) + +(defroute ("/user/admin/delete" :method :POST) () + (destructuring-bind + (&key username authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:administrator) + ;; Authorised + (cond ((validation:string-is-nil-or-empty? username) + (utils:set-alert "Username not provided. Unable to delete account." + "missing-data") + (redirect "/users")) + ((null (nera:get-user username)) + (utils:set-alert "Unable to find user. Unable to delete account" + "invalid-data") + (redirect "/users")) + (t (nera:delete-user + (user::username-of (nera:get-user username))) + (utils:set-alert "Account deleted." "success") + (redirect "/users"))) + ;; Not Authorised + (progn (utils:set-alert "You are not logged in." "error") + (redirect "/login"))))))) + +(defroute ("/user/delete" :method :POST) () + (destructuring-bind + (&key authenticity-token delete-account-check &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth (:logged-in) + ;; Authorised + (cond ((validation:string-is-nil-or-empty? delete-account-check) + (utils:set-alert + "No username entered. Account not deleted." + "missing-data") + (redirect "/user/edit")) + ((not (string= delete-account-check + (user::username-of + (auth:get-current-user)))) + (utils:set-alert + "Wrong username entered. Account not deleted." + "invalid-data") + (redirect "/user/edit")) + (t + (progn + (nera-db:delete-user + (user::username-of (auth:get-current-user))) + (hermetic:logout + ;; Successful log-out -- after account deleted + ;; Session data cleared. + (progn (auth:flash-gethash :id ningle:*session*) + (redirect "/")) + ;; Failed log-out -- after account deleted + ;; Session data persits. + (progn (utils:set-alert + "Unable to delete session data." "error") + (redirect "/")))))) + ;; Not Authorised + (progn (utils:set-alert "You are not logged in." + "error") + (redirect "/login"))))))) + +(defroute ("/create/page" :method :GET) () + (hermetic:auth (:logged-in) + ;; Authorised + (let ((alert (utils:get-and-reset-alert))) + (render "/user/create-page.html" + (append (auth:auth-user-data) + `(:alert ,alert + :system-data ,(nera:system-data))))) + ;; Not Authorised + (progn + (utils:set-alert "You are not logged in." "error") + (redirect "/login")))) + +(defroute ("/create/page" :method :POST) () + (destructuring-bind + (&key title page-content authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:logged-in) + ;; Authorised + (cond ((validation:string-is-nil-or-empty? title) + (render + "/user/create-page.html" + (append (auth:auth-user-data) + `(:alert "Title not provided. Unable to save page." + :title ,title + :data ,page-content)))) + + ((storage:file-exists-p "" "pages" (utils:slugify title)) + (render + "/user/create-page.html" + (append (auth:auth-user-data) + `(:alert "Page with that title already exists. Unable to save page." + :title ,title + :data ,page-content)))) + + (t (storage:store-text + "" ; `USERNAME' blank because it's not used/needed. + "pages" + (utils:slugify title) + page-content) + (nera:create-page title (utils:slugify title) +false+ +true+) + (utils:set-alert "Page created." "created") + (redirect "/dashboard"))) + ;; Not Authorised + (progn (utils:set-alert "You are not logged in." "error") + (redirect "/login"))))))) + +(defroute ("/user/pages" :method :GET) () + (hermetic:auth (:logged-in) + ;; Authorised + (let ((alert (utils:get-and-reset-alert))) + (render "/user/pages.html" + (append (auth:auth-user-data) + `(:alert ,alert + :system-data ,(nera:system-data) + :pages ,(nera:get-all-pages))))) + ;; Not Authorised + (progn + (utils:set-alert "You are not logged in." "error") + (redirect "/login")))) + +(defroute ("/pages" :method :GET) () + (let ((alert (utils:get-and-reset-alert))) + (render #P"pages.html" + (append (if (hermetic:logged-in-p) + (auth:auth-user-data)) + `(:alert ,alert + :system-data ,(nera:system-data) + :pages ,(nera:get-all-pages)))))) + +(defroute ("/view/page/:slug" :method :GET) (&key slug) + (let ((alert (utils:get-and-reset-alert))) + (if (storage:file-exists-p "" "pages" slug) + (render #P"page.html" + (append (if (hermetic:logged-in-p) + (auth:auth-user-data)) + `(:alert ,alert + :db-data ,(nera:get-page slug) + :system-data ,(nera:system-data) + :data ,(storage:open-text-file + "" "pages" slug)))) + (on-exception *web* 404)))) + +(defroute ("/edit/page/:slug" :method :GET) (&key slug) + (hermetic:auth (:logged-in) + ;; Authorised + (let ((alert (utils:get-and-reset-alert))) + (render "/user/edit-page.html" + (append (auth:auth-user-data) + `(:alert ,alert + :system-data ,(nera:system-data) + :db-data ,(nera:get-page slug) + :data ,(storage:open-text-file + "" "pages" slug))))) + ;; Not Authorised + (progn + (utils:set-alert "You are not logged in." "error") + (redirect "/login")))) + +(defroute ("/edit/page" :method :POST) () + (destructuring-bind + (&key slug page-content authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:logged-in) + ;; Authorised + (cond ((validation:string-is-nil-or-empty? slug) + (utils:set-alert "Page cannot be found." "missing-data") + (redirect "/user/pages")) + + (t (storage:store-text + "" ; `USERNAME' blank because it's not used/needed. + "pages" slug page-content) + (utils:set-alert "Page updated." "success") + (redirect "/user/pages"))) + ;; Not Authorised + (progn (utils:set-alert "You are not logged in." "error") + (redirect "/login"))))))) + +(defroute ("/rename/page" :method :POST) () + (destructuring-bind + (&key id slug new-title authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:logged-in) + ;; Authorised + (cond ((validation:string-is-nil-or-empty? slug) + (utils:set-alert "Cannot find file. Unable to save changes." + "missing-data") + (redirect "/user/pages")) + + ((validation:string-is-nil-or-empty? new-title) + (utils:set-alert "No title provided. Unable to save changes." + "missing-data") + (redirect (format nil "/edit/page/~a" slug))) + + ((validation:string-is-nil-or-empty? id) + (utils:set-alert "No Id. found. Cannot find page in database." + "missing-data") + (redirect "/user/pages")) + + (t (storage:rename-content-file + "" + "pages" slug (utils:slugify new-title)) + (nera:update-page id new-title (utils:slugify new-title)) + (utils:set-alert "File name changed." "success") + (redirect (format nil "/edit/page/~a" + (utils:slugify new-title))))) + ;; Not Authorised + (progn (utils:set-alert "You are not logged in." "error") + (redirect "/login"))))))) + +(defroute ("/page/set-nav-menu" :method :POST) () + (destructuring-bind + (&key slug show-in-nav authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:logged-in) + ;; Authorised + (cond ((validation:string-is-nil-or-empty? slug) + (utils:set-alert "Cannot find page in database." + "missing-data") + (redirect "/user/pages")) + + (t (nera:update-single-nav-menu-item + slug (if (null show-in-nav) +false+ +true+)) + (utils:set-alert "Update nav. menu settings." "success") + (redirect (format nil "/edit/page/~a" slug)))) + ;; Not Authorised + (progn (utils:set-alert "You are not logged in." "error") + (redirect "/login"))))))) + +(defroute ("/page/delete" :method :POST) () + (destructuring-bind + (&key slug authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:administrator) + ;; Authorised + (cond ((validation:string-is-nil-or-empty? slug) + (utils:set-alert "Cannot find page in database. Nothing deleted." + "missing-data") + (redirect "/user/pages")) + + ((null (storage:file-exists-p "" "pages" slug)) + (utils:set-alert "Unable to find page. Nothing deleted." + "missing-data") + (redirect "/user/pages")) + + ((eql (pages::can-delete-p (nera:get-page slug)) +false+) + (utils:set-alert "File not allowed to be deleted." + "warning") + (redirect "/user/pages")) + + (t (storage:remove-file + "" ; `USERNAME' blank because it's not used/needed. + "pages" slug) + (nera:delete-page :slug slug) + (utils:set-alert "Page deleted." "success") + (redirect "/user/pages"))) + ;; Not Authorised + (progn (utils:set-alert "You are not authorised to delete page." + "warning") + (redirect "/login"))))))) + +(defroute ("/storage/view/media/:slug" :method :GET) (&key slug) + (if (nera:get-storage-file :slug slug) + `(200 (:content-type + ,(files::file-type-of + (nera:get-storage-file :slug slug))) + ,(storage:open-binary-file + "" "media" (files::name-of + (nera:get-storage-file :slug slug)))) + (on-exception *web* 404))) + +(defroute ("/storage/thumb/media/:slug" :method :GET) (&key slug) + (let ((storage-file (nera:get-storage-file :slug slug))) + (if storage-file + `(200 (:content-type ,(files::file-type-of storage-file)) + ,(storage:open-binary-file + "" "media" + (format nil "thumbnail-~a" (files::name-of storage-file)))) + (on-exception *web* 404)))) + +(defroute ("/storage/thumb/archive/:slug" :method :GET) (&key slug) + (if (nera:get-archive-entry :slug slug) + (let ((archive-entry (nera:get-archive-entry :slug slug))) + `(200 (:content-type ,(archive::thumbnail-file-type-of archive-entry)) + ,(storage:open-binary-file + "" "archive" (archive::thumbnail-slug-of archive-entry)))) + (on-exception *web* 404))) + +(defroute ("/storage/manage" :method :GET) () + (hermetic:auth (:logged-in) + ;; Authorised + (let ((alert (utils:get-and-reset-alert))) + (render #P"/user/storage.html" + (append (auth:auth-user-data) + `(:alert ,alert + :files ,(nera:get-all-storage-files) + :system-data ,(nera:system-data))))) + ;; Not Authorised + (progn (utils:set-alert "You are not logged in." "error") + (redirect "/login")))) + +(defroute ("/storage/multi-upload" :method :POST) () + (destructuring-bind + (&key authenticity-token &allow-other-keys) + (utils:request-params + (lack.request:request-body-parameters ningle:*request*)) + (if (not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied")) + (let ((files (utils:separate-files-in-web-request + (lack.request:request-body-parameters ningle:*request*) + "STORAGE-FILES"))) + (hermetic:auth + (:logged-in) + ;; Authorised + (cond ((validation:string-is-nil-or-empty? (caddr (car files))) + (utils:set-alert "No files provided." "missing-data") + (redirect "/storage/manage")) + + (t (loop + :for item :in files + :do (storage:store-file + "" "media" (utils:format-filename (caddr item)) (cdr item)) + + (nera:add-storage-file (utils:format-filename (caddr item)) + (utils:slugify (caddr item)) + (cadddr item)) + ;; Thumbnail not stored in the database. It + ;; is a hard-coded utility feature of the + ;; website. The thumbnail is created so + ;; large-scale images are not used at the + ;; thumbnail, decreasing download sizes. + (when (str:contains? "image" (cadddr item) :ignore-case t) + (utils:create-thumbnail + "media" (utils:format-filename (caddr item)) nil))) + (utils:set-alert "File upload complete." "success") + (redirect "/storage/manage"))) + ;; Not Authorised + (progn + (utils:set-alert "You are not authorised to view this page." + "error") + (redirect "/login"))))))) + +(defroute ("/storage/rename/:slug" :method :POST) (&key slug) + (destructuring-bind + (&key new-file-name authenticity-token &allow-other-keys) + (utils:request-params + (lack.request:request-body-parameters ningle:*request*)) + (if (not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied")) + (hermetic:auth + (:logged-in) + ;; Authorised + (cond ((validation:string-is-nil-or-empty? new-file-name) + (utils:set-alert "No file name provided. Nothing updated." + "missing-data") + (redirect "/storage/manage")) + + ((not (null (nera:get-storage-file :filename new-file-name))) + (utils:set-alert "File with that name already exists. File not saved." + "invalid-data") + (redirect "/storage/manage")) + + (t (storage:rename-content-file + "" "media" (files::name-of (nera:get-storage-file :slug slug)) + new-file-name) + (when (storage:file-exists-p + "" "media" + (format nil "thumbnail-~a" + (files::name-of (nera:get-storage-file :slug slug)))) + (storage:rename-content-file + "" "media" (format nil "thumbnail-~a" + (files::name-of + (nera:get-storage-file :slug slug))) + (format nil "thumbnail-~a" new-file-name))) + (nera:rename-storage-file + (files::name-of (nera:get-storage-file :slug slug)) + new-file-name) + (utils:set-alert "File renamed." "success") + (redirect "/storage/manage"))) + ;; Not Authorised + (progn + (utils:set-alert "You are not authorised to view this page." "error") + (redirect "/login")))))) + +(defroute ("/storage/delete/:slug" :method :POST) (&key slug) + (destructuring-bind + (&key authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:administrator) + ;; Authorised + (cond ((null (nera:get-storage-file :slug slug)) + (utils:set-alert "Unable to find file. Nothing deleted." + "missing-data") + (redirect "/storage/manage")) + + (t (storage:remove-file + "" "media" + (files::name-of (nera:get-storage-file :slug slug))) + (when (storage:file-exists-p + "" "media" + (format nil "thumbnail-~a" + (files::name-of + (nera:get-storage-file :slug slug)))) + (storage:remove-file + "" "media" + (format nil "thumbnail-~a" (files::name-of + (nera:get-storage-file + :slug slug))))) + (nera:delete-storage-file :slug slug) + (utils:set-alert "File deleted." "success") + (redirect "/storage/manage"))) + ;; Not Authorised + (progn (utils:set-alert "You are not authorised to delete page." + "error") + (redirect "/login"))))))) + +(defroute ("/archive" :method :GET) () + (let ((alert (utils:get-and-reset-alert))) + (render #P"archive.html" + (append (if (hermetic:logged-in-p) + (auth:auth-user-data)) + `(:alert ,alert + :system-data ,(nera:system-data) + :archive-entries ,(nera:get-all-archive-entries)))))) + +(defroute ("/view/archive/:slug" :method :GET) (&key slug) + (let ((alert (utils:get-and-reset-alert))) + (if (storage:file-exists-p "" "archive" slug) + (let* ((archive-entry (nera:get-archive-entry :slug slug)) + (archive-id (archive::object-id archive-entry))) + (render #P"archive-entry.html" + (append (if (hermetic:logged-in-p) + (auth:auth-user-data)) + `(:alert ,alert + :db-data ,archive-entry + :system-data ,(nera:system-data) + :newer-entries + ,(nera:get-newer-archive-entries archive-id 2) + :older-entries + ,(nera:get-older-archive-entries archive-id 2) + :data ,(storage:open-text-file "" "archive" slug))))) + (on-exception *web* 404)))) + +(defroute ("/user/archive" :method :GET) () + (hermetic:auth (:logged-in) + ;; Authorised + (let ((alert (utils:get-and-reset-alert))) + (render "/user/archive.html" + (append (auth:auth-user-data) + `(:alert ,alert + :system-data ,(nera:system-data) + :archive-entries ,(nera:get-all-archive-entries))))) + ;; Not Authorised + (progn + (utils:set-alert "You are not logged in." "error") + (redirect "/login")))) + +(defroute ("/create/archive-entry" :method :GET) () + (hermetic:auth (:logged-in) + ;; Authorised + (let ((alert (utils:get-and-reset-alert))) + (render "/user/create-archive.html" + (append (auth:auth-user-data) + `(:alert ,alert + :system-data ,(nera:system-data))))) + ;; Not Authorised + (progn + (utils:set-alert "You are not logged in." "error") + (redirect "/login")))) + +(defroute ("/create/archive-entry" :method :POST) () + (destructuring-bind + (&key title month year keywords thumbnail-file page-content + authenticity-token &allow-other-keys) + (utils:request-params + (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:logged-in) + ;; Authorised + (cond ((find t (mapcar #'validation:string-is-nil-or-empty? `(,title ,month ,year))) + (render + "/user/create-archive.html" + (append (auth:auth-user-data) + `(:alert + ,(utils:build-alert-string + "missing-data" + "sherlock-cat.png" + "Data is missing. Unable to create entry.") + :title ,title + :month ,month + :year ,year + :keywords ,keywords + :data ,page-content)))) + + ((not (null (nera:get-archive-entry :title title))) + (render + "/user/create-archive.html" + (append (auth:auth-user-data) + `(:alert + ,(utils:build-alert-string + "invalid-data" + "confused-cat.png" + "Entry with that title already exists. Unable to create entry.") + :title ,title + :month ,month + :year ,year + :keywords ,keywords + :data ,page-content)))) + + ((not (str:contains? + "image" (caddr thumbnail-file) :ignore-case t)) + (render + "/user/create-archive.html" + (append (auth:auth-user-data) + `(:alert + ,(utils:build-alert-string + "invalid-data" + "confused-cat.png" + "File uploaded is not an image. Entry not created.") + :title ,title + :month ,month + :year ,year + :keywords ,keywords + :data ,page-content)))) + + (t (let ((search-id (utils:create-timestamp-id))) + ;; Database Entry + (nera:create-archive-entry + title + search-id + (format nil "~a.html" (utils:slugify title)) + month + year + (utils:format-filename (cadr thumbnail-file)) ; File Name + (caddr thumbnail-file) ; File Type + (utils:format-keywords keywords)) + ;; Use placeholder thumbnail if one not detected? + ;; Meilisearch Database Entry + (search:submit-entry + (search:build-payload + search-id title + (format nil "view/archive/~a.html" + (utils:slugify title)) + (format nil "storage/thumb/archive/~a.html" + (utils:slugify title)) + month + year + (utils:format-keywords keywords))) + ;; Storage File Entry + (storage:store-text + "" "archive" + (format nil "~a.html" (utils:slugify title)) + page-content) + (storage:store-file + "" "archive" + (utils:format-filename (cadr thumbnail-file)) + thumbnail-file) + (utils:create-thumbnail ; Overwrites the original here. + "archive" (utils:format-filename (cadr thumbnail-file)) t) + (utils:set-alert "Archive entry created. Great Success!" + "created") + (redirect "/dashboard")))) + ;; Not Authorised + (progn (utils:set-alert "You are not logged in." "error") + (redirect "/login"))))))) + +(defroute ("/edit/archive/:slug" :method :GET) (&key slug) + (if (nera:get-archive-entry :slug slug) + (progn + (hermetic:auth + (:logged-in) + ;; Authorised + (let ((alert (utils:get-and-reset-alert))) + (render "/user/edit-archive.html" + (append (auth:auth-user-data) + `(:alert ,alert + :system-data ,(nera:system-data) + :db-data ,(nera:get-archive-entry :slug slug) + :data ,(storage:open-text-file "" "archive" slug))))) + ;; Not Authorised + (progn + (utils:set-alert "You are not logged in." "error") + (redirect "/login")))) + (on-exception *web* 404))) + +(defroute ("/edit/archive-thumbnail" :method :POST) () + (destructuring-bind + (&key archive-slug thumbnail-file authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:administrator) + ;; Authorised + (cond ((validation:string-is-nil-or-empty? archive-slug) + (utils:set-alert + "No archive slug provided. Thumbnail not updated." + "missing-data") + (redirect "/user/archive")) + ((null (nera:get-archive-entry :slug archive-slug)) + (utils:set-alert + "Cannot file thumbnail's archive entry. Nothing updated." + "missing-data") + (redirect "/user/archive")) + ((not (str:contains? "image" (caddr thumbnail-file) :ignore-case t)) + (utils:set-alert + "File uploaded is not an image. Thumbnail not updated." + "invalid-data") + (redirect (format nil "/edit/archive/~a" archive-slug))) + (t (let ((archive-entry (nera:get-archive-entry :slug archive-slug))) + (storage:remove-file + "" "archive" (archive::thumbnail-slug-of archive-entry)) + (storage:store-file + "" "archive" (cadr thumbnail-file) thumbnail-file) + (nera:update-archive-entry-property + :slug archive-slug + :property 'archive::thumbnail-file-type-of + :value (caddr thumbnail-file)) + (nera:update-archive-entry-property + :slug archive-slug + :property 'archive::thumbnail-slug-of + :value (cadr thumbnail-file)) + (utils:create-thumbnail + "archive" (archive::thumbnail-slug-of archive-entry) t) + ;; Meilisearch DB doesn't need updating because nothing + ;; has changed from its perspective. + (utils:set-alert "Thumbnail updated." "success") + (redirect (format nil "/edit/archive/~a" archive-slug))))) + ;; Not Authorised + (progn (utils:set-alert + "You are not authorised to delete this archive entry." + "error") + (redirect "/login"))))))) + +(defroute ("/rename/archive-entry" :method :POST) () + (destructuring-bind + (&key id archive-slug new-title authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:administrator) + ;; Authorised + (cond ((find t (mapcar #'validation:string-is-nil-or-empty? + `(,id ,archive-slug ,new-title))) + (utils:set-alert + "Title and meta-data not provided. Archive entry not renamed." + "missing-data") + (redirect "/user/archive")) + ((null (nera:get-archive-entry :slug archive-slug)) + (utils:set-alert + "Cannot file archive entry. Archive entry not updated." + "invalid-data") + (redirect "/user/archive")) + (t (let ((archive-entry + (nera:get-archive-entry :id (parse-integer id)))) + (storage:rename-content-file + "" "archive" (archive::slug-of archive-entry) + (utils:format-filename (format nil "~a.html" new-title))) + (nera:update-archive-entry-property + :slug archive-slug + :property 'archive::title-of + :value new-title) + (nera:update-archive-entry-property + :slug archive-slug + :property 'archive::slug-of + :value (utils:format-filename (format nil "~a.html" new-title))) + (search:submit-entry + (search:build-payload + (archive::search-id-of archive-entry) + new-title + (format nil "view/archive/~a.html" + (utils:slugify new-title)) + (format nil + "storage/thumb/archive/~a.html" + (utils:slugify new-title)) + (archive::month-of archive-entry) + (archive::year-of archive-entry) + (archive::keywords-of archive-entry))) + (utils:set-alert "Archive entry updated." "success") + (redirect + (format nil + "/edit/archive/~a" + (utils:format-filename + (format nil "~a.html" new-title))))))) + ;; Not Authorised + (progn (utils:set-alert + "You are not authorised to delete this archive entry." + "error") + (redirect "/login"))))))) + +(defroute ("/edit/archive-publish-date" :method :POST) () + (destructuring-bind + (&key archive-slug authenticity-token month year &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:administrator) + ;; Authorised + (cond ((find t (mapcar #'validation:string-is-nil-or-empty? + `(,archive-slug ,month ,year))) + (utils:set-alert "Full date not provided. Not updated." + "missing-data") + (redirect "/user/archive")) + ((null (nera:get-archive-entry :slug archive-slug)) + (utils:set-alert + "Cannot file archive entry. Keywords not updated." + "invalid-data") + (redirect "/user/archive")) + (t (let ((archive-entry + (nera:get-archive-entry :slug archive-slug))) + (nera:update-archive-entry-property + :slug archive-slug + :property 'archive::month-of + :value month) + (nera:update-archive-entry-property + :slug archive-slug + :property 'archive::year-of + :value year) + (search:submit-entry + (search:build-payload + (archive::search-id-of archive-entry) + (archive::title-of archive-entry) + (format nil "view/archive/~a" + (archive::slug-of archive-entry)) + (format nil "storage/thumb/archive/~a" + (archive::slug-of archive-entry)) + month + year + (archive::keywords-of archive-entry))) + (utils:set-alert "Archive entry updated." "success") + (redirect (format nil "/edit/archive/~a" archive-slug))))) + ;; Not Authorised + (progn (utils:set-alert + "You are not authorised to delete this archive entry." + "error") + (redirect "/login"))))))) + +(defroute ("/edit/archive-keywords" :method :POST) () + (destructuring-bind + (&key archive-slug new-keywords authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:administrator) + ;; Authorised + (cond ((find t (mapcar #'validation:string-is-nil-or-empty? + `(,archive-slug ,new-keywords))) + (utils:set-alert "Keywords not provided. Not updated." + "missing-data") + (redirect "/user/archive")) + ((null (nera:get-archive-entry :slug archive-slug)) + (utils:set-alert + "Cannot file archive entry. Keywords not updated." + "invalid-data") + (redirect "/user/archive")) + (t (let ((archive-entry (nera:get-archive-entry :slug archive-slug)) + (keywords (utils:format-keywords new-keywords))) + (nera:update-archive-entry-property + :slug archive-slug + :property 'archive::keywords-of + :value keywords) + (search:submit-entry + (search:build-payload + (archive::search-id-of archive-entry) + (archive::title-of archive-entry) + (format nil "view/archive/~a" + (archive::slug-of archive-entry)) + (format nil "storage/thumb/archive/~a" + (archive::slug-of archive-entry)) + (archive::month-of archive-entry) + (archive::year-of archive-entry) + keywords)) + (utils:set-alert "Archive entry updated." "success") + (redirect (format nil "/edit/archive/~a" archive-slug))))) + ;; Not Authorised + (progn (utils:set-alert + "You are not authorised to delete this archive entry." + "error") + (redirect "/login"))))))) + +(defroute ("/edit/archive" :method :POST) () + (destructuring-bind + (&key slug page-content authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:logged-in) + ;; Authorised + (cond ((validation:string-is-nil-or-empty? slug) + (utils:set-alert + "Archive entry cannot be found." "missing-data") + (redirect "/user/archive")) + (t (storage:store-text "" "archive" slug page-content) + ;; Meilisearch integration not needed here because + ;; nothing has changed from the Meilisearch DB + ;; perspective. + (utils:set-alert "Archive entry updated." "success") + (redirect (format nil "/edit/archive/~a" slug)))) + ;; Not Authorised + (progn (utils:set-alert "You are not logged in." "error") + (redirect "/login"))))))) + +(defroute ("/archive/delete/entry" :method :POST) () + (destructuring-bind + (&key slug authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:administrator) + ;; Authorised + (cond ((validation:string-is-nil-or-empty? slug) + (utils:set-alert + "Cannot find archive entry in database. Nothing deleted." + "missing-data") + (redirect "/user/archive")) + ((and (null (storage:file-exists-p "" "archive" slug)) + (null (nera:get-archive-entry :slug slug))) + (utils:set-alert + "Unable to find archive entry. Nothing deleted." + "invalid-data") + (redirect "/user/archive")) + ((and (null (storage:file-exists-p "" "archive" slug)) + (not (null (nera:get-archive-entry :slug slug)))) + (nera:delete-archive-entry :slug slug) + (utils:set-alert + "Couldn't find archive entry files. Deleted from database only." + "invalid-data") + (redirect "/user/archive")) + ((and (not (null (storage:file-exists-p "" "archive" slug))) + (null (nera:get-archive-entry :slug slug))) + (utils:set-alert + "Couldn't find archive entry in database. Deleted files only." + "invalid-data") + ;; The system doesn't know about the thumbnail at this + ;; point because it was linked to the text file via the + ;; database. You will need to delete the thumbnail manually + ;; at this point but the system has already failed here + ;; anyway so the extra work was already needed. + (storage:remove-file "" "archive" slug) + (redirect "/user/archive")) + (t (storage:remove-file "" "archive" slug) + (storage:remove-file + "" "archive" (archive::thumbnail-slug-of + (nera:get-archive-entry :slug slug))) + (search:delete-entry + (archive::search-id-of (nera:get-archive-entry :slug slug))) + (nera:delete-archive-entry :slug slug) + (utils:set-alert "Archive entry deleted." "success") + (redirect "/user/archive"))) + ;; Not Authorised + (progn (utils:set-alert + "You are not authorised to delete this archive entry." + "error") + (redirect "/login"))))))) + +(defroute ("/search" :method :GET) () + (render #P"search.html" (append (if (hermetic:logged-in-p) + (auth:auth-user-data)) + `(:alert ,(utils:get-and-reset-alert) + :nav-menu ,(nera:nav-menu-slugs) + :system-data ,(nera:system-data))))) + +(defroute ("/sitemap" :method :GET) () + (redirect "/sitemap.xml")) + +(defroute ("/sitemap.xml" :method :GET) () + (setf (getf (response-headers *response*) :content-type) "application/xml") + (with-output-to-string (stream) + (let ((pages (nera:get-all-pages)) + (entries (nera:get-all-archive-entries)) + (root-url (utils:build-url-root ningle:*request*))) + (xml-emitter:with-xml-output (stream :encoding "utf-8") + (xml-emitter:with-simple-tag + ("urlset" + nil + "http://www.sitemaps.org/schemas/sitemap/0.9") + ;; Lists all the pages first. + ;; The 'unless' block is to remove pages which are not wanting to be + ;; part of a search engine's crawler results. + (loop for item in pages + do + (unless (or (string= "sign-up" (pages::slug-of item)) + (string= "login" (pages::slug-of item))) + (xml-emitter:with-tag ("url") + (xml-emitter:emit-simple-tags + :loc (format nil "~a/view/page/~a" + root-url (pages::slug-of item)) + :lastmod + (format nil "~a" (mito.dao.mixin:object-updated-at item)))))) + ;; Lists all the archive entries second. + (loop for item in entries + do + (xml-emitter:with-tag ("url") + (xml-emitter:emit-simple-tags + :loc (format nil "~a/view/archive/~a" + root-url (archive::slug-of item)) + :lastmod + (format nil "~a" + (mito.dao.mixin:object-updated-at item)))))))))) + +(defroute ("/danger/manage-files" :method :GET) () + (hermetic:auth + (:administrator) + ;; Authorised + (let ((alert (utils:get-and-reset-alert))) + (render "/danger/manage-files.html" + (append (auth:auth-user-data) + `(:alert ,alert + :system-data ,(nera:system-data) + :archive-files + ,(storage:get-file-names + (storage:get-files-in-directory "" "archive")) + :media-files + ,(storage:get-file-names + (storage:get-files-in-directory "" "media")) + :pages-files + ,(storage:get-file-names + (storage:get-files-in-directory "" "pages")))))) + ;; Not Authorised + (progn + (utils:set-alert "You are not authorised to view this page." "error") + (redirect "/login")))) + +(defroute ("/danger/delete-file" :method :POST) () + (destructuring-bind + (&key filename directory authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:administrator) + ;; Authorised + (cond ((find t (mapcar #'validation:string-is-nil-or-empty? + `(,filename ,directory))) + (utils:set-alert + "File name or directory not provided." "missing-data") + (redirect "/danger/manage-files")) + ((not (storage:file-exists-p "" directory filename)) + (utils:set-alert "File cannot be found." "invalid-data") + (redirect "/danger/manage-files")) + (t (storage:file-exists-p "" directory filename) + (storage:remove-file "" directory filename) + (utils:set-alert "File deleted." "success") + (redirect "/danger/manage-files"))) + ;; Not Authorised + (progn (utils:set-alert + "You are not authorised to delete page." "error") + (redirect "/login"))))))) + +(defroute ("/danger/manage-database-entries" :method :GET) () + (hermetic:auth + (:administrator) + ;; Authorised + (let ((alert (utils:get-and-reset-alert))) + (render "/danger/manage-db-entries.html" + (append (auth:auth-user-data) + `(:alert ,alert + :system-data ,(nera:system-data) + :archive-entries ,(nera:get-all-archive-entries) + :storage-entries ,(nera:get-all-storage-files) + :pages-entries ,(nera:get-all-pages))))) + ;; Not Authorised + (progn + (utils:set-alert "You are not authorised to view this page." "error") + (redirect "/login")))) + +(defroute ("/danger/delete-database-entry" :method :POST) () + (destructuring-bind + (&key name table authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:administrator) + ;; Authorised + (cond ((find t (mapcar #'validation:string-is-nil-or-empty? `(,name ,table))) + (utils:set-alert + "Entry name or database table not provided." "missing-data") + (redirect "/danger/manage-database-entries")) + ((string= "page" table) + (if (not (nera:get-page name)) + (utils:set-alert + "Database entry cannot be found." "invalid-data") + (progn + (nera:delete-page :slug name) + (utils:set-alert "Database entry deleted." "success"))) + (redirect "/danger/manage-database-entries")) + ((string= "archive" table) + (if (not (nera:get-archive-entry :slug name)) + (utils:set-alert + "Database entry cannot be found." "invalid-data") + (progn + (nera:delete-archive-entry :slug name) + (utils:set-alert + "Database entry deleted." "success"))) + (redirect "/danger/manage-database-entries")) + ((string= "storage-file" table) + (if (not (nera:get-storage-file :slug name)) + (utils:set-alert + "Database entry cannot be found." "invalid-data") + (progn + (nera:delete-storage-file :slug name) + (utils:set-alert + "Database entry deleted." "success"))) + (redirect "/danger/manage-database-entries")) + (t (utils:set-alert "Database table not found." "invalid-data") + (redirect "/danger/manage-database-entries"))) + ;; Not Authorised + (progn (utils:set-alert + "You are not authorised to delete page." "error") + (redirect "/login"))))))) + +(defroute ("/danger/repopulate-search-db" :method :POST) () + (destructuring-bind + (&key authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:administrator) + ;; Authorised + (progn + (search:repopulate-database (nera:get-all-archive-entries)) + (utils:set-alert + "Search database re-populated. Great Success!" "success") + (redirect "/site-settings")) + ;; Not Authorised + (progn (utils:set-alert + "You are not authorised to use this feature." + "error") + (redirect "/login"))))))) + +(defroute ("/danger/reset-website" :method :POST) () + (destructuring-bind + (&key authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:administrator) + ;; Authorised + (progn + ;; The 'when' checks are just a precaution. These directories + ;; were created during the site's first-run/initial set-up. If + ;; they are missing, though, whilst this function is executing, + ;; an error is thrown -- hence the check. + (when (storage:directory-exists-p "" "media") + (storage:remove-directory "" "media")) + (when (storage:directory-exists-p "" "archive") + (storage:remove-directory "" "archive")) + (when (storage:directory-exists-p "" "pages") + (storage:remove-directory "" "pages")) + (when (storage:directory-exists-p "" "snippets") + (storage:remove-directory "" "snippets")) + ;; If the database doesn't exist, the site is in a much worse + ;; state than anticipated and needs someone to SSH into the host + ;; and look at it -- hence no 'when' check. + (storage:remove-file-with-raw-path + (ritherdon-archive.config:database-name)) + ;; If Meilisearch service is down, you need to SSH into + ;; host. That is a separate service which this website utilises + ;; but doesn't control. + (search:delete-all-entries) + (redirect "/")) + ;; Not Authorised + (progn (utils:set-alert + "You are not authorised to use this feature." + "error") + (redirect "/login"))))))) + +(defroute ("/danger/manage-snapshots" :method :GET) () + (hermetic:auth + (:logged-in) + ;; Authorised + (let ((alert (utils:get-and-reset-alert))) + (render "/danger/snapshots.html" + (append (auth:auth-user-data) + `(:alert ,alert + :system-data ,(nera:system-data) + :snapshots + ,(reverse + (storage::get-directory-names + (storage::get-raw-directories "snapshots/"))))))) + ;; Not Authorised + (progn + (utils:set-alert "You are not authorised to view this page." "error") + (redirect "/login")))) + +(defroute ("/danger/take-snapshot" :method :POST) () + (destructuring-bind + (&key authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:administrator) + ;; Authorised + (progn + (snapshot:take-snapshot) + (utils:set-alert "Snapshot taken." "success") + (redirect "/danger/manage-snapshots")) + ;; Not Authorised + (progn (utils:set-alert + "You are not authorised to delete page." "error") + (redirect "/login"))))))) + +(defroute ("/danger/delete-snapshot" :method :POST) () + (destructuring-bind + (&key snapshot-name authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:administrator) + ;; Authorised + (cond ((validation::string-is-nil-or-empty? snapshot-name) + (utils:set-alert "No Snapshot Name provided." "missing-data") + (redirect "/danger/manage-snapshots")) + ((not (storage:raw-directory-exists? + (format nil "snapshots/~a/" snapshot-name))) + (utils:set-alert "Cannot find selected Snapshot." "invalid-data") + (redirect "/danger/manage-snapshots")) + (t (snapshot:delete-snapshot snapshot-name) + (utils:set-alert "Snapshot deleted." "success") + (redirect "/danger/manage-snapshots"))) + ;; Not Authorised + (progn (utils:set-alert + "You are not authorised to delete page." "error") + (redirect "/login"))))))) + + +(defroute ("/danger/create-snapshot-download" :method :POST) () + (destructuring-bind + (&key snapshot-name authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:administrator) + ;; Authorised + (cond ((validation::string-is-nil-or-empty? snapshot-name) + (utils:set-alert "No Snapshot Name provided." "missing-data") + (redirect "/danger/manage-snapshots")) + ((not (storage:raw-directory-exists? + (format nil "snapshots/~a/" snapshot-name))) + (utils:set-alert "Cannot find selected Snapshot." "invalid-data") + (redirect "/danger/manage-snapshots")) + ((storage:file-exists-p + "" "media" (format nil "~a.zip" snapshot-name)) + (utils:set-alert + "Snapshot already prepared and moved to Storage Files" + "invalid-data") + (redirect "/danger/manage-snapshots")) + (t (zip:zip + (storage:make-path + "" "media" (format nil "~a.zip"snapshot-name)) + (storage:make-raw-path + (format nil "snapshots/~a/" snapshot-name))) + (nera:add-storage-file + (format nil "~a.zip"snapshot-name) + (format nil "~a-zip"snapshot-name) + "application/zip") + (utils:set-alert "Snapshot ready for download." "success") + (redirect "/danger/manage-snapshots"))) + ;; Not Authorised + (progn (utils:set-alert + "You are not authorised to delete page." "error") + (redirect "/login"))))))) + +(defroute ("/danger/restore-snapshot" :method :POST) () + (destructuring-bind + (&key snapshot-name authenticity-token &allow-other-keys) + (utils:request-params (lack.request:request-body-parameters ningle:*request*)) + (cond ((not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied"))) + (t (hermetic:auth + (:administrator) + ;; Authorised + (cond ((validation::string-is-nil-or-empty? snapshot-name) + (utils:set-alert "No Snapshot Name provided." + "missing-data") + (redirect "/danger/manage-snapshots")) + ((not (storage:raw-directory-exists? + (format nil "snapshots/~a/" snapshot-name))) + (utils:set-alert "Cannot find selected Snapshot." + "invalid-data") + (redirect "/danger/manage-snapshots")) + (t (snapshot:restore-from-snapshot snapshot-name) + (if (str:contains? + "://localhost:" (utils:build-url-root ningle:*request*)) + (utils:set-alert + "Snapshot restored. Restart local server for changes to take effect." + "success") + (progn + (utils:set-alert + "Snapshot restored restarting server. FEATURE NOT IMPLEMENTED YET..." + "success") + ;; TODO: WRITE SCRIPT TO RESTART SYSTEMD SERVICE. + ;; utils:run-bash-command "Restart Systemd Service" + (format + t "[INFO] Restarting Systemd service is not yet implemented."))) + (redirect "/danger/manage-snapshots"))) + ;; Not Authorised + (progn (utils:set-alert + "You are not authorised to delete page." "error") + (redirect "/login"))))))) + +(defroute ("/danger/upload-snapshot" :method :POST) () + (destructuring-bind + (&key authenticity-token &allow-other-keys) + (utils:request-params + (lack.request:request-body-parameters ningle:*request*)) + (if (not (string= authenticity-token (auth:csrf-token))) + `(,+forbidden+ (:content-type "text/plain") ("Denied")) + (let ((files (utils:separate-files-in-web-request + (lack.request:request-body-parameters ningle:*request*) + "SNAPSHOT-FILES"))) + (hermetic:auth + (:administrator) + ;; Authorised + (cond ((validation:string-is-nil-or-empty? (caddr (car files))) + (utils:set-alert "No Snapshots provided." "missing-data") + (redirect "/danger/manage-snapshots")) + (t (loop + :for item :in files + :do (when (and (not (storage:raw-directory-exists? + (storage:make-raw-path + (format + nil "snapshots/~a/" + (pathname-name (caddr item)))))) + (string= "zip" (pathname-type (caddr item)))) + (snapshot:store-snapshot + (utils:format-filename (caddr item)) (cdr item)))) + (utils:set-alert "Snapshot upload complete." "success") + (redirect "/danger/manage-snapshots"))) + ;; Not Authorised + (progn + (utils:set-alert "You are not authorised to view this page." + "error") + (redirect "/login"))))))) ;; ;; Error pages diff --git a/static/css/archivo/Archivo-Bold.otf b/static/css/archivo/Archivo-Bold.otf new file mode 100644 index 0000000..71016bb Binary files /dev/null and b/static/css/archivo/Archivo-Bold.otf differ diff --git a/static/css/archivo/Archivo-BoldItalic.otf b/static/css/archivo/Archivo-BoldItalic.otf new file mode 100644 index 0000000..b143c47 Binary files /dev/null and b/static/css/archivo/Archivo-BoldItalic.otf differ diff --git a/static/css/archivo/Archivo-Italic.otf b/static/css/archivo/Archivo-Italic.otf new file mode 100644 index 0000000..8b57839 Binary files /dev/null and b/static/css/archivo/Archivo-Italic.otf differ diff --git a/static/css/archivo/Archivo-Medium.otf b/static/css/archivo/Archivo-Medium.otf new file mode 100644 index 0000000..698a1ad Binary files /dev/null and b/static/css/archivo/Archivo-Medium.otf differ diff --git a/static/css/archivo/Archivo-MediumItalic.otf b/static/css/archivo/Archivo-MediumItalic.otf new file mode 100644 index 0000000..026771b Binary files /dev/null and b/static/css/archivo/Archivo-MediumItalic.otf differ diff --git a/static/css/archivo/Archivo-Regular.otf b/static/css/archivo/Archivo-Regular.otf new file mode 100644 index 0000000..4a57550 Binary files /dev/null and b/static/css/archivo/Archivo-Regular.otf differ diff --git a/static/css/archivo/Archivo-SemiBold.otf b/static/css/archivo/Archivo-SemiBold.otf new file mode 100644 index 0000000..50d8f6b Binary files /dev/null and b/static/css/archivo/Archivo-SemiBold.otf differ diff --git a/static/css/archivo/Archivo-SemiBoldItalic.otf b/static/css/archivo/Archivo-SemiBoldItalic.otf new file mode 100644 index 0000000..f8f00af Binary files /dev/null and b/static/css/archivo/Archivo-SemiBoldItalic.otf differ diff --git a/static/css/full-search.css b/static/css/full-search.css new file mode 100644 index 0000000..46db302 --- /dev/null +++ b/static/css/full-search.css @@ -0,0 +1,294 @@ +.search-dashboard { + margin: 0px; + padding: 0px; + display: flex; + flex-direction: column; +} + +.refinements-panel h2, +.refinements-panel p { + padding: 0px; + margin: 12px 0px; +} + +#clear-refinements { + margin-bottom: 20px; +} + +.ais-ClearRefinements-button { + font-size: 16px; + height: 40px; + width: 100%; + margin: 0px; + font-family: 'main', sans-serif; + color: black; + background-color: white; + cursor: pointer; + border: none; + text-align: left; +} + +.ais-ClearRefinements-button:hover { + text-decoration: underline; +} + +.ais-ClearRefinements-button--disabled { + color: slategrey; +} + +.ais-ClearRefinements-button--disabled:hover { + color: slategrey; + text-decoration: none; + cursor: initial; +} + +.search-refinement-list { + /* margin: 20px 0px; */ + /* border-bottom: 2px solid black; */ +} + +#searchbox { + width: 100%; + margin-top: 20px; + margin-bottom: 20px; + margin-left: auto; + margin-right: auto; +} + +.ais-SearchBox, +.ais-ClearRefinements-button { + max-width: 600px; +} + +.search-results-container { + display: flex; + flex-direction: column; +} + +.ais-SearchBox-form { + display: flex; + flex-wrap: nowrap; + justify-content: center; + align-items: center; +} + +.ais-SearchBox-input { + box-sizing: border-box; + width: 100%; + margin-bottom: 15px; + padding: 10px; + border-radius: 8px; + border: 1px solid black; +} + +.ais-SearchBox-input::placeholder { + /* font-family: 'main', sans-serif; */ + /* font-size: 16px; */ +} + +.ais-SearchBox-form input:focus-visible { + /* outline: none; */ +} + +.ais-SearchBox-submitIcon, +.ais-SearchBox-submit, +.ais-SearchBox-reset { + display: none; +} + +.ais-RefinementList-list { + list-style: none; + padding: 0px; + margin: 0px 0px 40px 0px; + display: flex; + flex-direction: row; + width: 100%; + overflow: scroll; +} + +.ais-RefinementList-label { + display: flex; + align-items: center ; + width: max-content; + margin-right: 6px; +} + +.ais-RefinementList-label > span { + padding: 0px 2px; +} + +.ais-RefinementList-checkbox { + width: 30px; + height: 30px; + margin: 0px; +} + +.search-hits-panel { + width: -webkit-fill-available; +} + +#hits { + width: 100%; + min-width: 350px; + display: flex; + flex-direction: row; +} + +.ais-Hits-list { + padding: 0px; + margin: 0px; + display: flex; + flex-direction: column; + list-style: none; +} + +.ais-Hits-item { + margin: 8px; + max-height: 400px; + border-radius: 4px; + overflow: hidden; + display: flex; + flex-direction: column; +} + +.ais-Hits-item:hover { + /* border-color: lightblue; */ + /* box-shadow: none; */ +} + +.fe-search-hit { + max-width: 375px; +} + +.fe-search-hit-title { + font-weight: bold; +} + +.fe-search-hit-secondary { + display: block; +} + +.fe-search-hit-keywords { + display: block; + color: slategrey; + font-size: 11px; +} + +.fe-search-hit img { + width: 375px; + height: 200px; + object-fit: cover; + overflow: hidden; +} + +#pagination { + display: block; + margin: 40px 0px 40px 0px; + overflow: auto; + width: 100%; +} + +.ais-Pagination-list { + list-style: none; + padding: 0px; + margin: 0px 12px; + display: flex; + justify-content: center; + align-items: center; +} + +.ais-Pagination-item { + font-size: 22px; + margin: 6px; +} + +.ais-Pagination-item--disabled { + color: slategrey; +} + +/* @media (min-width:600px) { + .ais-ClearRefinements-button { + max-width: 200px; + } + } */ + +/* @media (min-width:961px) { */ +@media (min-width: 600px) { + .search-results-container { + flex-direction: row; + } + + .refinements-panel { + max-width: 200px; + width: 100%; + margin-right: 20px; + } + + .ais-RefinementList-list { + font-size: 12px; + flex-direction: column; + overflow: auto; + } + + .ais-RefinementList-item { + margin: 2px 0px; + } + + .ais-RefinementList-checkbox { + width: 20px; + margin-right: 4px; + } + + #hits { + flex-direction: row; + flex-wrap: wrap; + } + + .ais-Hits-list { + padding: 0px; + margin: 0px; + display: flex; + flex-direction: row; + flex-wrap: wrap; + list-style: none; + } + + .ais-Hits-item { + /* width: 200px; */ + /* height: 280px; */ + /* margin: 12px; */ + /* height: 100%; */ + /* display: flex; */ + /* flex-direction: column; */ + } + + .fe-search-hit { + max-width: 200px; + } + + .fe-search-hit-title { + font-weight: bold; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + } + + .fe-search-hit-secondary { + display: block; + } + + .fe-search-hit-keywords { + display: block; + color: slategrey; + font-size: 11px; + } + + .fe-search-hit img { + width: 200px; + height: 100px; + object-fit: cover; + overflow: hidden; + } + +} diff --git a/static/css/main.css b/static/css/main.css index 2e05864..ec9eb6b 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -1,21 +1,859 @@ @charset "UTF-8"; +@font-face { + font-family: "main"; + src: url("archivo/Archivo-Regular.otf") format("opentype"); +} + +/* smartphones, iPhone, portrait 480x320 phones */ +html, body { + /* height: 100%; */ +} + body { - font-family: 'Myriad Pro', Calibri, Helvetica, Arial, sans-serif; + font-family: 'main', Calibri, Helvetica, Arial, sans-serif; + margin: 0px; + padding: 0px; +} + +button { + font-family: 'main', Calibri, Helvetica, Arial, sans-serif; } a:link { - color: #005585; - text-decoration: none; + color: black; + text-decoration: none; } + a:visited { - color: #485270; + color: black; } + a:hover { - color: #b83800; - text-decoration: underline; + text-decoration: underline; +} + +input[type=file], +input[type=text], +input[type=password], +input[type=number] { + border: 1px solid black; + border-radius: 8px; + margin: 0px; + padding: 4px; + display: inline-block; +} + +.be-gui-form-row select { + width: 100%; + height: 38px; + border-radius: 8px; } #main { text-align: center; } + +.fr-main { + max-width: 880px; + margin: auto; + padding: 20px; +} + +.fr-main h2 { + padding: 0px; + margin: 20px 0px 0px 0px; +} + +.fr-main .be-gui-form-hint { + margin-bottom: 20px; +} + +.fr-main .fr-gui-form-hint { + margin-bottom: 0px; + font-style: italic; + font-size: 12px; + padding: 0px; + margin: 0px; +} + +.fr-main img { + max-width: 200px; + width: 100%; +} + +.be-alert-container { + display: flex; + align-items: center; + position: fixed; + top: 60px; + left: 8px; + right: 8px; +} + +.be-alert-container button { + position: fixed; + right: 15px; +} + +.be-alert-container p { + padding: 0px 60px 0px 0px; + margin: 0px; + border-radius: 8px; + display: flex; + flex-direction: row; + align-items: center; + width: 100%; +} + +.be-alert-container .success { + background: #adefad; +} + +.be-alert-container .error { + background: #ff607c; +} + +.be-alert-container .missing-data{ + background: #ffaf8e; +} + +.be-alert-container .invalid-data { + background: #efe1ad; +} + +.be-alert-container .created { + background: #b0f3ff; +} + +.be-alert-container .warning { + background: #ffe0c0; +} + +.be-alert-container p img { + max-height: 75px; + padding: 12px 8px; +} + +.be-login-container { + margin: 60px 0px; +} + +.be-user-accounts-container { + display: flex; + flex-direction: column; + justify-content: flex-start; + /* margin-bottom: 20px; */ +} + +.be-user-accounts-container p, +.be-user-accounts-container .be-gui-button-no-text { + display: inline; + padding: 4px; +} + +.be-user-accounts-container p, +.be-user-accounts-container label { + margin: 0px 4px; +} + +.be-user-accounts-container p { + font-weight: bold; +} + +.be-user-accounts-container input[type=password] { + height: 34px; + width: 100%; +} + +.be-section-thumbnail-row { + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + margin: 0px; + padding: 0px; + width: 100%; +} + +.wrap-break-spaces { + white-space: break-spaces !important; +} + +.be-gui-link:link, +.be-gui-button:link, +.be-gui-link-no-text, +.be-gui-button-no-text { + background: #905da1; + color: white; +} + +.be-gui-link-no-text { + width: 40px; + height: 40px; +} + +.be-gui-button-no-text { + width: 40px; + height: 40px; +} + +.be-gui-link-no-text img, +.be-gui-button-no-text img { + width: 32px; +} + +.be-gui-link-no-text, +.be-gui-button-no-text { + padding: 2px 4px; + border-radius: 8px; + border: none; + color: white; + display: flex; + align-items: center; + justify-content: center; + margin: 4px; +} + +.be-gui-link, +.be-gui-button { + padding: 0px; + width: 100%; + height: 36px; + padding: 8px 0px; + border: none; + max-width: 600px; + background: #905da1; + color: white; + display: flex; + justify-content: flex-start; + align-items: center; + border-radius: 6px; + max-width: initial; + text-decoration: none; +} + +.be-gui-button { + height: 42px; + font-size: 16px; +} + +.be-gui-link:hover , +.be-gui-button:hover, +.be-gui-link-no-text:hover, +.be-gui-button-no-text:hover { + background: #473951; + text-decoration: none; + /* color: white; */ +} + +.be-gui-link:visited, +.be-gui-button:visited { + /* background: #905da1; */ + color: white; +} + +.be-gui-link img, +.be-gui-button img { + width: 34px; + padding: 5px; + margin-right: 12px; +} + +.be-section-entry .be-gui-button-no-text { + padding: 22px; +} + +.be-gui-button p { + padding: 0px 0px 0px 8px; + margin: 0px; + display: inline; + font-size: 18px; + font-family: 'main'; +} + +.be-gui-form { + display: flex; + flex-direction: column; + margin: 12px 0px; +} + +.be-gui-form label, +.be-gui-form input { + display: block; + /* width: 100%; */ +} + +.be-gui-form label { + text-transform: uppercase; + font-weight: bold; + margin-bottom: 4px; +} + +hr { + margin: initial; +} + +.be-gui-form input { + margin-bottom: 12px; + height: 24px; +} + +.be-gui-form-inline { + display: inline; + align-items: center; +} + +.be-gui-form-inline-flex{ + display: flex; + align-items: center; +} + +.be-gui-form input[type=checkbox] { + display: inline; +} + +.be-gui-form input[type=file] { + padding: 12px; +} + +.be-gui-form textarea { + margin-bottom: 20px; +} + +.be-gui-form-hint { + font-style: italic; + font-size: 12px; + padding: 0px; + margin: 0px; +} + +.be-gui-form-row { + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + margin: 0px; + padding: 0px; +} + +.be-gui-form-row input, +.be-gui-form-row label { + margin: 0px 5px 0px 0px; + padding: 0px; +} + +.be-gui-form-row input[type=number] { + padding: 6px; +} + +.be-gui-form-row select { + margin: 0px 6px 0px 0px; +} + +.be-gui-form-thumbnail { + max-height: 80px; + margin: 12px; + box-shadow: 1px 1px 7px 1px silver; + +} + +.be-gui-form-row input[type=text] { + height: 30px; + padding: 4px; + width: 100%; +} + +.be-site-header { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + background: #2a0134; + height: 44px; + padding: 0px; + position: sticky; + top: 0; + z-index: 3; +} + +.be-site-header button { + width: auto; + height: 32px; + background: #473951; + border: none; + color: white; + display: flex; + flex-direction: row; + align-items: center; + font-size: 18px; + margin: 0px 4px; + padding: 6px 12px; + border-radius: 6px; +} + +.be-site-header button img { + width: 22px; + margin-right: 6px; +} + +.be-user-info { + display: flex; + align-items: center; + padding-right: 12px; +} + +.be-user-info p { + display: inline; + color: white; + padding-left: 6px; + font-weight: bold; +} + +.be-user-info span { + font-weight: normal; +} + +.be-site-side-menu { + display: none; + flex-direction: column; + justify-content: space-between; + background: #473951; + position: fixed; + width: 300px; + /* Based on the height of be-site-header. */ + top: 0px; + padding-top: 86px; + left: 0; + bottom: 0px; + /* Stops the text editor rendering over it. */ + z-index: 2; + overflow-y: auto; +} + +.be-site-side-menu h2 { + text-align: center; + color: white; + font-size: 16px; + border-bottom: 1px solid white; + padding-bottom: 6px; +} + +.be-site-side-menu div { + display: flex; + flex-direction: column; + padding: 0px; + margin: 12px; +} + +.be-site-side-menu .be-gui-link, +.be-site-side-menu .be-gui-button { + padding: 8px; + margin: 0px; + width: auto; + background: #473951; +} + +.be-site-side-menu .be-gui-button { + padding: 28px 8px; + width: 276px; + font-size: 16px; +} + +.be-site-side-menu .be-gui-link:hover, +.be-site-side-menu .be-gui-button:hover { + background: #905da1;; +} + +.be-main { + max-width: 880px; + width: 100%; + display: flex; + justify-content: center; + flex-direction: column; + margin: 20px auto; +} + +.be-dashboard-header { + display: flex; + flex-direction: column; + align-items: start; + justify-content: space-between; + padding: 0px; + margin: 0px; +} + +.be-dashboard-header .profile-cat { + height: 75px; +} + +.be-dashboard-header div { + display: flex; + flex-direction: row; + justify-content: flex-start; + margin: 0px; +} + +.be-dashboard-header .be-gui-link, +.be-dashboard-section .be-gui-link { + background: #905da1; +} + +.be-dashboard-header .be-gui-link:hover, +.be-dashboard-section .be-gui-link:hover{ + background: #473951; +} + +.be-dashboard-section { + display: flex; + flex-direction: column; + margin: 0px; + padding: 0px; +} + +.be-dashboard-section form input[type=file] { + border: 1px solid silver; + border-radius: 8px; + margin: 4px 4px 4px 0px; + padding: 12px; + display: inline-block; +} + +.be-dashboard-section h2 { + margin: 20px 0px 20px 0px; + padding: 0px; +} + +.be-section-controls { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + margin-bottom: 20px; +} + +.be-section-controls .be-gui-link { + margin-right: 6px; +} + +.be-section-controls .be-gui-link { + max-width: 175px; +} + +.be-section-entries { + display: flex; + flex-direction: column; +} + +.be-section-entry, +.be-section-image-title { + display: flex; + flex-direction: row; + justify-content: space-between; +} + +.be-section-image-title { + display: flex; + flex-direction: row; + justify-content: flex-start; + max-width: 716px; + width: 100%; + margin: 4px 0px; +} + +.be-section-image-title img { + max-height: 50px; + height: 100%; + margin-right: 6px; +} + +.be-section-entry form { + display: flex; + flex-direction: row; + justify-content: space-between; + margin: 0px; +} + +.be-section-entry img { + /* max-height: 80px; */ + /* width: 100%; */ +} + +.be-section-entry p { + max-width: 800px; + white-space: nowrap; + overflow-x: clip; + text-overflow: ellipsis; +} + +.be-section-image-title p { + white-space: initial; +} + +.be-section-entry:hover, +.be-index-item:hover, +.be-user-accounts-container:hover { + background: #fff6d2; +} + +.be-entry-controls { + display: flex; + flex-direction: row; +} + +.be-dashboard-section-list .be-gui-link { + margin: 6px 0px; +} + +.be-quicklist { + display: flex; + flex-direction: row; + flex-wrap: wrap; + align-items: center; +} + +.be-quicklist .be-gui-link { + max-width: 140px; + margin: 4px; +} + +.be-quicklist .be-gui-link img { + margin-right: 0px; +} + +.be-storage-section { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.be-storage-section-upload { + display: flex; + flex-direction: row; + align-items: center; + margin: 12px 0px; +} + +.be-storage-section-upload form { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + width: 100%; +} + +.be-storage-section-upload form [type=file] { + padding: 10px 12px; +} + +.be-storage-entry { + width: 100%; + display: flex; + flex-direction: row; + align-items: center; +} + +.file-thumbnail { + max-width: 50px; + max-height: 50px; + width: 100%; + padding: 0px 4px; +} + +.be-storage-rename { + display: flex; + flex-direction: row; + align-items: center; + width: 100%; +} + +.be-storage-rename input[type=text] { + width: 100%; + height: 30px; +} + +.be-warning { + color: red; +} + +.be-gui-link.danger { + background: #ffa700; + color: black; +} + +.be-gui-button.danger { + background: red; +} + +.be-gui-button.danger:hover, +.be-gui-link.danger:hover { + background: #473951; + text-decoration: none; + color: white; +} + +.be-popup-container { + position: relative; + display: inline-block; +} + +.be-popup { + background: palevioletred; + color: white; + padding: 8px; + border-radius: 8px; + visibility: hidden; + position: absolute; + left: 20px; + top: -20px; + z-index: 10; +} + +.fe-site-header { + display: flex; + flex-direction: column; + background: white; + align-items: center; + padding: 8px; + text-align: center; + text-decoration: none; +} + +.fe-site-header img { + max-height: 100px; + width: auto; + margin-right: 8px; +} + +#fe-main { + margin: 8px; +} + +#fe-main nav { + text-align: center; +} + +.fe-index { + max-width: 880px; + width: 100%; + margin: 0px auto; +} + +.fe-index-entry { + margin: 8px 0px; +} + +/* Start of Index Filter */ +#fe-search-filter { + box-sizing: border-box; + width: 100%; + margin-bottom: 15px; + padding: 10px; +} + + +#fe-search-filter-list { + list-style: none; + margin: 0; + padding: 0; +} + +#fe-search-filter-list li { + padding: 0px; +} + + +#fe-search-filter-list li.hide { + display: none; +} +/* End of Index Filter Stuff */ + +.fe-index-entry img { + max-height: 100px; +} + +.fe-hint { + margin: 0px; + padding: 0px; + font-size: 11px; + color: slategrey; +} + +.fe-article { + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; +} + +.fe-article-header { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + margin: 12px 0px; +} + +.fe-article-header h1 { + padding: 0px; + margin: 0px; +} + +.fe-article-header img { + /* max-width: 100px; */ + height: 100px; +} + +.flex-row { + display: flex; + flex-direction: row; + align-items: center; +} + +.fe-article-header p { + padding: 0px; + margin: 0px; +} + +.fe-article-body { + max-width: 880px; + width: 100%; +} + +.fe-article-body img { + max-width: 350px; + height: auto; +} + +.fe-article-nav { + width: 100%; +} + +/* .fe-article-nav ul { */ +/* padding: 0px; */ +/* margin: 6px 0px; */ +/* } */ + +.fe-article-nav ul li { + /* list-style: none; */ + margin: 6px 0px; +} + +/* big landscape tablets, laptops, and desktops */ +@media (min-width:880px) { + + .fe-article-body img { + max-width: 880px; + +} + +/* big landscape tablets, laptops, and desktops */ +@media (min-width:1025px) { +} +/* hi-res laptops and desktops */ +@media (min-width:1281px) { +} +/* Anything bigger */ +@media (min-width:2100px) { +} diff --git a/static/css/search.css b/static/css/search.css new file mode 100644 index 0000000..d3b1455 --- /dev/null +++ b/static/css/search.css @@ -0,0 +1,94 @@ +.fe-search-container { + margin: 0px; + display: flex; + flex-direction: column; + align-items: center; + height: 120px; +} + +#searchbox { + position: relative; + top: 40px; + width: 100%; + max-width: 600px; +} + +.ais-SearchBox-form { + display: flex; + flex-wrap: nowrap; + justify-content: center; + align-items: center; +} + +.ais-SearchBox-input { + width: 100%; + height: 40px; + padding: 10px; + border: 1px solid black; + border-radius: 8px; +} + +.ais-SearchBox-submitIcon, +.ais-SearchBox-submit, +.ais-SearchBox-reset, +#hits { + display: none; +} + +#hits { + position: relative; + top:40px; + background: white; + width: calc(100% - 4px); + max-width: calc(600px - 4px); + border-right: 2px solid black; + border-bottom: 2px solid black; + border-left: 2px solid black; + border-radius: 0px 0px 4px 4px; +} + +.ais-Hits-list { + list-style: none; + padding: 0px 2px; + margin: 0px; +} + +.ais-Hits-list:first-child { + display: flex; + flex-wrap: nowrap; + flex-direction: column; + justify-content: flex-start; +} + + +.ais-Hits-item { + margin: 4px 0px 0px 0px; +} + +.fe-search-hit { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + width: 100%; +} + +.fe-search-hit:link { + text-decoration: none; + float: left; + border-radius: 0px; + padding: 4px 0px; +} + +.fe-search-hit img { + width: 30px; + height: 30px; + display: inline; + float: left; + padding: 0px 6px; +} + +.fe-search-hit span { + vertical-align: middle; +} + + diff --git a/static/images/alerts/art-cat.png b/static/images/alerts/art-cat.png new file mode 100644 index 0000000..8a55cff Binary files /dev/null and b/static/images/alerts/art-cat.png differ diff --git a/static/images/alerts/confused-cat.png b/static/images/alerts/confused-cat.png new file mode 100644 index 0000000..995636b Binary files /dev/null and b/static/images/alerts/confused-cat.png differ diff --git a/static/images/alerts/disco-cat.png b/static/images/alerts/disco-cat.png new file mode 100644 index 0000000..9ade88b Binary files /dev/null and b/static/images/alerts/disco-cat.png differ diff --git a/static/images/alerts/pending-cat.png b/static/images/alerts/pending-cat.png new file mode 100644 index 0000000..8fd41a3 Binary files /dev/null and b/static/images/alerts/pending-cat.png differ diff --git a/static/images/alerts/sherlock-cat.png b/static/images/alerts/sherlock-cat.png new file mode 100644 index 0000000..c9cb6ab Binary files /dev/null and b/static/images/alerts/sherlock-cat.png differ diff --git a/static/images/alerts/success-cat.png b/static/images/alerts/success-cat.png new file mode 100644 index 0000000..e10f236 Binary files /dev/null and b/static/images/alerts/success-cat.png differ diff --git a/static/images/alerts/vomit-cat.png b/static/images/alerts/vomit-cat.png new file mode 100644 index 0000000..c69899c Binary files /dev/null and b/static/images/alerts/vomit-cat.png differ diff --git a/static/images/alerts/workout-cat.png b/static/images/alerts/workout-cat.png new file mode 100644 index 0000000..af99086 Binary files /dev/null and b/static/images/alerts/workout-cat.png differ diff --git a/static/images/icons-1/ai.png b/static/images/icons-1/ai.png new file mode 100644 index 0000000..691ffa0 Binary files /dev/null and b/static/images/icons-1/ai.png differ diff --git a/static/images/icons-1/cad.png b/static/images/icons-1/cad.png new file mode 100644 index 0000000..749c123 Binary files /dev/null and b/static/images/icons-1/cad.png differ diff --git a/static/images/icons-1/css.png b/static/images/icons-1/css.png new file mode 100644 index 0000000..d8d2540 Binary files /dev/null and b/static/images/icons-1/css.png differ diff --git a/static/images/icons-1/docx.png b/static/images/icons-1/docx.png new file mode 100644 index 0000000..ebb0f89 Binary files /dev/null and b/static/images/icons-1/docx.png differ diff --git a/static/images/icons-1/gif.png b/static/images/icons-1/gif.png new file mode 100644 index 0000000..aa40260 Binary files /dev/null and b/static/images/icons-1/gif.png differ diff --git a/static/images/icons-1/html.png b/static/images/icons-1/html.png new file mode 100644 index 0000000..9b9a6d7 Binary files /dev/null and b/static/images/icons-1/html.png differ diff --git a/static/images/icons-1/jpg.png b/static/images/icons-1/jpg.png new file mode 100644 index 0000000..54ecd0b Binary files /dev/null and b/static/images/icons-1/jpg.png differ diff --git a/static/images/icons-1/mp4.png b/static/images/icons-1/mp4.png new file mode 100644 index 0000000..8e30589 Binary files /dev/null and b/static/images/icons-1/mp4.png differ diff --git a/static/images/icons-1/png.png b/static/images/icons-1/png.png new file mode 100644 index 0000000..96479b5 Binary files /dev/null and b/static/images/icons-1/png.png differ diff --git a/static/images/icons-1/pptx.png b/static/images/icons-1/pptx.png new file mode 100644 index 0000000..a96b97c Binary files /dev/null and b/static/images/icons-1/pptx.png differ diff --git a/static/images/icons-1/psd.png b/static/images/icons-1/psd.png new file mode 100644 index 0000000..f82f61e Binary files /dev/null and b/static/images/icons-1/psd.png differ diff --git a/static/images/icons-1/rar.png b/static/images/icons-1/rar.png new file mode 100644 index 0000000..1dbb96c Binary files /dev/null and b/static/images/icons-1/rar.png differ diff --git a/static/images/icons-1/txt.png b/static/images/icons-1/txt.png new file mode 100644 index 0000000..e198698 Binary files /dev/null and b/static/images/icons-1/txt.png differ diff --git a/static/images/icons-1/xlsx.png b/static/images/icons-1/xlsx.png new file mode 100644 index 0000000..89cef9f Binary files /dev/null and b/static/images/icons-1/xlsx.png differ diff --git a/static/images/icons-1/zip.png b/static/images/icons-1/zip.png new file mode 100644 index 0000000..5361033 Binary files /dev/null and b/static/images/icons-1/zip.png differ diff --git a/static/images/icons/add-circle.png b/static/images/icons/add-circle.png new file mode 100644 index 0000000..4dc9453 Binary files /dev/null and b/static/images/icons/add-circle.png differ diff --git a/static/images/icons/add-square.png b/static/images/icons/add-square.png new file mode 100644 index 0000000..16b7c34 Binary files /dev/null and b/static/images/icons/add-square.png differ diff --git a/static/images/icons/ai.png b/static/images/icons/ai.png new file mode 100644 index 0000000..6de6d5d Binary files /dev/null and b/static/images/icons/ai.png differ diff --git a/static/images/icons/all-accounts.png b/static/images/icons/all-accounts.png new file mode 100644 index 0000000..910242f Binary files /dev/null and b/static/images/icons/all-accounts.png differ diff --git a/static/images/icons/apk.png b/static/images/icons/apk.png new file mode 100644 index 0000000..547fae5 Binary files /dev/null and b/static/images/icons/apk.png differ diff --git a/static/images/icons/archive-index.png b/static/images/icons/archive-index.png new file mode 100644 index 0000000..fd89d69 Binary files /dev/null and b/static/images/icons/archive-index.png differ diff --git a/static/images/icons/archive.png b/static/images/icons/archive.png new file mode 100644 index 0000000..9ac3918 Binary files /dev/null and b/static/images/icons/archive.png differ diff --git a/static/images/icons/audio.png b/static/images/icons/audio.png new file mode 100644 index 0000000..3012c3f Binary files /dev/null and b/static/images/icons/audio.png differ diff --git a/static/images/icons/audio2.png b/static/images/icons/audio2.png new file mode 100644 index 0000000..a8cbad7 Binary files /dev/null and b/static/images/icons/audio2.png differ diff --git a/static/images/icons/bed-time-cat.png b/static/images/icons/bed-time-cat.png new file mode 100644 index 0000000..7e1d258 Binary files /dev/null and b/static/images/icons/bed-time-cat.png differ diff --git a/static/images/icons/birthday-cat.png b/static/images/icons/birthday-cat.png new file mode 100644 index 0000000..2fd12d7 Binary files /dev/null and b/static/images/icons/birthday-cat.png differ diff --git a/static/images/icons/code.png b/static/images/icons/code.png new file mode 100644 index 0000000..ae190cb Binary files /dev/null and b/static/images/icons/code.png differ diff --git a/static/images/icons/code2.png b/static/images/icons/code2.png new file mode 100644 index 0000000..01e157f Binary files /dev/null and b/static/images/icons/code2.png differ diff --git a/static/images/icons/code3.png b/static/images/icons/code3.png new file mode 100644 index 0000000..fc05b61 Binary files /dev/null and b/static/images/icons/code3.png differ diff --git a/static/images/icons/coffee-cat.png b/static/images/icons/coffee-cat.png new file mode 100644 index 0000000..c6dee2a Binary files /dev/null and b/static/images/icons/coffee-cat.png differ diff --git a/static/images/icons/copy.png b/static/images/icons/copy.png new file mode 100644 index 0000000..79964ae Binary files /dev/null and b/static/images/icons/copy.png differ diff --git a/static/images/icons/create-account.png b/static/images/icons/create-account.png new file mode 100644 index 0000000..0cc8012 Binary files /dev/null and b/static/images/icons/create-account.png differ diff --git a/static/images/icons/create-archive-entry.png b/static/images/icons/create-archive-entry.png new file mode 100644 index 0000000..e5107b9 Binary files /dev/null and b/static/images/icons/create-archive-entry.png differ diff --git a/static/images/icons/cross-circle.png b/static/images/icons/cross-circle.png new file mode 100644 index 0000000..daaba4d Binary files /dev/null and b/static/images/icons/cross-circle.png differ diff --git a/static/images/icons/dashboard.png b/static/images/icons/dashboard.png new file mode 100644 index 0000000..349a67d Binary files /dev/null and b/static/images/icons/dashboard.png differ diff --git a/static/images/icons/database-manual-delete.png b/static/images/icons/database-manual-delete.png new file mode 100644 index 0000000..554d53a Binary files /dev/null and b/static/images/icons/database-manual-delete.png differ diff --git a/static/images/icons/default-cat.png b/static/images/icons/default-cat.png new file mode 100644 index 0000000..a5ae3df Binary files /dev/null and b/static/images/icons/default-cat.png differ diff --git a/static/images/icons/delete-account.png b/static/images/icons/delete-account.png new file mode 100644 index 0000000..919eaa3 Binary files /dev/null and b/static/images/icons/delete-account.png differ diff --git a/static/images/icons/delete-archive-entry.png b/static/images/icons/delete-archive-entry.png new file mode 100644 index 0000000..3e4acce Binary files /dev/null and b/static/images/icons/delete-archive-entry.png differ diff --git a/static/images/icons/delete-entry.png b/static/images/icons/delete-entry.png new file mode 100644 index 0000000..90a4e56 Binary files /dev/null and b/static/images/icons/delete-entry.png differ diff --git a/static/images/icons/delete-page.png b/static/images/icons/delete-page.png new file mode 100644 index 0000000..0b05eb9 Binary files /dev/null and b/static/images/icons/delete-page.png differ diff --git a/static/images/icons/delete.png b/static/images/icons/delete.png new file mode 100644 index 0000000..73b0e85 Binary files /dev/null and b/static/images/icons/delete.png differ diff --git a/static/images/icons/dinner-cat.png b/static/images/icons/dinner-cat.png new file mode 100644 index 0000000..c3b4c71 Binary files /dev/null and b/static/images/icons/dinner-cat.png differ diff --git a/static/images/icons/doc.png b/static/images/icons/doc.png new file mode 100644 index 0000000..c6a2441 Binary files /dev/null and b/static/images/icons/doc.png differ diff --git a/static/images/icons/document.png b/static/images/icons/document.png new file mode 100644 index 0000000..8c09d3a Binary files /dev/null and b/static/images/icons/document.png differ diff --git a/static/images/icons/down-arrow.png b/static/images/icons/down-arrow.png new file mode 100644 index 0000000..f7aeb79 Binary files /dev/null and b/static/images/icons/down-arrow.png differ diff --git a/static/images/icons/edit-entry.png b/static/images/icons/edit-entry.png new file mode 100644 index 0000000..f850c37 Binary files /dev/null and b/static/images/icons/edit-entry.png differ diff --git a/static/images/icons/edit-profile.png b/static/images/icons/edit-profile.png new file mode 100644 index 0000000..08cfd80 Binary files /dev/null and b/static/images/icons/edit-profile.png differ diff --git a/static/images/icons/edit-storage-item.png b/static/images/icons/edit-storage-item.png new file mode 100644 index 0000000..90d74ed Binary files /dev/null and b/static/images/icons/edit-storage-item.png differ diff --git a/static/images/icons/email.png b/static/images/icons/email.png new file mode 100644 index 0000000..d9dd462 Binary files /dev/null and b/static/images/icons/email.png differ diff --git a/static/images/icons/email2.png b/static/images/icons/email2.png new file mode 100644 index 0000000..2e1bbc2 Binary files /dev/null and b/static/images/icons/email2.png differ diff --git a/static/images/icons/error-refresh.png b/static/images/icons/error-refresh.png new file mode 100644 index 0000000..723812b Binary files /dev/null and b/static/images/icons/error-refresh.png differ diff --git a/static/images/icons/file.png b/static/images/icons/file.png new file mode 100644 index 0000000..a57d183 Binary files /dev/null and b/static/images/icons/file.png differ diff --git a/static/images/icons/font.png b/static/images/icons/font.png new file mode 100644 index 0000000..bbe037c Binary files /dev/null and b/static/images/icons/font.png differ diff --git a/static/images/icons/happy-cat.png b/static/images/icons/happy-cat.png new file mode 100644 index 0000000..34bb399 Binary files /dev/null and b/static/images/icons/happy-cat.png differ diff --git a/static/images/icons/image.png b/static/images/icons/image.png new file mode 100644 index 0000000..819e16c Binary files /dev/null and b/static/images/icons/image.png differ diff --git a/static/images/icons/index.png b/static/images/icons/index.png new file mode 100644 index 0000000..37cabe7 Binary files /dev/null and b/static/images/icons/index.png differ diff --git a/static/images/icons/info.png b/static/images/icons/info.png new file mode 100644 index 0000000..3522b33 Binary files /dev/null and b/static/images/icons/info.png differ diff --git a/static/images/icons/iso.png b/static/images/icons/iso.png new file mode 100644 index 0000000..4c0551d Binary files /dev/null and b/static/images/icons/iso.png differ diff --git a/static/images/icons/iso2.png b/static/images/icons/iso2.png new file mode 100644 index 0000000..39015a7 Binary files /dev/null and b/static/images/icons/iso2.png differ diff --git a/static/images/icons/js.png b/static/images/icons/js.png new file mode 100644 index 0000000..bdf192f Binary files /dev/null and b/static/images/icons/js.png differ diff --git a/static/images/icons/login.png b/static/images/icons/login.png new file mode 100644 index 0000000..532cdd7 Binary files /dev/null and b/static/images/icons/login.png differ diff --git a/static/images/icons/logout.png b/static/images/icons/logout.png new file mode 100644 index 0000000..8bfbf05 Binary files /dev/null and b/static/images/icons/logout.png differ diff --git a/static/images/icons/love-cat.png b/static/images/icons/love-cat.png new file mode 100644 index 0000000..72ee47f Binary files /dev/null and b/static/images/icons/love-cat.png differ diff --git a/static/images/icons/manage-archive.png b/static/images/icons/manage-archive.png new file mode 100644 index 0000000..63571a5 Binary files /dev/null and b/static/images/icons/manage-archive.png differ diff --git a/static/images/icons/manage-pages.png b/static/images/icons/manage-pages.png new file mode 100644 index 0000000..28d839b Binary files /dev/null and b/static/images/icons/manage-pages.png differ diff --git a/static/images/icons/manage-users.png b/static/images/icons/manage-users.png new file mode 100644 index 0000000..e5ab4a2 Binary files /dev/null and b/static/images/icons/manage-users.png differ diff --git a/static/images/icons/morning-cat.png b/static/images/icons/morning-cat.png new file mode 100644 index 0000000..69ee20d Binary files /dev/null and b/static/images/icons/morning-cat.png differ diff --git a/static/images/icons/pdf.png b/static/images/icons/pdf.png new file mode 100644 index 0000000..ed84a99 Binary files /dev/null and b/static/images/icons/pdf.png differ diff --git a/static/images/icons/plus.png b/static/images/icons/plus.png new file mode 100644 index 0000000..b58f521 Binary files /dev/null and b/static/images/icons/plus.png differ diff --git a/static/images/icons/power.png b/static/images/icons/power.png new file mode 100644 index 0000000..9d5ca5c Binary files /dev/null and b/static/images/icons/power.png differ diff --git a/static/images/icons/ppt.png b/static/images/icons/ppt.png new file mode 100644 index 0000000..b01df5d Binary files /dev/null and b/static/images/icons/ppt.png differ diff --git a/static/images/icons/presentation.png b/static/images/icons/presentation.png new file mode 100644 index 0000000..cb0cb1b Binary files /dev/null and b/static/images/icons/presentation.png differ diff --git a/static/images/icons/profile.png b/static/images/icons/profile.png new file mode 100644 index 0000000..fbfa1cc Binary files /dev/null and b/static/images/icons/profile.png differ diff --git a/static/images/icons/psd.png b/static/images/icons/psd.png new file mode 100644 index 0000000..e1a3260 Binary files /dev/null and b/static/images/icons/psd.png differ diff --git a/static/images/icons/record.png b/static/images/icons/record.png new file mode 100644 index 0000000..4f2971c Binary files /dev/null and b/static/images/icons/record.png differ diff --git a/static/images/icons/reset-website.png b/static/images/icons/reset-website.png new file mode 100644 index 0000000..7acac81 Binary files /dev/null and b/static/images/icons/reset-website.png differ diff --git a/static/images/icons/restore-snapshot.png b/static/images/icons/restore-snapshot.png new file mode 100644 index 0000000..edc4c43 Binary files /dev/null and b/static/images/icons/restore-snapshot.png differ diff --git a/static/images/icons/rock-star-cat.png b/static/images/icons/rock-star-cat.png new file mode 100644 index 0000000..60f85ba Binary files /dev/null and b/static/images/icons/rock-star-cat.png differ diff --git a/static/images/icons/save.png b/static/images/icons/save.png new file mode 100644 index 0000000..2cd2520 Binary files /dev/null and b/static/images/icons/save.png differ diff --git a/static/images/icons/settings.png b/static/images/icons/settings.png new file mode 100644 index 0000000..6bba071 Binary files /dev/null and b/static/images/icons/settings.png differ diff --git a/static/images/icons/site-side-menu.png b/static/images/icons/site-side-menu.png new file mode 100644 index 0000000..d0ea81e Binary files /dev/null and b/static/images/icons/site-side-menu.png differ diff --git a/static/images/icons/spreadsheet.png b/static/images/icons/spreadsheet.png new file mode 100644 index 0000000..5075cd2 Binary files /dev/null and b/static/images/icons/spreadsheet.png differ diff --git a/static/images/icons/sql.png b/static/images/icons/sql.png new file mode 100644 index 0000000..f7f79e5 Binary files /dev/null and b/static/images/icons/sql.png differ diff --git a/static/images/icons/storage-index-1.png b/static/images/icons/storage-index-1.png new file mode 100644 index 0000000..5516213 Binary files /dev/null and b/static/images/icons/storage-index-1.png differ diff --git a/static/images/icons/storage-index-2.png b/static/images/icons/storage-index-2.png new file mode 100644 index 0000000..65cda90 Binary files /dev/null and b/static/images/icons/storage-index-2.png differ diff --git a/static/images/icons/storage-index.png b/static/images/icons/storage-index.png new file mode 100644 index 0000000..6e1af40 Binary files /dev/null and b/static/images/icons/storage-index.png differ diff --git a/static/images/icons/study-cat.png b/static/images/icons/study-cat.png new file mode 100644 index 0000000..1bc28bb Binary files /dev/null and b/static/images/icons/study-cat.png differ diff --git a/static/images/icons/svg.png b/static/images/icons/svg.png new file mode 100644 index 0000000..ab6a4bc Binary files /dev/null and b/static/images/icons/svg.png differ diff --git a/static/images/icons/svg2.png b/static/images/icons/svg2.png new file mode 100644 index 0000000..6ef6021 Binary files /dev/null and b/static/images/icons/svg2.png differ diff --git a/static/images/icons/take-snapshot.png b/static/images/icons/take-snapshot.png new file mode 100644 index 0000000..48165f7 Binary files /dev/null and b/static/images/icons/take-snapshot.png differ diff --git a/static/images/icons/transfer.png b/static/images/icons/transfer.png new file mode 100644 index 0000000..51583d7 Binary files /dev/null and b/static/images/icons/transfer.png differ diff --git a/static/images/icons/ttf.png b/static/images/icons/ttf.png new file mode 100644 index 0000000..b73c841 Binary files /dev/null and b/static/images/icons/ttf.png differ diff --git a/static/images/icons/txt.png b/static/images/icons/txt.png new file mode 100644 index 0000000..7b66b30 Binary files /dev/null and b/static/images/icons/txt.png differ diff --git a/static/images/icons/up-arrow.png b/static/images/icons/up-arrow.png new file mode 100644 index 0000000..c6d7676 Binary files /dev/null and b/static/images/icons/up-arrow.png differ diff --git a/static/images/icons/upload-storage-item.png b/static/images/icons/upload-storage-item.png new file mode 100644 index 0000000..5f1f7c9 Binary files /dev/null and b/static/images/icons/upload-storage-item.png differ diff --git a/static/images/icons/video.png b/static/images/icons/video.png new file mode 100644 index 0000000..dbfa2ae Binary files /dev/null and b/static/images/icons/video.png differ diff --git a/static/images/icons/video2.png b/static/images/icons/video2.png new file mode 100644 index 0000000..b5a6dca Binary files /dev/null and b/static/images/icons/video2.png differ diff --git a/static/images/icons/view-entry.png b/static/images/icons/view-entry.png new file mode 100644 index 0000000..881cc38 Binary files /dev/null and b/static/images/icons/view-entry.png differ diff --git a/static/images/icons/workout-cat.png b/static/images/icons/workout-cat.png new file mode 100644 index 0000000..939a3fa Binary files /dev/null and b/static/images/icons/workout-cat.png differ diff --git a/static/images/icons/xls.png b/static/images/icons/xls.png new file mode 100644 index 0000000..74e6b48 Binary files /dev/null and b/static/images/icons/xls.png differ diff --git a/static/js/filter-search.js b/static/js/filter-search.js new file mode 100644 index 0000000..514d52a --- /dev/null +++ b/static/js/filter-search.js @@ -0,0 +1,18 @@ + window.addEventListener("load", () => { + // (A) GET HTML ELEMENTS + var filter = document.getElementById("fe-search-filter"), // search box + list = document.querySelectorAll("#fe-search-filter-list li"); // all list items + + // (B) ATTACH KEY UP LISTENER TO SEARCH BOX + filter.onkeyup = () => { + // (B1) GET CURRENT SEARCH TERM + let search = filter.value.toLowerCase(); + + // (B2) LOOP THROUGH LIST ITEMS - ONLY SHOW THOSE THAT MATCH SEARCH + for (let i of list) { + let item = i.innerHTML.toLowerCase(); + if (item.indexOf(search) == -1) { i.classList.add("hide"); } + else { i.classList.remove("hide"); } + } + }; + }); diff --git a/static/js/full-search.js b/static/js/full-search.js new file mode 100644 index 0000000..69891e9 --- /dev/null +++ b/static/js/full-search.js @@ -0,0 +1,99 @@ +/** +Full Search +================================================================================ +This file's main focus in providing the Meilisearch features to the +search.html template. + +For more information on Meilisearch, use: + +- https://docs.meilisearch.com/ +- https://github.com/meilisearch/instant-meilisearch + +Meilisearch provides an 'InstantSearch' add-on (plug-in?) which +links the Meilisearch instance you have running to this website (link above for +more information). +*/ + +// 'server' variable defined in /templates/search.html + +// -- constructed via Djula template. URL provided by data in this website's +// database. Value stored in back-end database and varies from localhost to +// prod. Which is why the database is stored in the database and passed to the +// view instead of trying to work it out in JavaScript -- the user can't change +// it here, only the developers can. + +let apiKey = ""; + +if (location.hostname === "localhost" + || location.hostname === "127.0.0.1") { + apiKey= "meilisearch-beta-key"; +} else { + apiKey = "meilisearch-key"; +} + +const search = instantsearch({ + indexName: "nera", + searchClient: instantMeiliSearch( + server, + apiKey, + { + primaryKey: 'id', + } + ) +}); + +search.addWidgets([ + instantsearch.widgets.searchBox({ + container: "#searchbox", + placeholder: "Search the archive here...", + }), + instantsearch.widgets.clearRefinements({ + container: "#clear-refinements" + }), + instantsearch.widgets.refinementList({ + container: "#year-list", + attribute: "year" + }), + instantsearch.widgets.refinementList({ + container: "#month-list", + attribute: "month" + }), + instantsearch.widgets.refinementList({ + container: "#keywords-list", + attribute: "keywords" + }), + instantsearch.widgets.configure({ + hitsPerPage: 50, + snippetEllipsisText: "...", + attributesToSnippet: ["title:100"] + }), + instantsearch.widgets.hits({ + container: "#hits", + templates: { + item: ` + +
+ +
+ +{{#helpers.highlight}}{"attribute": "title"}{{/helpers.highlight}} + + +{{#helpers.highlight}}{"attribute": "month"}{{/helpers.highlight}} +{{#helpers.highlight}}{"attribute": "year"}{{/helpers.highlight}} + + +{{keywords}} + +
+
+
+ ` + } + }), + instantsearch.widgets.pagination({ + container: "#pagination" + }) +]); + +search.start(); diff --git a/static/js/instant-meilisearch-0.8.0.js b/static/js/instant-meilisearch-0.8.0.js new file mode 100644 index 0000000..1e03c00 --- /dev/null +++ b/static/js/instant-meilisearch-0.8.0.js @@ -0,0 +1,29 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).window=t.window||{})}(this,(function(t){"use strict"; +/*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */var e=function(){return(e=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0&&i[i.length-1])||6!==o[0]&&2!==o[0])){s=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]-1};function c(t){if("string"!=typeof t&&(t=String(t)),/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(t))throw new TypeError("Invalid character in header field name");return t.toLowerCase()}function h(t){return"string"!=typeof t&&(t=String(t)),t}function l(t){var e={next:function(){var e=t.shift();return{done:void 0===e,value:e}}};return r&&(e[Symbol.iterator]=function(){return e}),e}function d(t){this.map={},t instanceof d?t.forEach((function(t,e){this.append(e,t)}),this):Array.isArray(t)?t.forEach((function(t){this.append(t[0],t[1])}),this):t&&Object.getOwnPropertyNames(t).forEach((function(e){this.append(e,t[e])}),this)}function f(t){if(t.bodyUsed)return Promise.reject(new TypeError("Already read"));t.bodyUsed=!0}function p(t){return new Promise((function(e,n){t.onload=function(){e(t.result)},t.onerror=function(){n(t.error)}}))}function v(t){var e=new FileReader,n=p(e);return e.readAsArrayBuffer(t),n}function y(t){if(t.slice)return t.slice(0);var e=new Uint8Array(t.byteLength);return e.set(new Uint8Array(t)),e.buffer}function b(){return this.bodyUsed=!1,this._initBody=function(t){var e;this._bodyInit=t,t?"string"==typeof t?this._bodyText=t:i&&Blob.prototype.isPrototypeOf(t)?this._bodyBlob=t:o&&FormData.prototype.isPrototypeOf(t)?this._bodyFormData=t:n&&URLSearchParams.prototype.isPrototypeOf(t)?this._bodyText=t.toString():s&&i&&((e=t)&&DataView.prototype.isPrototypeOf(e))?(this._bodyArrayBuffer=y(t.buffer),this._bodyInit=new Blob([this._bodyArrayBuffer])):s&&(ArrayBuffer.prototype.isPrototypeOf(t)||a(t))?this._bodyArrayBuffer=y(t):this._bodyText=t=Object.prototype.toString.call(t):this._bodyText="",this.headers.get("content-type")||("string"==typeof t?this.headers.set("content-type","text/plain;charset=UTF-8"):this._bodyBlob&&this._bodyBlob.type?this.headers.set("content-type",this._bodyBlob.type):n&&URLSearchParams.prototype.isPrototypeOf(t)&&this.headers.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"))},i&&(this.blob=function(){var t=f(this);if(t)return t;if(this._bodyBlob)return Promise.resolve(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(new Blob([this._bodyArrayBuffer]));if(this._bodyFormData)throw new Error("could not read FormData body as blob");return Promise.resolve(new Blob([this._bodyText]))},this.arrayBuffer=function(){return this._bodyArrayBuffer?f(this)||Promise.resolve(this._bodyArrayBuffer):this.blob().then(v)}),this.text=function(){var t,e,n,r=f(this);if(r)return r;if(this._bodyBlob)return t=this._bodyBlob,e=new FileReader,n=p(e),e.readAsText(t),n;if(this._bodyArrayBuffer)return Promise.resolve(function(t){for(var e=new Uint8Array(t),n=new Array(e.length),r=0;r-1?r:n),this.mode=e.mode||this.mode||null,this.signal=e.signal||this.signal,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&i)throw new TypeError("Body not allowed for GET or HEAD requests");this._initBody(i)}function m(t){var e=new FormData;return t.trim().split("&").forEach((function(t){if(t){var n=t.split("="),r=n.shift().replace(/\+/g," "),i=n.join("=").replace(/\+/g," ");e.append(decodeURIComponent(r),decodeURIComponent(i))}})),e}function x(t,e){e||(e={}),this.type="default",this.status=void 0===e.status?200:e.status,this.ok=this.status>=200&&this.status<300,this.statusText="statusText"in e?e.statusText:"OK",this.headers=new d(e.headers),this.url=e.url||"",this._initBody(t)}w.prototype.clone=function(){return new w(this,{body:this._bodyInit})},b.call(w.prototype),b.call(x.prototype),x.prototype.clone=function(){return new x(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new d(this.headers),url:this.url})},x.error=function(){var t=new x(null,{status:0,statusText:""});return t.type="error",t};var T=[301,302,303,307,308];x.redirect=function(t,e){if(-1===T.indexOf(e))throw new RangeError("Invalid status code");return new x(null,{status:e,headers:{location:t}})},e.DOMException=t.DOMException;try{new e.DOMException}catch(t){e.DOMException=function(t,e){this.message=t,this.name=e;var n=Error(t);this.stack=n.stack},e.DOMException.prototype=Object.create(Error.prototype),e.DOMException.prototype.constructor=e.DOMException}function R(t,n){return new Promise((function(r,o){var s=new w(t,n);if(s.signal&&s.signal.aborted)return o(new e.DOMException("Aborted","AbortError"));var u=new XMLHttpRequest;function a(){u.abort()}u.onload=function(){var t,e,n={status:u.status,statusText:u.statusText,headers:(t=u.getAllResponseHeaders()||"",e=new d,t.replace(/\r?\n[\t ]+/g," ").split(/\r?\n/).forEach((function(t){var n=t.split(":"),r=n.shift().trim();if(r){var i=n.join(":").trim();e.append(r,i)}})),e)};n.url="responseURL"in u?u.responseURL:n.headers.get("X-Request-URL");var i="response"in u?u.response:u.responseText;r(new x(i,n))},u.onerror=function(){o(new TypeError("Network request failed"))},u.ontimeout=function(){o(new TypeError("Network request failed"))},u.onabort=function(){o(new e.DOMException("Aborted","AbortError"))},u.open(s.method,s.url,!0),"include"===s.credentials?u.withCredentials=!0:"omit"===s.credentials&&(u.withCredentials=!1),"responseType"in u&&i&&(u.responseType="blob"),s.headers.forEach((function(t,e){u.setRequestHeader(e,t)})),s.signal&&(s.signal.addEventListener("abort",a),u.onreadystatechange=function(){4===u.readyState&&s.signal.removeEventListener("abort",a)}),u.send(void 0===s._bodyInit?null:s._bodyInit)}))}R.polyfill=!0,t.fetch||(t.fetch=R,t.Headers=d,t.Request=w,t.Response=x),e.Headers=d,e.Request=w,e.Response=x,e.fetch=R,Object.defineProperty(e,"__esModule",{value:!0})}({})}("undefined"!=typeof self?self:o)}));var u=s((function(t,e){!function(t){ +/*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ +var e=function(t,n){return(e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])})(t,n)};function n(t,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function r(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}var r=function(){return(r=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0&&i[i.length-1])||6!==o[0]&&2!==o[0])){s=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0)for(var n in t){e[n]||(e[n]={});for(var r=0,i=t[n];rr&&e>Math.PI&&r<-Math.PI?(d+=Math.PI,l+=Math.PI):(d=p(d),l=p(l)),Math.abs(u)l.paginationTotalHits?e.limit=l.paginationTotalHits:e.limit=d}var f=t.sort;(null==f?void 0:f.length)&&(e.sort=[f]);var p=y(function(t){var e={},n=t.aroundLatLng,r=t.aroundLatLngViaIP,i=t.aroundRadius,o=t.aroundPrecision,s=t.minimumAroundRadius,u=t.insideBoundingBox,a=t.insidePolygon;return n&&(e.aroundLatLng=n),r&&console.warn("instant-meilisearch: `aroundLatLngViaIP` is not supported."),i&&(e.aroundRadius=i),o&&console.warn("instant-meilisearch: `aroundPrecision` is not supported.\n See this discussion to track its implementation https://github.com/meilisearch/product/discussions/264"),s&&(e.minimumAroundRadius=s),u&&(e.insideBoundingBox=u),a&&console.warn("instant-meilisearch: `insidePolygon` is not implented in instant-meilisearch."),e}(t));return(null==p?void 0:p.filter)&&(e.filter?e.filter.unshift(p.filter):e.filter=[p.filter]),e}function x(t){return"string"==typeof t?t:void 0===t?JSON.stringify(null):JSON.stringify(t)}function T(t){return Array.isArray(t)?t.map((function(t){return T(t)})):"object"!=typeof(e=t)||Array.isArray(e)||null===e?{value:x(t)}:Object.keys(t).reduce((function(e,n){return e[n]=T(t[n]),e}),{});var e}function R(t,e,n){var r=e.primaryKey,i=n.hitsPerPage,o=function(t,e,n){if(n<0)throw new TypeError('Value too small for "hitsPerPage" parameter, expected integer between 0 and 9223372036854775807');var r=e*n;return t.slice(r,r+n)}(t,n.page,i).map((function(t){if(Object.keys(t).length>0){var e=t._formatted;t._matchesPosition;var n=function(t,e){var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(r=Object.getOwnPropertySymbols(t);i0?Math.ceil(r/i):0),a=R(t.hits,n,s),c=t.estimatedTotalHits,h=t.processingTimeMs,l=t.query,d=s.hitsPerPage,f=s.page;return{results:[e({index:n.indexUid,hitsPerPage:d,page:f,facets:o,nbPages:u,nbHits:c,processingTimeMS:h,query:l,hits:a,params:"",exhaustiveNbHits:!1},{})]}}function k(t){void 0===t&&(t={});var e=t;return{getEntry:function(t){if(e[t])try{return JSON.parse(e[t])}catch(n){return e[t]}},formatKey:function(t){return t.reduce((function(t,e){return t+JSON.stringify(e)}),"")},setEntry:function(t,n){e[t]=JSON.stringify(n)}}}t.instantMeiliSearch=function(t,i,o){void 0===i&&(i=""),void 0===o&&(o={});var s=f(k()),a={},c=function(t){void 0===t&&(t=[]);var e="Meilisearch instant-meilisearch (v".concat("0.8.0",")");return t.concat(e)}(o.clientAgents),h=new u.MeiliSearch({host:t,apiKey:i,clientAgents:c});return{search:function(t){return n(this,void 0,void 0,(function(){var n,i,u,c,l;return r(this,(function(r){switch(r.label){case 0:return r.trys.push([0,2,,3]),n=t[0],i=function(t,n,r){var i=t.indexName.split(":"),o=i[0],s=i.slice(1),u=t.params,a=function(t){var e=t.paginationTotalHits,n=t.hitsPerPage;return{paginationTotalHits:null!=e?e:200,hitsPerPage:void 0===n?20:n,page:t.page||0}}({paginationTotalHits:n.paginationTotalHits,hitsPerPage:null==u?void 0:u.hitsPerPage,page:null==u?void 0:u.page});return e(e(e({},n),u),{sort:s.join(":")||"",indexUid:o,pagination:a,defaultFacetDistribution:r,placeholderSearch:!1!==n.placeholderSearch,keepZeroFacets:!!n.keepZeroFacets,finitePagination:!!n.finitePagination})}(n,o,a),u=m(i),[4,s.searchResponse(i,u,h)];case 1:return c=r.sent(),a=function(t,e){return""===e.query&&0===Object.keys(t).length?e.facetDistribution:t}(a,c),[2,A(c,i)];case 2:throw l=r.sent(),console.error(l),new Error(l);case 3:return[2]}}))}))},searchForFacetValues:function(t){return n(this,void 0,void 0,(function(){return r(this,(function(t){switch(t.label){case 0:return[4,new Promise((function(t,e){e(new Error("SearchForFacetValues is not compatible with Meilisearch")),t([])}))];case 1:return[2,t.sent()]}}))}))}}},Object.defineProperty(t,"__esModule",{value:!0})})); +//# sourceMappingURL=instant-meilisearch.umd.min.js.map diff --git a/static/js/instantsearch-4.43.1.js b/static/js/instantsearch-4.43.1.js new file mode 100644 index 0000000..6205bad --- /dev/null +++ b/static/js/instantsearch-4.43.1.js @@ -0,0 +1,3 @@ +/*! InstantSearch.js 4.43.1 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch.js */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).instantsearch=t()}(this,function(){"use strict";function f(e){return(f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function C(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n "},_getHierarchicalRootPath:function(e){return e.rootPath||null},_getHierarchicalShowParentLevel:function(e){return"boolean"!=typeof e.showParentLevel||e.showParentLevel},getHierarchicalFacetByName:function(t){return g(this.hierarchicalFacets,function(e){return e.name===t})},getHierarchicalFacetBreadcrumb:function(e){if(!this.isHierarchicalFacet(e))return[];var t=this.getHierarchicalRefinement(e)[0];if(!t)return[];var n=this._getHierarchicalFacetSeparator(this.getHierarchicalFacetByName(e));return t.split(n).map(function(e){return e.trim()})},toString:function(){return JSON.stringify(this,null,2)}};var _=w;function x(e,t){if(e!==t){var n=void 0!==e,r=null===e,i=void 0!==t,a=null===t;if(!a&&t=i.length?r:"desc"===i[n]?-r:r}return e.index-t.index}),t.map(function(e){return e.value})};var e=function(e){return"string"!=typeof e?e:String(e).replace(/^-/,"\\-")},A=function(e){return"string"!=typeof e?e:e.replace(/^\\-/,"-")},H=function(d){return function(e,t){var n=d.hierarchicalFacets[t],r=d.hierarchicalFacetsRefinements[n.name]&&d.hierarchicalFacetsRefinements[n.name][0]||"",i=d._getHierarchicalFacetSeparator(n),a=d._getHierarchicalRootPath(n),s=d._getHierarchicalShowParentLevel(n),o=F(d._getHierarchicalFacetSortBy(n)),c=e.every(function(e){return e.exhaustive}),u=function(o,c,u,l,d){return function(e,n,t){var r=e;if(0n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},X.prototype.once=function(e,t){if(!Z(t))throw TypeError("listener must be a function");var n=!1;function r(){this.removeListener(e,r),n||(n=!0,t.apply(this,arguments))}return r.listener=t,this.on(e,r),this},X.prototype.removeListener=function(e,t){var n,r,i,a;if(!Z(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(i=(n=this._events[e]).length,r=-1,n===t||Z(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(ee(n)){for(a=i;0":7,"=":8,_v:9,"{":10,"&":11,_t:12},S.scan=function(e,t){var n,r,i,a,s,o=e.length,c=0,u=null,l=null,d="",h=[],f=!1,m=0,p=0,g="{{",v="}}";function y(){0"==n.tag&&(n.indent=h[r].text.toString()),h.splice(r,1));else t||h.push({tag:"\n"});f=!1,p=h.length}for(t&&(t=t.split(" "),g=t[0],v=t[1]),m=0;m":m,"<":function(e,t){var n={partials:{},code:"",subs:{},inPartial:!0};S.walk(e.nodes,n);var r=t.partials[m(e,t)];r.subs=n.subs,r.partials=n.partials},$:function(e,t){var n={subs:{},code:"",partials:t.partials,prefix:e.n};S.walk(e.nodes,n),t.subs[e.n]=n.code,t.inPartial||(t.code+='t.sub("'+h(e.n)+'",c,p,i);')},"\n":function(e,t){t.code+=p('"\\n"'+(e.last?"":" + i"))},_v:function(e,t){t.code+="t.b(t.v(t."+f(e.n)+'("'+h(e.n)+'",c,p,0)));'},_t:function(e,t){t.code+=p('"'+h(e.text)+'"')},"{":e,"&":e},S.walk=function(e,t){for(var n,r=0,i=e.length;r/g,i=/\'/g,a=/\"/g,s=/[&<>\"\']/;function o(e){return String(null==e?"":e)}var d=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)}}(t)});_e.Template=Pe.Template,_e.template=_e.Template;var xe=_e;function Ne(e){var t=e.templates,n=e.templateKey,r=e.compileOptions,i=e.helpers,a=e.data,s=e.bindEvent,o=t[n];if("string"!=typeof o&&"function"!=typeof o)throw new Error("Template must be 'string' or 'function', was '".concat(f(o),"' (key: ").concat(n,")"));if("function"==typeof o)return o(a,s);var c=function(e,t,n){var r=0":">",'"':""","'":"'"},Ue=/[&<>"']/g,qe=RegExp(Ue.source);var Qe={"&":"&","<":"<",">":">",""":'"',"'":"'"},Ve=/&(amp|quot|lt|gt|#39);/g,$e=RegExp(Ve.source);var Ke={highlightPreTag:"__ais-highlight__",highlightPostTag:"__/ais-highlight__"},ze={highlightPreTag:"",highlightPostTag:""};function Je(e){return function(e){return e&&qe.test(e)?e.replace(Ue,function(e){return Be[e]}):e}(e).replace(new RegExp(Ke.highlightPreTag,"g"),ze.highlightPreTag).replace(new RegExp(Ke.highlightPostTag,"g"),ze.highlightPostTag)}function Ye(n){return Ae(n)&&"string"!=typeof n.value?Object.keys(n).reduce(function(e,t){return W(W({},e),{},k({},t,Ye(n[t])))},{}):Array.isArray(n)?n.map(Ye):W(W({},n),{},{value:Je(n.value)})}function Xe(e){return void 0===e.__escaped&&((e=e.map(function(e){var t=h({},e);return t._highlightResult&&(t._highlightResult=Ye(t._highlightResult)),t._snippetResult&&(t._snippetResult=Ye(t._snippetResult)),t})).__escaped=!0),e}function Ge(e){var t=ze.highlightPreTag,n=ze.highlightPostTag;return e.map(function(e){return e.isHighlighted?t+e.value+n:e.value}).join("")}function Ze(e){var n=ze.highlightPostTag,t=ze.highlightPreTag,r=e.split(t),i=r.shift(),a=i?[{value:i,isHighlighted:!1}]:[];return r.forEach(function(e){var t=e.split(n);a.push({value:t[0],isHighlighted:!0}),""!==t[1]&&a.push({value:t[1],isHighlighted:!1})}),a}var et=new RegExp(/\w/i);function tt(e,t){var n,r,i=e[t],a=(null===(n=e[t+1])||void 0===n?void 0:n.isHighlighted)||!0,s=(null===(r=e[t-1])||void 0===r?void 0:r.isHighlighted)||!0;return et.test(function(e){return e&&$e.test(e)?e.replace(Ve,function(e){return Qe[e]}):e}(i.value))||s!==a?i.isHighlighted:s}function nt(n){return n.some(function(e){return e.isHighlighted})?n.map(function(e,t){return W(W({},e),{},{isHighlighted:!tt(n,t)})}):n.map(function(e){return W(W({},e),{},{isHighlighted:!1})})}function rt(e,t){return e.setQueryParameters({hierarchicalFacets:t.hierarchicalFacets.reduce(function(e,t){var n=function(e,t){if(!Array.isArray(e))return-1;for(var n=0;n')).replace(new RegExp(ze.highlightPostTag,"g"),""))}var Et=Ft("ReverseHighlight");function kt(e){var t=e.attribute,n=e.highlightedTagName,r=void 0===n?"mark":n,i=e.hit,a=e.cssClasses,s=void 0===a?{}:a,o=(Me(i._highlightResult,t)||{}).value,c=void 0===o?"":o,u=Et({descendantName:"highlighted"})+(s.highlighted?" ".concat(s.highlighted):"");return Ge(nt(Ze(c))).replace(new RegExp(ze.highlightPreTag,"g"),"<".concat(r,' class="').concat(u,'">')).replace(new RegExp(ze.highlightPostTag,"g"),""))}var Lt=Ft("Snippet");function jt(e){var t=e.attribute,n=e.highlightedTagName,r=void 0===n?"mark":n,i=e.hit,a=e.cssClasses,s=void 0===a?{}:a,o=(Me(i._snippetResult,t)||{}).value,c=void 0===o?"":o,u=Lt({descendantName:"highlighted"})+(s.highlighted?" ".concat(s.highlighted):"");return c.replace(new RegExp(ze.highlightPreTag,"g"),"<".concat(r,' class="').concat(u,'">')).replace(new RegExp(ze.highlightPostTag,"g"),""))}var Mt=Ft("ReverseSnippet");function Ot(e){var t=e.attribute,n=e.highlightedTagName,r=void 0===n?"mark":n,i=e.hit,a=e.cssClasses,s=void 0===a?{}:a,o=(Me(i._snippetResult,t)||{}).value,c=void 0===o?"":o,u=Mt({descendantName:"highlighted"})+(s.highlighted?" ".concat(s.highlighted):"");return Ge(nt(Ze(c))).replace(new RegExp(ze.highlightPreTag,"g"),"<".concat(r,' class="').concat(u,'">')).replace(new RegExp(ze.highlightPostTag,"g"),""))}function At(e,t){return function(e){var t,n=e.method,r=e.payload;if("object"!==f(r))throw new Error("The insights helper expects the payload to be an object.");try{t=ht(r)}catch(e){throw new Error("Could not JSON serialize the payload object.")}return'data-insights-method="'.concat(n,'" data-insights-payload="').concat(t,'"')}({method:e,payload:t})}function Ht(){return function(e){for(var t="".concat(e,"="),n=document.cookie.split(";"),r=0;r>6]+Zt[128|63&c]:c<55296||57344<=c?s+=Zt[224|c>>12]+Zt[128|c>>6&63]+Zt[128|63&c]:(o+=1,c=65536+((1023&c)<<10|1023&a.charCodeAt(o)),s+=Zt[240|c>>18]+Zt[128|c>>12&63]+Zt[128|c>>6&63]+Zt[128|63&c])}return s},isBuffer:function(e){return!(!e||"object"!=typeof e)&&!!(e.constructor&&e.constructor.isBuffer&&e.constructor.isBuffer(e))},isRegExp:function(e){return"[object RegExp]"===Object.prototype.toString.call(e)},maybeMap:function(e,t){if(Gt(e)){for(var n=[],r=0;r=":return"≥";case"<=":return"≤";default:return e}}(e.operator)," ").concat(e.name):e.name,r={attribute:e.attribute,type:e.type,value:t,label:n};return void 0!==e.operator&&(r.operator=e.operator),void 0!==e.count&&(r.count=e.count),void 0!==e.exhaustive&&(r.exhaustive=e.exhaustive),r}function Tn(N,e){var I=1 ":t,n=e.rootPath,l=void 0===n?null:n,r=e.showParentLevel,h=void 0===r||r,i=e.limit,f=void 0===i?10:i,a=e.showMore,m=void 0!==a&&a,s=e.showMoreLimit,p=void 0===s?20:s,o=e.sortBy,g=void 0===o?Ln:o,v=e.transformItems,y=void 0===v?function(e){return e}:v;if(!c||!Array.isArray(c)||0===c.length)throw new Error(kn("The `attributes` option expects an array of strings."));if(!0===m&&p<=f)throw new Error(kn("The `showMoreLimit` option must be greater than `limit`."));var b,S,R=D(c,1)[0],w=function(){};function _(){w()}var P=!1;function x(){return P?p:f}return{$$type:"ais.hierarchicalMenu",init:function(e){var t=e.instantSearchInstance;N(W(W({},this.getWidgetRenderState(e)),{},{instantSearchInstance:t}),!0)},render:function(e){var t=e.instantSearchInstance;w=function(e,t){return function(){P=!P,t.render(e)}}(e,this),N(W(W({},this.getWidgetRenderState(e)),{},{instantSearchInstance:t}),!1)},dispose:function(e){var t=e.state;return I(),t.removeHierarchicalFacet(R).setQueryParameter("maxValuesPerFacet",void 0)},getRenderState:function(e,t){return W(W({},e),{},{hierarchicalMenu:W(W({},e.hierarchicalMenu),{},k({},R,this.getWidgetRenderState(t)))})},getWidgetRenderState:function(e){var t=e.results,n=e.state,r=e.createURL,i=e.instantSearchInstance,a=e.helper,s=[],o=!1;if(b=b||dt({instantSearchInstance:i,helper:a,attribute:R,widgetType:this.$$type}),S=S||function(e){b("click",e),a.toggleFacetRefinement(R,e).search()},t){var c=t.getFacetValues(R,{sortBy:g,facetOrdering:g===Ln}),u=c&&!Array.isArray(c)&&c.data?c.data:[],l=(n.maxValuesPerFacet||0)>x()?u.length<=x():u.lengthR()),a=v(c.slice(0,R()).map(function(e){var t=e.name,n=e.escapedValue;e.path;return W(W({},j(e,["name","escapedValue","path"])),{},{label:t,value:n})}),{results:t})}return{items:a,createURL:d,refine:h,sendEvent:l,canRefine:0="]&&n[">="][0]||"",a=n["<="]&&n["<="][0]||"";return""===i&&""===a?e:W(W({},e),{},{numericMenu:W(W({},e.numericMenu),{},k({},u,"".concat(i,":").concat(a)))})},getWidgetSearchParameters:function(e,t){var n=t.uiState,r=n.numericMenu&&n.numericMenu[u],i=e.clearRefinements(u);if(!r)return i.setQueryParameters({numericRefinements:W(W({},i.numericRefinements),{},k({},u,{}))});if(-1===r.indexOf(":"))return i.addNumericRefinement(u,"=",Number(r));var a=D(r.split(":").map(parseFloat),2),s=a[0],o=a[1],c=Oe(s)?i.addNumericRefinement(u,">=",s):i;return Oe(o)?c.addNumericRefinement(u,"<=",o):c},getRenderState:function(e,t){return W(W({},e),{},{numericMenu:W(W({},e.numericMenu),{},k({},u,this.getWidgetRenderState(t)))})},getWidgetRenderState:function(e){var t=e.results,n=e.state,r=e.instantSearchInstance,i=e.helper,a=e.createURL;return l.refine||(l.refine=function(e){var t=Cr(i.state,u,e);l.sendEvent("click",e),i.setState(t).search()}),l.createURL||(l.createURL=function(t){return function(e){return a(Cr(t,u,e))}}),l.sendEvent||(l.sendEvent=function(e){var c=e.instantSearchInstance,u=e.helper,l=e.attribute;return function(){for(var e=arguments.length,t=new Array(e),n=0;n=",n.start)&&Er(r,"<=",n.end):void 0!==n.start?Er(r,">=",n.start):void 0!==n.end?Er(r,"<=",n.end):void 0===n.start&&void 0===n.end&&Object.keys(r).every(function(e){return 0===(r[e]||[]).length})}function Cr(e,t,n){var r=e,i=JSON.parse(decodeURI(n)),a=r.getNumericRefinements(t);if(void 0===i.start&&void 0===i.end)return r.removeNumericRefinement(t);if(Tr(r,t,i)||(r=r.removeNumericRefinement(t)),void 0!==i.start&&void 0!==i.end){if(i.start>i.end)throw new Error("option.start should be > to option.end");if(i.start===i.end)return r=Er(a,"=",i.start)?r.removeNumericRefinement(t,"=",i.start):r.addNumericRefinement(t,"=",i.start)}return void 0!==i.start&&(Er(a,">=",i.start)&&(r=r.removeNumericRefinement(t,">=",i.start)),r=r.addNumericRefinement(t,">=",i.start)),void 0!==i.end&&(Er(a,"<=",i.end)&&(r=r.removeNumericRefinement(t,"<=",i.end)),r=r.addNumericRefinement(t,"<=",i.end)),"number"==typeof r.page&&(r.page=0),r}function Er(e,t,n){return void 0!==e[t]&&e[t].includes(n)}function kr(n,e){var r=1=")||[],1)[0],l=D(s.getNumericRefinement(w,"<=")||[],1)[0],d=void 0===n||""===n,h=void 0===r||""===r,f=Ar({min:d?void 0:parseFloat(n),max:h?void 0:parseFloat(r),precision:x}),m=f.min,p=f.max;i=Oe(_)||o!==m?Oe(_)&&d?_:m:void 0,a=Oe(P)||c!==p?Oe(P)&&h?P:p:void 0;var g=void 0===i,v=Oe(o)&&o<=i,y=g||Oe(i)&&(!Oe(o)||v),b=void 0===a,S=Oe(a)&&a<=c,R=b||Oe(a)&&(!Oe(c)||S);return(u!==i||l!==a)&&y&&R?(s=s.removeNumericRefinement(w),Oe(i)&&(s=s.addNumericRefinement(w,">=",i)),Oe(a)&&(s=s.addNumericRefinement(w,"<=",a)),s.resetPage()):null}function m(e,t,n,r){var i=3=")||[],1)[0],n=D(e.getNumericRefinement(w,"<=")||[],1)[0];return[Oe(t)?t:-1/0,Oe(n)?n:1/0]}(n);return{refine:u(r,n,t?a:{min:void 0,max:void 0}),canRefine:a.min!==a.max,format:c,range:a,sendEvent:function(l,d,h){return function(){for(var e=arguments.length,t=new Array(e),n=0;n="],i=void 0===r?[]:r,a=n["<="],s=void 0===a?[]:a;return 0===i.length&&0===s.length?e:W(W({},e),{},{range:W(W({},e.range),{},k({},w,"".concat(i,":").concat(s)))})},getWidgetSearchParameters:function(e,t){var n=t.uiState,r=e.addDisjunctiveFacet(w).setQueryParameters({numericRefinements:W(W({},e.numericRefinements),{},k({},w,{}))});Oe(_)&&(r=r.addNumericRefinement(w,">=",_)),Oe(P)&&(r=r.addNumericRefinement(w,"<=",P));var i=n.range&&n.range[w];if(!i||-1===i.indexOf(":"))return r;var a=D(i.split(":").map(parseFloat),2),s=a[0],o=a[1];return Oe(s)&&(!Oe(_)||_=")).addNumericRefinement(w,">=",s)),Oe(o)&&(!Oe(P)||op||g&&!P;return{createURL:function(e){return r(n.resetPage().toggleFacetRefinement(m,e))},items:s,refine:R,searchForItems:d,isFromSearch:!1,canRefine:0="])&&void 0!==t&&t.length)return n[">="][0]}function r(e,t){var n=p(e)===Number(t),r=e.resetPage().removeNumericRefinement(f);return n?r:r.addNumericRefinement(f,"<=",m).addNumericRefinement(f,">=",Number(t))}var g=function(e){return function(e,t){h("click",t),e.setState(r(e.state,t)).search()}.bind(null,e)},v=function(e){var t=e.state,n=e.createURL;return function(e){return n(r(t,e))}};return{$$type:Gr,init:function(e){var t=e.instantSearchInstance;n(W(W({},this.getWidgetRenderState(e)),{},{instantSearchInstance:t}),!0)},render:function(e){var t=e.instantSearchInstance;n(W(W({},this.getWidgetRenderState(e)),{},{instantSearchInstance:t}),!1)},getRenderState:function(e,t){return W(W({},e),{},{ratingMenu:W(W({},e.ratingMenu),{},k({},f,this.getWidgetRenderState(t)))})},getWidgetRenderState:function(e){var t=e.helper,n=e.results,r=e.state,i=e.instantSearchInstance,a=e.createURL,s=[];if(h=h||function(e){var o=e.instantSearchInstance,c=e.helper,u=e.getRefinedStar,l=e.attribute;return function(){for(var e=arguments.length,t=new Array(e),n=0;n=").concat(i)]},attribute:l})}else o.sendEventToInsights(t[0])}}({instantSearchInstance:i,helper:t,getRefinedStar:function(){return p(t.state)},attribute:f}),n)for(var o=n.getFacetValues(f,{}),c=(o.length,function(e){var r=0;e.forEach(function(e){var t=D(e.name.split("."),2)[1],n=void 0===t?"":t;r=Math.max(r,n.length)})}(o),p(r)),u=function(n){var e=c===n,t=o.filter(function(e){return Number(e.name)>=n&&Number(e.name)<=m}).map(function(e){return e.count}).reduce(function(e,t){return e+t},0);if(c&&!e&&0===t)return"continue";var r=P(new Array(Math.floor(m/1))).map(function(e,t){return 1*t=",r):i.setQueryParameters({numericRefinements:W(W({},i.numericRefinements),{},k({},f,{}))})}}}}function Qr(n,e){var t=1 ":n,i=e.rootPath,a=void 0===i?null:i,o=e.transformItems,c=void 0===o?function(e){return e}:o;if(!t||!Array.isArray(t)||0===t.length)throw new Error(ni("The `attributes` option expects an array of strings."));var u=D(t,1)[0];function l(e,t){if(t)return e.resetPage().toggleFacetRefinement(u,t);var n=e.getHierarchicalFacetBreadcrumb(u);return 0===n.length?e:e.resetPage().toggleFacetRefinement(u,n[0])}return{$$type:"ais.breadcrumb",init:function(e){d(W(W({},this.getWidgetRenderState(e)),{},{instantSearchInstance:e.instantSearchInstance}),!0)},render:function(e){d(W(W({},this.getWidgetRenderState(e)),{},{instantSearchInstance:e.instantSearchInstance}),!1)},dispose:function(){h()},getRenderState:function(e,t){return W(W({},e),{},{breadcrumb:W(W({},e.breadcrumb),{},k({},u,this.getWidgetRenderState(t)))})},getWidgetRenderState:function(e){var t=e.helper,n=e.createURL,r=e.results,i=e.state;var a=function(){if(!r||0===i.hierarchicalFacets.length)return[];var e=D(i.hierarchicalFacets,1)[0].name,t=r.getFacetValues(e,{}),n=Array.isArray(t.data)?t.data:[];return c(function(n){return n.map(function(e,t){return{label:e.label,value:t+1===n.length?null:n[t+1].value}})}(function n(e){return e.reduce(function(e,t){return t.isRefined&&(e.push({label:t.name,value:t.escapedValue}),Array.isArray(t.data)&&(e=e.concat(n(t.data)))),e},[])}(n)),{results:r})}();return f.createURL||(f.createURL=function(e){return n(l(t.state,e))}),f.refine||(f.refine=function(e){t.setState(l(t.state,e)).search()}),{canRefine:0")}function pi(c,u){return function(e){var t=e||{},a=t.hit,s=t.matchingPatterns,n=t.transformSearchParameters,r=void 0===n?function(e){return e}:n;if(!a)throw new Error(fi("The `hit` option is required."));if(!s)throw new Error(fi("The `matchingPatterns` option is required."));var i=Object.keys(s).reduce(function(e,t){var n=s[t],r=Me(a,t),i=n.score;return Array.isArray(r)?[].concat(P(e),[r.map(function(e){return mi({attributeName:t,attributeValue:e,attributeScore:i})})]):"string"==typeof r?[].concat(P(e),[mi({attributeName:t,attributeValue:r,attributeScore:i})]):e},[]),o=W({},r(new pe.SearchParameters({sumOrFiltersScores:!0,facetFilters:["objectID:-".concat(a.objectID)],optionalFilters:i})));return W(W({},hi(c,u)({searchParameters:o})),{},{$$type:"ais.configureRelatedItems"})}}var gi=st({name:"autocomplete",connector:!0}),vi=st({name:"query-rules",connector:!0});function yi(e){var t=this.helper,n=this.initialRuleContexts,r=this.trackedFilters,i=this.transformRuleContexts,a=e.state,s=a.ruleContexts||[],o=function(e){var i=e.helper,a=e.sharedHelperState,s=e.trackedFilters;return Object.keys(s).reduce(function(e,t){var n=Ce(i.lastResults||{},a,!0).filter(function(e){return e.attribute===t}).map(function(e){return e.numericValue||e.name}),r=(0,s[t])(n);return[].concat(P(e),P(n.filter(function(e){return r.includes(e)}).map(function(e){return function(e){return e.replace(/[^a-z0-9-_]+/gi,"_")}("ais-".concat(t,"-").concat(e))})))},[])}({helper:t,sharedHelperState:a,trackedFilters:r}),c=i([].concat(P(n),P(o))).slice(0,10);De(s,c)||t.overrideStateWithoutTriggeringChangeEvent(W(W({},a),{},{ruleContexts:c}))}function bi(d,e){var h=1= 4.8.0 required."));m=yt(n.findAnswers,u),b(W(W({},this.getWidgetRenderState(e)),{},{instantSearchInstance:e.instantSearchInstance}),!0)},render:function(n){var r=this,e=n.state.query;if(!e)return v=!(g=[]),void b(W(W({},this.getWidgetRenderState(n)),{},{instantSearchInstance:n.instantSearchInstance}),!1);g=[],v=!0,b(W(W({},this.getWidgetRenderState(n)),{},{instantSearchInstance:n.instantSearchInstance}),!1),p(m(e,i,W(W({},f),{},{nbHits:s,attributesForPrediction:a}))).then(function(e){if(e){d&&0"},Wi=st({name:"breadcrumb"}),Di=Ft("Breadcrumb"),Bi={resetLabel:"Clear refinements"},Ui=st({name:"clear-refinements"}),qi=Ft("ClearRefinements"),Qi=st({name:"current-refinements"}),Vi=Ft("CurrentRefinements"),$i={header:"",loader:"",item:function(e){return JSON.stringify(e)}},Ki=st({name:"answers"}),zi=Ft("Answers"),Ji=st({name:"dynamic-widgets"}),Yi=Ft("DynamicWidgets");function Xi(e){var t=document.createElement("div");return t.className=Yi({descendantName:"widget"}),e.appendChild(t),t}function Gi(e){var t=e||{},n=t.container,r=t.widgets,i=t.fallbackWidget,a=j(t,["container","widgets","fallbackWidget"]);if(!n)throw new Error(Ji("The `container` option is required."));if(!(r&&Array.isArray(r)&&r.every(function(e){return"function"==typeof e})))throw new Error(Ji("The `widgets` option expects an array of callbacks."));var s=ye(n),o=document.createElement("div");o.className=Yi();var c=new Map,u=[],l=xi(function(e,t){var n=e.attributesToRender;t&&s.appendChild(o),n.forEach(function(e){if(c.has(e)){var t=c.get(e);o.appendChild(t)}})},function(){s.removeChild(o)})(W(W({},a),{},{widgets:u,fallbackWidget:"function"==typeof i?function(e){var t=e.attribute,n=Xi(o);return c.set(t,n),i({attribute:t,container:n})}:void 0}));return W(W({},l),{},{init:function(i){r.forEach(function(e){var t=Xi(o),n=e(t),r=bt(n,i);c.set(r,t),u.push(n)}),l.init(i)},$$widgetType:"ais.dynamicWidgets"})}function Zi(e){var t=e.className,n=e.disabled,r=void 0!==n&&n;return Kn("button",{className:t,onClick:e.onClick,disabled:r},e.children)}function ea(e){var t=e.classNameLabel,n=e.classNameInput,r=e.checked,i=e.onToggle,a=e.children;return Kn("label",{className:t},Kn("input",{className:n,type:"checkbox",checked:r,onChange:i}),a)}function ta(e){var t=e.cssClasses,n=e.enableRefine,r=e.enableRefineControl,i=e.enableClearMapRefinement,a=e.isRefineOnMapMove,s=e.isRefinedWithMap,o=e.hasMapMoveSinceLastRefine,c=e.onRefineToggle,u=e.onRefineClick,l=e.onClearClick,d=e.templateProps;return Kn(Jn,null,n&&Kn("div",null,r&&Kn("div",{className:t.control},a||!o?Kn(ea,{classNameLabel:Ei(t.label,k({},t.selectedLabel,a)),classNameInput:t.input,checked:a,onToggle:c},Kn(ki,h({},d,{templateKey:"toggle",rootTagName:"span"}))):Kn(Zi,{className:t.redo,disabled:!o,onClick:u},Kn(ki,h({},d,{templateKey:"redo",rootTagName:"span"})))),!r&&!a&&Kn("div",{className:t.control},Kn(Zi,{className:Ei(t.redo,k({},t.disabledRedo,!o)),disabled:!o,onClick:u},Kn(ki,h({},d,{templateKey:"redo",rootTagName:"span"})))),i&&s&&Kn(Zi,{className:t.reset,onClick:l},Kn(ki,h({},d,{templateKey:"reset",rootTagName:"span"})))))}function na(e){var t=e.refine,n=e.mapInstance;return t({northEast:n.getBounds().getNorthEast().toJSON(),southWest:n.getBounds().getSouthWest().toJSON()})}function ra(e,t){e.isUserInteraction=!1,t(),e.isUserInteraction=!0}function ia(e,t){var n=e.items,r=e.position,i=e.currentRefinement,a=e.refine,s=e.clearMapRefinement,o=e.toggleRefineOnMapMove,c=e.isRefineOnMapMove,u=e.setMapMoveSinceLastRefine,l=e.hasMapMoveSinceLastRefine,d=e.isRefinedWithMap,h=e.widgetParams,f=e.instantSearchInstance,m=h.container,p=h.googleReference,g=h.cssClasses,v=h.templates,y=h.initialZoom,b=h.initialPosition,S=h.enableRefine,R=h.enableClearMapRefinement,w=h.enableRefineControl,_=h.mapOptions,P=h.createMarker,x=h.markerOptions,N=h.renderState;if(t){N.isUserInteraction=!0,N.isPendingRefine=!1,N.markers=[];var I=document.createElement("div");I.className=g.root,m.appendChild(I);var F=document.createElement("div");F.className=g.map,I.appendChild(F);var T=document.createElement("div");T.className=g.tree,I.appendChild(T),N.mapInstance=new p.maps.Map(F,W({mapTypeControl:!1,fullscreenControl:!1,streetViewControl:!1,clickableIcons:!1,zoomControlOptions:{position:p.maps.ControlPosition.LEFT_TOP}},_));return p.maps.event.addListenerOnce(N.mapInstance,"idle",function(){function e(){N.isUserInteraction&&S&&(u(),c()&&(N.isPendingRefine=!0))}N.mapInstance.addListener("center_changed",e),N.mapInstance.addListener("zoom_changed",e),N.mapInstance.addListener("dragstart",e),N.mapInstance.addListener("idle",function(){N.isUserInteraction&&N.isPendingRefine&&(N.isPendingRefine=!1,na({mapInstance:N.mapInstance,refine:a}))})}),void(N.templateProps=Re({templatesConfig:f.templatesConfig,templates:v}))}var C=n.map(function(e){return e.objectID}),E=D(function(e,a){return e.reduce(function(e,t){var n=D(e,2),r=n[0],i=n[1];return a.includes(t.__id)?[r.concat(t),i]:[r,i.concat(t)]},[[],[]])}(N.markers,C),2),k=E[0],L=E[1],j=k.map(function(e){return e.__id}),M=n.filter(function(e){return!j.includes(e.objectID)});L.forEach(function(e){return e.setMap(null)}),N.markers=k.concat(M.map(function(n){var r=P({map:N.mapInstance,item:n});return Object.keys(x.events).forEach(function(t){r.addListener(t,function(e){x.events[t]({map:N.mapInstance,event:e,item:n,marker:r})})}),r}));var O=!l(),A=i?0:null,H=!i&&Boolean(N.markers.length)?function(e,t){var n=t.reduce(function(e,t){return e.extend(t.getPosition())},new e.maps.LatLngBounds);return{northEast:n.getNorthEast().toJSON(),southWest:n.getSouthWest().toJSON()}}(p,N.markers):i;H&&O?ra(N,function(){N.mapInstance.fitBounds(new p.maps.LatLngBounds(H.southWest,H.northEast),A)}):O&&ra(N,function(){N.mapInstance.setCenter(r||b),N.mapInstance.setZoom(y)}),fr(Kn(ta,{cssClasses:g,enableRefine:S,enableRefineControl:w,enableClearMapRefinement:R,isRefineOnMapMove:c(),isRefinedWithMap:d(),hasMapMoveSinceLastRefine:l(),onRefineToggle:o,onRefineClick:function(){return na({mapInstance:N.mapInstance,refine:a})},onClearClick:s,templateProps:N.templateProps}),m.querySelector(".".concat(g.tree)))}var aa={HTMLMarker:"

Your custom HTML Marker

",reset:"Clear the map refinement",toggle:"Search as I move the map",redo:"Redo search here"},sa=st({name:"geo-search"}),oa=Ft("GeoSearch");function ca(e){var t=e.className,n=e.handleClick,r=e.facetValueToRefine,i=e.isRefined,a=e.templateProps,s=e.templateKey,o=e.templateData,c=e.subItems;return Kn("li",{className:t,onClick:function(e){n({facetValueToRefine:r,isRefined:i,originalEvent:e})}},Kn(ki,h({},a,{templateKey:s,data:o})),c)}var ua={query:"",showSubmit:!0,showReset:!0,showLoadingIndicator:!0,autofocus:!1,searchAsYouType:!0,isSearchStalled:!1,disabled:!1,onChange:Le,onSubmit:Le,onReset:Le,refine:Le},la=function(){L(i,Yn);var r=O(i);function i(){var s;C(this,i);for(var e=arguments.length,t=new Array(e),n=0;n{{label}}{{#helpers.formatNumber}}{{count}}{{/helpers.formatNumber}}',showMoreText:"\n {{#isShowingMore}}\n Show less\n {{/isShowingMore}}\n {{^isShowingMore}}\n Show more\n {{/isShowingMore}}\n "},ma=st({name:"hierarchical-menu"}),pa=Ft("HierarchicalMenu"),ga={empty:"No results",item:function(e){return JSON.stringify(e,null,2)}},va=st({name:"hits"}),ya=Ft("Hits"),ba=pr(function(e){var t=e.results,n=e.hits,r=e.bindEvent,i=e.cssClasses,a=e.templateProps;return 0===t.hits.length?Kn(ki,h({},a,{templateKey:"empty",rootProps:{className:Ei(i.root,i.emptyRoot)},data:t})):Kn("div",{className:i.root},Kn("ol",{className:i.list},n.map(function(e,t){return Kn(ki,h({},a,{templateKey:"item",rootTagName:"li",rootProps:{className:i.item},key:e.objectID,data:W(W({},e),{},{__hitIndex:t}),bindEvent:r}))})))});function Sa(e){var t=e.currentValue,n=e.options,r=e.cssClasses,i=e.setValue;return Kn("select",{className:Ei(r.select),onChange:function(e){return i(e.target.value)},value:"".concat(t)},n.map(function(e){return Kn("option",{className:Ei(r.option),key:e.label+e.value,value:"".concat(e.value)},e.label)}))}var Ra=st({name:"hits-per-page"}),wa=Ft("HitsPerPage"),_a={empty:"No results",showPreviousText:"Show previous results",showMoreText:"Show more results",item:function(e){return JSON.stringify(e,null,2)}},Pa=st({name:"infinite-hits"}),xa=Ft("InfiniteHits"),Na=pr(function(e){var t=e.results,n=e.hits,r=e.bindEvent,i=e.hasShowPrevious,a=e.showPrevious,s=e.showMore,o=e.isFirstPage,c=e.isLastPage,u=e.cssClasses,l=e.templateProps;return 0===t.hits.length?Kn(ki,h({},l,{templateKey:"empty",rootProps:{className:Ei(u.root,u.emptyRoot)},data:t})):Kn("div",{className:u.root},i&&Kn(ki,h({},l,{templateKey:"showPreviousText",rootTagName:"button",rootProps:{className:Ei(u.loadPrevious,k({},u.disabledLoadPrevious,o)),disabled:o,onClick:a}})),Kn("ol",{className:u.list},n.map(function(e,t){return Kn(ki,h({},l,{templateKey:"item",rootTagName:"li",rootProps:{className:u.item},key:e.objectID,data:W(W({},e),{},{__hitIndex:t}),bindEvent:r}))})),Kn(ki,h({},l,{templateKey:"showMoreText",rootTagName:"button",rootProps:{className:Ei(u.loadMore,k({},u.disabledLoadMore,c)),disabled:c,onClick:s}})))}),Ia={item:'{{label}}{{#helpers.formatNumber}}{{count}}{{/helpers.formatNumber}}',showMoreText:"\n {{#isShowingMore}}\n Show less\n {{/isShowingMore}}\n {{^isShowingMore}}\n Show more\n {{/isShowingMore}}\n "},Fa=st({name:"menu"}),Ta=Ft("Menu");function Ca(e){var t=e.cssClasses,n=e.templateProps,r=e.items,i=e.refine,a=(Ie(r,function(e){return e.isRefined})||{value:""}).value;return Kn("div",{className:Ei(t.root,k({},t.noRefinementRoot,0===r.length))},Kn("select",{className:t.select,value:a,onChange:function(e){i(e.target.value)}},Kn(ki,h({},n,{templateKey:"defaultOption",rootTagName:"option",rootProps:{value:"",className:t.option}})),r.map(function(e){return Kn(ki,h({},n,{templateKey:"item",rootTagName:"option",rootProps:{value:e.value,className:t.option},key:e.value,data:e}))})))}var Ea={item:"{{label}} ({{#helpers.formatNumber}}{{count}}{{/helpers.formatNumber}})",defaultOption:"See all"},ka=st({name:"menu-select"}),La=Ft("MenuSelect"),ja={item:''},Ma=st({name:"numeric-menu"}),Oa=Ft("NumericMenu");function Aa(n){function t(t){return function(e){be(e)||(e.preventDefault(),n.setCurrentPage(t))}}return Kn("div",{className:Ei(n.cssClasses.root,k({},n.cssClasses.noRefinementRoot,n.nbPages<=1))},Kn("ul",{className:n.cssClasses.list},n.showFirst&&Kn(Ha,{ariaLabel:"First",className:n.cssClasses.firstPageItem,isDisabled:n.isFirstPage,label:n.templates.first,pageNumber:0,createURL:n.createURL,cssClasses:n.cssClasses,createClickHandler:t}),n.showPrevious&&Kn(Ha,{ariaLabel:"Previous",className:n.cssClasses.previousPageItem,isDisabled:n.isFirstPage,label:n.templates.previous,pageNumber:n.currentPage-1,createURL:n.createURL,cssClasses:n.cssClasses,createClickHandler:t}),n.pages.map(function(e){return Kn(Ha,{key:e,ariaLabel:"".concat(e+1),className:n.cssClasses.pageItem,isSelected:e===n.currentPage,label:"".concat(e+1),pageNumber:e,createURL:n.createURL,cssClasses:n.cssClasses,createClickHandler:t})}),n.showNext&&Kn(Ha,{ariaLabel:"Next",className:n.cssClasses.nextPageItem,isDisabled:n.isLastPage,label:n.templates.next,pageNumber:n.currentPage+1,createURL:n.createURL,cssClasses:n.cssClasses,createClickHandler:t}),n.showLast&&Kn(Ha,{ariaLabel:"Last",className:n.cssClasses.lastPageItem,isDisabled:n.isLastPage,label:n.templates.last,pageNumber:n.nbPages-1,createURL:n.createURL,cssClasses:n.cssClasses,createClickHandler:t})))}function Ha(e){var t=e.label,n=e.ariaLabel,r=e.pageNumber,i=e.className,a=e.isDisabled,s=void 0!==a&&a,o=e.isSelected,c=void 0!==o&&o,u=e.cssClasses,l=e.createURL,d=e.createClickHandler;return Kn("li",{className:Ei(u.item,i,s&&u.disabledItem,c&&u.selectedItem)},s?Kn("span",{className:u.link,dangerouslySetInnerHTML:{__html:t}}):Kn("a",{className:u.link,"aria-label":n,href:l(r),onClick:d(r),dangerouslySetInnerHTML:{__html:t}}))}var Wa,Da,Ba,Ua=Ft("Pagination"),qa=st({name:"pagination"}),Qa={previous:"‹",next:"›",first:"«",last:"»"},Va=0,$a=[],Ka=An.__b,za=An.__r,Ja=An.diffed,Ya=An.__c,Xa=An.unmount;function Ga(e,t){An.__h&&An.__h(Da,e,Va||t),Va=0;var n=Da.__H||(Da.__H={__:[],__h:[]});return e>=n.__.length&&n.__.push({}),n.__[e]}function Za(e){return Va=1,function(e,t,n){var r=Ga(Wa++,2);return r.t=e,r.__c||(r.__=[n?n(t):ss(void 0,t),function(e){var t=r.t(r.__[0],e);r.__[0]!==t&&(r.__=[t,r.__[1]],r.__c.setState({}))}],r.__c=Da),r.__}(ss,e)}function es(e){return Va=5,function(e,t){var n=Ga(Wa++,7);return as(n.__H,t)&&(n.__=e(),n.__H=t,n.__h=e),n.__}(function(){return{current:e}},[])}function ts(){var t;for($a.sort(function(e,t){return e.__v.__b-t.__v.__b});t=$a.pop();)if(t.__P)try{t.__H.__h.forEach(rs),t.__H.__h.forEach(is),t.__H.__h=[]}catch(e){t.__H.__h=[],An.__e(e,t.__v)}}An.__b=function(e){Da=null,Ka&&Ka(e)},An.__r=function(e){za&&za(e),Wa=0;var t=(Da=e.__c).__H;t&&(t.__h.forEach(rs),t.__h.forEach(is),t.__h=[])},An.diffed=function(e){Ja&&Ja(e);var t=e.__c;t&&t.__H&&t.__H.__h.length&&(1!==$a.push(t)&&Ba===An.requestAnimationFrame||((Ba=An.requestAnimationFrame)||function(e){function t(){clearTimeout(r),ns&&cancelAnimationFrame(n),setTimeout(e)}var n,r=setTimeout(t,100);ns&&(n=requestAnimationFrame(t))})(ts)),Da=null},An.__c=function(e,n){n.some(function(t){try{t.__h.forEach(rs),t.__h=t.__h.filter(function(e){return!e.__||is(e)})}catch(e){n.some(function(e){e.__h&&(e.__h=[])}),n=[],An.__e(e,t.__v)}}),Ya&&Ya(e,n)},An.unmount=function(e){Xa&&Xa(e);var t,n=e.__c;n&&n.__H&&(n.__H.__.forEach(function(e){try{rs(e)}catch(e){t=e}}),t&&An.__e(t,n.__v))};var ns="function"==typeof requestAnimationFrame;function rs(e){var t=Da,n=e.__c;"function"==typeof n&&(e.__c=void 0,n()),Da=t}function is(e){var t=Da;e.__c=e.__(),Da=t}function as(n,e){return!n||n.length!==e.length||e.some(function(e,t){return e!==n[t]})}function ss(e,t){return"function"==typeof t?t(e):t}function os(t){var e,n=D(Za(t.isCollapsed),2),r=n[0],i=n[1],a=D(Za(!1),2),s=a[0],o=a[1],c=es(null);return function(e,t){var n=Ga(Wa++,3);!An.__s&&as(n.__H,t)&&(n.__=e,n.__H=t,Da.__H.__h.push(n))}(function(){var e=c.current;if(e)return e.appendChild(t.bodyElement),function(){e.removeChild(t.bodyElement)}},[c,t.bodyElement]),s||t.isCollapsed===r||i(t.isCollapsed),Kn("div",{className:Ei(t.cssClasses.root,(e={},k(e,t.cssClasses.noRefinementRoot,t.hidden),k(e,t.cssClasses.collapsibleRoot,t.collapsible),k(e,t.cssClasses.collapsedRoot,r),e)),hidden:t.hidden},t.templates.header&&Kn("div",{className:t.cssClasses.header},Kn(ki,{templates:t.templates,templateKey:"header",rootTagName:"span",data:t.data}),t.collapsible&&Kn("button",{className:t.cssClasses.collapseButton,"aria-expanded":!r,onClick:function(e){e.preventDefault(),o(!0),i(function(e){return!e})}},Kn(ki,{templates:t.templates,templateKey:"collapseButtonText",rootTagName:"span",data:{collapsed:r}}))),Kn("div",{className:t.cssClasses.body,ref:c}),t.templates.footer&&Kn(ki,{templates:t.templates,templateKey:"footer",rootProps:{className:t.cssClasses.footer},data:t.data}))}function cs(e){var t=e.url,n=e.theme,r=e.cssClasses;return Kn("div",{className:r.root},Kn("a",{href:t,target:"_blank",className:r.link,"aria-label":"Search by Algolia",rel:"noopener noreferrer"},Kn("svg",{height:"1.2em",className:r.logo,viewBox:"0 0 168 24",style:{width:"auto"}},Kn("path",{fill:"dark"===n?"#FFF":"#5D6494",d:"M6.97 6.68V8.3a4.47 4.47 0 00-2.42-.67 2.2 2.2 0 00-1.38.4c-.34.26-.5.6-.5 1.02 0 .43.16.77.49 1.03.33.25.83.53 1.51.83a7.04 7.04 0 011.9 1.08c.34.24.58.54.73.89.15.34.23.74.23 1.18 0 .95-.33 1.7-1 2.24a4 4 0 01-2.6.81 5.71 5.71 0 01-2.94-.68v-1.71c.84.63 1.81.94 2.92.94.58 0 1.05-.14 1.39-.4.34-.28.5-.65.5-1.13 0-.29-.1-.55-.3-.8a2.2 2.2 0 00-.65-.53 23.03 23.03 0 00-1.64-.78 13.67 13.67 0 01-1.11-.64c-.12-.1-.28-.22-.46-.4a1.72 1.72 0 01-.39-.5 4.46 4.46 0 01-.22-.6c-.07-.23-.1-.48-.1-.75 0-.91.33-1.63 1-2.17a4 4 0 012.57-.8c.97 0 1.8.18 2.47.52zm7.47 5.7v-.3a2.26 2.26 0 00-.5-1.44c-.3-.35-.74-.53-1.32-.53-.53 0-.99.2-1.37.58a2.9 2.9 0 00-.72 1.68h3.91zm1 2.79v1.4c-.6.34-1.38.51-2.36.51a4.02 4.02 0 01-3-1.13 4.04 4.04 0 01-1.11-2.97c0-1.3.34-2.32 1.02-3.06a3.38 3.38 0 012.6-1.1c1.03 0 1.85.32 2.46.96.6.64.9 1.57.9 2.78 0 .33-.03.68-.09 1.04h-5.31c.1.7.4 1.24.89 1.61.49.38 1.1.56 1.85.56.86 0 1.58-.2 2.15-.6zm6.61-1.78h-1.21c-.6 0-1.05.12-1.35.36-.3.23-.46.53-.46.89 0 .37.12.66.36.88.23.2.57.32 1.02.32.5 0 .9-.15 1.2-.43.3-.28.44-.65.44-1.1v-.92zm-4.07-2.55V9.33a4.96 4.96 0 012.5-.55c2.1 0 3.17 1.03 3.17 3.08V17H22.1v-.96c-.42.68-1.15 1.02-2.19 1.02-.76 0-1.38-.22-1.84-.66-.46-.44-.7-1-.7-1.68 0-.78.3-1.38.88-1.81.59-.43 1.4-.65 2.46-.65h1.34v-.46c0-.55-.13-.97-.4-1.25-.26-.29-.7-.43-1.32-.43-.86 0-1.65.24-2.35.72zm9.34-1.93v1.42c.39-1 1.1-1.5 2.12-1.5.15 0 .31.02.5.05v1.53c-.23-.1-.48-.14-.76-.14-.54 0-.99.24-1.34.71a2.8 2.8 0 00-.52 1.71V17h-1.57V8.91h1.57zm5 4.09a3 3 0 00.76 2.01c.47.53 1.14.8 2 .8.64 0 1.24-.18 1.8-.53v1.4c-.53.32-1.2.48-2 .48a3.98 3.98 0 01-4.17-4.18c0-1.16.38-2.15 1.14-2.98a4 4 0 013.1-1.23c.7 0 1.34.15 1.92.44v1.44a3.24 3.24 0 00-1.77-.5A2.65 2.65 0 0032.33 13zm7.92-7.28v4.58c.46-1 1.3-1.5 2.5-1.5.8 0 1.42.24 1.9.73.48.5.72 1.17.72 2.05V17H43.8v-5.1c0-.56-.14-.99-.43-1.29-.28-.3-.65-.45-1.1-.45-.54 0-1 .2-1.42.6-.4.4-.61 1.02-.61 1.85V17h-1.56V5.72h1.56zM55.2 15.74c.6 0 1.1-.25 1.5-.76.4-.5.6-1.16.6-1.95 0-.92-.2-1.62-.6-2.12-.4-.5-.92-.74-1.55-.74-.56 0-1.05.22-1.5.67-.44.45-.66 1.13-.66 2.06 0 .96.22 1.67.64 2.14.43.47.95.7 1.57.7zM53 5.72v4.42a2.74 2.74 0 012.43-1.34c1.03 0 1.86.38 2.51 1.15.65.76.97 1.78.97 3.05 0 1.13-.3 2.1-.92 2.9-.62.81-1.47 1.21-2.54 1.21s-1.9-.45-2.46-1.34V17h-1.58V5.72H53zm9.9 11.1l-3.22-7.9h1.74l1 2.62 1.26 3.42c.1-.32.48-1.46 1.15-3.42l.91-2.63h1.66l-2.92 7.87c-.78 2.07-1.96 3.1-3.56 3.1-.28 0-.53-.02-.73-.07v-1.34c.17.04.35.06.54.06 1.03 0 1.76-.57 2.17-1.7z"}),hs,fs,Kn("path",{fill:"dark"===n?"#FFF":"#5468FF",d:"M120.92 18.8c-4.38.02-4.38-3.54-4.38-4.1V1.36l2.67-.42v13.25c0 .32 0 2.36 1.71 2.37v2.24zm-10.84-2.18c.82 0 1.43-.04 1.85-.12v-2.72a5.48 5.48 0 00-1.57-.2c-.3 0-.6.02-.9.07-.3.04-.57.12-.81.24-.24.11-.44.28-.58.49a.93.93 0 00-.22.65c0 .63.22 1 .61 1.23.4.24.94.36 1.62.36zm-.23-9.7c.88 0 1.62.11 2.23.33.6.22 1.09.53 1.44.92.36.4.61.92.76 1.48.16.56.23 1.17.23 1.85v6.87a21.69 21.69 0 01-4.68.5c-.69 0-1.32-.07-1.9-.2a4 4 0 01-1.46-.63 3.3 3.3 0 01-.96-1.13 4.3 4.3 0 01-.34-1.8 3.13 3.13 0 011.43-2.63c.45-.3.95-.5 1.54-.62a8.8 8.8 0 013.79.05v-.44c0-.3-.04-.6-.11-.87a1.78 1.78 0 00-1.1-1.22 3.2 3.2 0 00-1.15-.2 9.75 9.75 0 00-2.95.46l-.33-2.19a11.43 11.43 0 013.56-.53zm52.84 9.63c.82 0 1.43-.05 1.85-.13V13.7a5.42 5.42 0 00-1.57-.2c-.3 0-.6.02-.9.07-.3.04-.57.12-.81.24-.24.12-.44.28-.58.5a.93.93 0 00-.22.65c0 .63.22.99.61 1.23.4.24.94.36 1.62.36zm-.23-9.7c.88 0 1.63.11 2.23.33.6.22 1.1.53 1.45.92.35.39.6.92.76 1.48.15.56.23 1.18.23 1.85v6.88c-.41.08-1.03.19-1.87.31-.83.12-1.77.18-2.81.18-.7 0-1.33-.06-1.9-.2a4 4 0 01-1.47-.63c-.4-.3-.72-.67-.95-1.13a4.3 4.3 0 01-.34-1.8c0-.66.13-1.08.38-1.53.26-.45.61-.82 1.05-1.1.44-.3.95-.5 1.53-.62a8.8 8.8 0 013.8.05v-.43c0-.31-.04-.6-.12-.88-.07-.28-.2-.52-.38-.73a1.78 1.78 0 00-.73-.5c-.3-.1-.68-.2-1.14-.2a9.85 9.85 0 00-2.95.47l-.32-2.19a11.63 11.63 0 013.55-.53zm-8.03-1.27a1.62 1.62 0 000-3.24 1.62 1.62 0 100 3.24zm1.35 13.22h-2.7V7.27l2.7-.42V18.8zm-4.72 0c-4.38.02-4.38-3.54-4.38-4.1l-.01-13.34 2.67-.42v13.25c0 .32 0 2.36 1.72 2.37v2.24zm-8.7-5.9a4.7 4.7 0 00-.74-2.79 2.4 2.4 0 00-2.07-1 2.4 2.4 0 00-2.06 1 4.7 4.7 0 00-.74 2.8c0 1.16.25 1.94.74 2.62a2.4 2.4 0 002.07 1.02c.88 0 1.57-.34 2.07-1.02a4.2 4.2 0 00.73-2.63zm2.74 0a6.46 6.46 0 01-1.52 4.23c-.49.53-1.07.94-1.76 1.22-.68.29-1.73.45-2.26.45a6.6 6.6 0 01-2.25-.45 5.1 5.1 0 01-2.88-3.13 7.3 7.3 0 01-.01-4.84 5.13 5.13 0 012.9-3.1 5.67 5.67 0 012.22-.42c.81 0 1.56.14 2.24.42.69.29 1.28.69 1.75 1.22.49.52.87 1.15 1.14 1.89a7 7 0 01.43 2.5zm-20.14 0c0 1.11.25 2.36.74 2.88.5.52 1.13.78 1.91.78a4.07 4.07 0 002.12-.6V9.33c-.19-.04-.99-.2-1.76-.23a2.67 2.67 0 00-2.23 1 4.73 4.73 0 00-.78 2.8zm7.44 5.27c0 1.82-.46 3.16-1.4 4-.94.85-2.37 1.27-4.3 1.27-.7 0-2.17-.13-3.34-.4l.43-2.11c.98.2 2.27.26 2.95.26 1.08 0 1.84-.22 2.3-.66.46-.43.68-1.08.68-1.94v-.44a5.2 5.2 0 01-2.54.6 5.6 5.6 0 01-2.01-.36 4.2 4.2 0 01-2.58-2.71 9.88 9.88 0 01.02-5.35 4.92 4.92 0 012.93-2.96 6.6 6.6 0 012.43-.46 19.64 19.64 0 014.43.66v10.6z"}))))}function us(e){var t=e.cssClasses,n=e.templates,r=e.items;return Kn(ki,{templateKey:"default",templates:n,rootProps:{className:t.root},data:{items:r}})}var ls=st({name:"panel"}),ds=Ft("Panel"),hs=Kn("path",{fill:"#5468FF",d:"M78.99.94h16.6a2.97 2.97 0 012.96 2.96v16.6a2.97 2.97 0 01-2.97 2.96h-16.6a2.97 2.97 0 01-2.96-2.96V3.9A2.96 2.96 0 0179 .94"}),fs=Kn("path",{fill:"#FFF",d:"M89.63 5.97v-.78a.98.98 0 00-.98-.97h-2.28a.98.98 0 00-.97.97V6c0 .09.08.15.17.13a7.13 7.13 0 013.9-.02c.08.02.16-.04.16-.13m-6.25 1L83 6.6a.98.98 0 00-1.38 0l-.46.46a.97.97 0 000 1.38l.38.39c.06.06.15.04.2-.02a7.49 7.49 0 011.63-1.62c.07-.04.08-.14.02-.2m4.16 2.45v3.34c0 .1.1.17.2.12l2.97-1.54c.06-.03.08-.12.05-.18a3.7 3.7 0 00-3.08-1.87c-.07 0-.14.06-.14.13m0 8.05a4.49 4.49 0 110-8.98 4.49 4.49 0 010 8.98m0-10.85a6.37 6.37 0 100 12.74 6.37 6.37 0 000-12.74"}),ms=Ft("PoweredBy"),ps=st({name:"powered-by"}),gs=st({name:"query-rule-context"}),vs={default:function(e){var t=e.items;return JSON.stringify(t,null,2)}},ys=st({name:"query-rule-custom-data"}),bs=Ft("QueryRuleCustomData"),Ss=function(){L(a,Yn);var i=O(a);function a(){var r;C(this,a);for(var e=arguments.length,t=new Array(e),n=0;n=this.props.max}},{key:"computeDefaultPitPoints",value:function(e){var t=e.min,n=e.max,r=(n-t)/34;return[t].concat(P(He({end:33}).map(function(e){return t+r*(e+1)})),[n])}},{key:"computeSnapPoints",value:function(e){var t=e.min,n=e.max,r=e.step;if(r)return[].concat(P(He({start:t,end:n,step:r})),[n])}},{key:"render",value:function(){var e=this.props,t=e.tooltips,n=e.step,r=e.pips,i=e.values,a=e.cssClasses,s=this.isDisabled?{min:this.props.min,max:this.props.max+.001}:this.props,o=s.min,c=s.max,u=this.computeSnapPoints({min:o,max:c,step:n}),l=!1===r?[]:this.computeDefaultPitPoints({min:o,max:c});return Kn("div",{className:Ei(a.root,k({},a.disabledRoot,this.isDisabled))},Kn(Ds,{handle:this.createHandleComponent(t),onChange:this.handleChange,min:o,max:c,pitComponent:Bs,pitPoints:l,snap:!0,snapPoints:u,values:this.isDisabled?[o,c]:i,disabled:this.isDisabled}))}}]),a}(),Ks=st({name:"range-slider"}),zs=Ft("RangeSlider"),Js={item:'{{#count}}{{/count}}{{^count}}{{/count}}'},Ys=st({name:"rating-menu"}),Xs=Ft("RatingMenu"),Gs=Kn("path",{d:"M12 .288l2.833 8.718h9.167l-7.417 5.389 2.833 8.718-7.416-5.388-7.417 5.388 2.833-8.718-7.416-5.389h9.167z"}),Zs=Kn("path",{d:"M12 6.76l1.379 4.246h4.465l-3.612 2.625 1.379 4.246-3.611-2.625-3.612 2.625 1.379-4.246-3.612-2.625h4.465l1.38-4.246zm0-6.472l-2.833 8.718h-9.167l7.416 5.389-2.833 8.718 7.417-5.388 7.416 5.388-2.833-8.718 7.417-5.389h-9.167l-2.833-8.718z"}),eo={reset:'\n\n \n\n ',submit:'\n\n \n\n ',loadingIndicator:'\n\n \n \n \n \n \n \n \n \n\n '},to={item:'',showMoreText:"\n {{#isShowingMore}}\n Show less\n {{/isShowingMore}}\n {{^isShowingMore}}\n Show more\n {{/isShowingMore}}\n ",searchableNoResults:"No results"},no=st({name:"refinement-list"}),ro=Ft("RefinementList"),io=Ft("SearchBox"),ao={text:"",button:function(e){return e.isRelevantSorted?"See all results":"See relevant results"}},so=st({name:"relevant-sort"}),oo=Ft("RelevantSort"),co=st({name:"search-box"}),uo=Ft("SearchBox"),lo=st({name:"sort-by"}),ho=Ft("SortBy"),fo=st({name:"stats"}),mo=Ft("Stats"),po={text:"\n {{#areHitsSorted}}\n {{#hasNoSortedResults}}No relevant results{{/hasNoSortedResults}}\n {{#hasOneSortedResults}}1 relevant result{{/hasOneSortedResults}}\n {{#hasManySortedResults}}{{#helpers.formatNumber}}{{nbSortedHits}}{{/helpers.formatNumber}} relevant results{{/hasManySortedResults}}\n sorted out of {{#helpers.formatNumber}}{{nbHits}}{{/helpers.formatNumber}}\n {{/areHitsSorted}}\n {{^areHitsSorted}}\n {{#hasNoResults}}No results{{/hasNoResults}}\n {{#hasOneResult}}1 result{{/hasOneResult}}\n {{#hasManyResults}}{{#helpers.formatNumber}}{{nbHits}}{{/helpers.formatNumber}} results{{/hasManyResults}}\n {{/areHitsSorted}}\n found in {{processingTimeMS}}ms"},go={labelText:"{{name}}"},vo=st({name:"toggle-refinement"}),yo=Ft("ToggleRefinement"),bo={buttonText:function(e){var t=e.status,n=e.errorCode,r=e.isListening;return'\n '.concat(function(e,t,n){return"error"===e&&"not-allowed"===t?'\n \n \n \n ':'\n \n \n \n ')}(t,n,r),"\n ")},status:"

{{transcript}}

"},So=st({name:"voice-search"}),Ro=Ft("VoiceSearch"),wo=je(Gi),_o=Object.freeze({__proto__:null,dynamicWidgets:Gi,EXPERIMENTAL_dynamicWidgets:wo,analytics:function(e){var t=e||{},s=t.pushFunction,n=t.delay,r=void 0===n?3e3:n,i=t.triggerOnUIInteraction,a=void 0!==i&&i,o=t.pushInitialSearch,c=void 0===o||o,u=t.pushPagination,l=void 0!==u&&u;if(!s)throw new Error(Ci("The `pushFunction` option is required."));function d(e){if(null!==e){var t=[],n=function(e){var t=[];for(var n in e)if(e.hasOwnProperty(n)){var r=e[n].join("+");t.push("".concat(encodeURIComponent(n),"=").concat(encodeURIComponent(n),"_").concat(encodeURIComponent(r)))}return t.join("&")}(W(W(W({},e.state.disjunctiveFacetsRefinements),e.state.facetsRefinements),e.state.hierarchicalFacetsRefinements)),r=function(e){var t=[];for(var n in e)if(e.hasOwnProperty(n)){var r=e[n];if(r.hasOwnProperty(">=")&&r.hasOwnProperty("<="))r[">="]&&r[">="][0]===r["<="]&&r["<="][0]?t.push("".concat(n,"=").concat(n,"_").concat(r[">="])):t.push("".concat(n,"=").concat(n,"_").concat(r[">="],"to").concat(r["<="]));else if(r.hasOwnProperty(">="))t.push("".concat(n,"=").concat(n,"_from").concat(r[">="]));else if(r.hasOwnProperty("<="))t.push("".concat(n,"=").concat(n,"_to").concat(r["<="]));else if(r.hasOwnProperty("=")){var i=[];for(var a in r["="])r["="].hasOwnProperty(a)&&i.push(r["="][a]);t.push("".concat(n,"=").concat(n,"_").concat(i.join("-")))}}return t.join("&")}(e.state.numericRefinements);""!==n&&t.push(n),""!==r&&t.push(r);var i=t.join("&"),a="Query: ".concat(e.state.query||"",", ").concat(i);!0===l&&(a+=", Page: ".concat(e.state.page||0)),m!==a&&(s(i,e.state,e.results),m=a)}}var h,f=null,m="",p=!0;!0===c&&(p=!1);function g(){d(f)}function v(){d(f)}return{$$type:"ais.analytics",$$widgetType:"ais.analytics",init:function(){!0===a&&(document.addEventListener("click",g),window.addEventListener("beforeunload",v))},render:function(e){var t=e.results,n=e.state;!0!==p?(f={results:t,state:n},h&&clearTimeout(h),h=window.setTimeout(function(){return d(f)},r)):p=!1},dispose:function(){!0===a&&(document.removeEventListener("click",g),window.removeEventListener("beforeunload",v))},getRenderState:function(e,t){return W(W({},e),{},{analytics:this.getWidgetRenderState(t)})},getWidgetRenderState:function(){return{widgetParams:e}}}},breadcrumb:function(e){var t=e||{},n=t.container,r=t.attributes,i=t.separator,a=t.rootPath,s=t.transformItems,o=t.templates,c=void 0===o?{}:o,u=t.cssClasses,l=void 0===u?{}:u;if(!n)throw new Error(Wi("The `container` option is required."));var d=ye(n),h={root:Ei(Di(),l.root),noRefinementRoot:Ei(Di({modifierName:"noRefinement"}),l.noRefinementRoot),list:Ei(Di({descendantName:"list"}),l.list),item:Ei(Di({descendantName:"item"}),l.item),selectedItem:Ei(Di({descendantName:"item",modifierName:"selected"}),l.selectedItem),separator:Ei(Di({descendantName:"separator"}),l.separator),link:Ei(Di({descendantName:"link"}),l.link)},f=function(e){var o=e.containerNode,c=e.cssClasses,u=e.renderState,l=e.templates;return function(e,t){var n=e.canRefine,r=e.createURL,i=e.instantSearchInstance,a=e.items,s=e.refine;t?u.templateProps=Re({defaultTemplates:Hi,templatesConfig:i.templatesConfig,templates:l}):fr(Kn(Li,{canRefine:n,cssClasses:c,createURL:r,items:a,refine:s,templateProps:u.templateProps}),o)}}({containerNode:d,cssClasses:h,renderState:{},templates:c});return W(W({},$r(f,function(){return fr(null,d)})({attributes:r,separator:i,rootPath:a,transformItems:s})),{},{$$widgetType:"ais.breadcrumb"})},clearRefinements:function(e){var t=e||{},n=t.container,r=t.templates,i=void 0===r?{}:r,a=t.includedAttributes,s=t.excludedAttributes,o=t.transformItems,c=t.cssClasses,u=void 0===c?{}:c;if(!n)throw new Error(Ui("The `container` option is required."));var l=ye(n),d={root:Ei(qi(),u.root),button:Ei(qi({descendantName:"button"}),u.button),disabledButton:Ei(qi({descendantName:"button",modifierName:"disabled"}),u.disabledButton)},h=function(e){var a=e.containerNode,s=e.cssClasses,o=e.renderState,c=e.templates;return function(e,t){var n=e.refine,r=e.hasRefinements,i=e.instantSearchInstance;t?o.templateProps=Re({defaultTemplates:Bi,templatesConfig:i.templatesConfig,templates:c}):fr(Kn(ji,{refine:n,cssClasses:s,hasRefinements:r,templateProps:o.templateProps}),a)}}({containerNode:l,cssClasses:d,renderState:{},templates:i});return W(W({},Sn(h,function(){return fr(null,l)})({includedAttributes:a,excludedAttributes:s,transformItems:o})),{},{$$widgetType:"ais.clearRefinements"})},configure:function(e){return W(W({},hi(Le)({searchParameters:e})),{},{$$widgetType:"ais.configure"})},currentRefinements:function(e){var t=e||{},n=t.container,r=t.includedAttributes,i=t.excludedAttributes,a=t.cssClasses,s=void 0===a?{}:a,o=t.transformItems;if(!n)throw new Error(Qi("The `container` option is required."));var c=ye(n),u={root:Ei(Vi(),s.root),list:Ei(Vi({descendantName:"list"}),s.list),item:Ei(Vi({descendantName:"item"}),s.item),label:Ei(Vi({descendantName:"label"}),s.label),category:Ei(Vi({descendantName:"category"}),s.category),categoryLabel:Ei(Vi({descendantName:"categoryLabel"}),s.categoryLabel),delete:Ei(Vi({descendantName:"delete"}),s.delete)};return W(W({},_n(Oi,function(){return fr(null,c)})({container:c,cssClasses:u,includedAttributes:r,excludedAttributes:i,transformItems:o})),{},{$$widgetType:"ais.currentRefinements"})},EXPERIMENTAL_answers:function(e){var t=e||{},n=t.container,r=t.attributesForPrediction,i=t.queryLanguages,a=t.nbHits,s=t.searchDebounceTime,o=t.renderDebounceTime,c=t.escapeHTML,u=t.extraParameters,l=t.templates,d=void 0===l?{}:l,h=t.cssClasses,f=void 0===h?{}:h;if(!n)throw new Error(Ki("The `container` option is required."));var m=ye(n),p={root:Ei(zi(),f.root),emptyRoot:Ei(zi({modifierName:"empty"}),f.emptyRoot),header:Ei(zi({descendantName:"header"}),f.header),loader:Ei(zi({descendantName:"loader"}),f.loader),list:Ei(zi({descendantName:"list"}),f.list),item:Ei(zi({descendantName:"item"}),f.item)},g=function(e){var a=e.containerNode,s=e.cssClasses,o=e.renderState,c=e.templates;return function(e,t){var n=e.hits,r=e.isLoading,i=e.instantSearchInstance;t?o.templateProps=Re({defaultTemplates:$i,templatesConfig:i.templatesConfig,templates:c}):fr(Kn(Ai,{cssClasses:s,hits:n,isLoading:r,templateProps:o.templateProps}),a)}}({containerNode:m,cssClasses:p,templates:d,renderState:{}});return W(W({},_i(g,function(){return fr(null,m)})({attributesForPrediction:r,queryLanguages:i,nbHits:a,searchDebounceTime:s,renderDebounceTime:o,escapeHTML:c,extraParameters:u})),{},{$$widgetType:"ais.answers"})},EXPERIMENTAL_configureRelatedItems:function(e){return W(W({},pi(Le)(e)),{},{$$widgetType:"ais.configureRelatedItems"})},geoSearch:function(e){var t=e||{},n=t.initialZoom,r=void 0===n?1:n,i=t.initialPosition,a=void 0===i?{lat:0,lng:0}:i,s=t.templates,o=void 0===s?{}:s,c=t.cssClasses,u=void 0===c?{}:c,l=t.builtInMarker,d=void 0===l?{}:l,h=t.customHTMLMarker,f=t.enableRefine,m=void 0===f||f,p=t.enableClearMapRefinement,g=void 0===p||p,v=t.enableRefineControl,y=void 0===v||v,b=t.container,S=t.googleReference,R=j(t,["initialZoom","initialPosition","templates","cssClasses","builtInMarker","customHTMLMarker","enableRefine","enableClearMapRefinement","enableRefineControl","container","googleReference"]);if(!b)throw new Error(sa("The `container` option is required."));if(!S)throw new Error(sa("The `googleReference` option is required."));var w=ye(b),_={root:Ei(oa(),u.root),tree:oa({descendantName:"tree"}),map:Ei(oa({descendantName:"map"}),u.map),control:Ei(oa({descendantName:"control"}),u.control),label:Ei(oa({descendantName:"label"}),u.label),selectedLabel:Ei(oa({descendantName:"label",modifierName:"selected"}),u.selectedLabel),input:Ei(oa({descendantName:"input"}),u.input),redo:Ei(oa({descendantName:"redo"}),u.redo),disabledRedo:Ei(oa({descendantName:"redo",modifierName:"disabled"}),u.disabledRedo),reset:Ei(oa({descendantName:"reset"}),u.reset)},P=W(W({},aa),o),x=W(W({},{createOptions:function(){return{}},events:{}}),d),N=(Boolean(h)||Boolean(o.HTMLMarker))&&W(W({},{createOptions:function(){return{}},events:{}}),h),I=function(d){return function(){L(l,d.maps.OverlayView);var u=O(l);function l(e){var t,n=e.__id,r=e.position,i=e.map,a=e.template,s=e.className,o=e.anchor,c=void 0===o?{x:0,y:0}:o;return C(this,l),k(M(t=u.call(this)),"__id",void 0),k(M(t),"anchor",void 0),k(M(t),"offset",void 0),k(M(t),"listeners",void 0),k(M(t),"latLng",void 0),k(M(t),"element",void 0),t.__id=n,t.anchor=c,t.listeners={},t.latLng=new d.maps.LatLng(r),t.element=document.createElement("div"),t.element.className=s,t.element.style.position="absolute",t.element.innerHTML=a,t.setMap(i),t}return E(l,[{key:"onAdd",value:function(){this.getPanes().overlayMouseTarget.appendChild(this.element);var e=this.element.getBoundingClientRect();this.offset={x:this.anchor.x+e.width/2,y:this.anchor.y+e.height},this.element.style.width="".concat(e.width,"px")}},{key:"draw",value:function(){var e=this.getProjection().fromLatLngToDivPixel(this.latLng);this.element.style.left="".concat(Math.round(e.x-this.offset.x),"px"),this.element.style.top="".concat(Math.round(e.y-this.offset.y),"px"),this.element.style.zIndex=String(parseInt(this.element.style.top,10))}},{key:"onRemove",value:function(){var t=this;this.element&&(this.element.parentNode.removeChild(this.element),Object.keys(this.listeners).forEach(function(e){t.element.removeEventListener(e,t.listeners[e])}),delete this.element,delete this.listeners)}},{key:"addListener",value:function(e,t){this.listeners[e]=t;var n=this.element;return n.addEventListener(e,t),{remove:function(){return n.removeEventListener(e,t)}}}},{key:"getPosition",value:function(){return this.latLng}}]),l}()}(S),F=N?function(e){var t=e.item,n=j(e,["item"]);return new I(W(W(W({},N.createOptions(t)),n),{},{__id:t.objectID,position:t._geoloc,className:Ei(oa({descendantName:"marker"})),template:Ne({templateKey:"HTMLMarker",templates:P,data:t})}))}:function(e){var t=e.item,n=j(e,["item"]);return new S.maps.Marker(W(W(W({},x.createOptions(t)),n),{},{__id:t.objectID,position:t._geoloc}))},T=N||x;return W(W({},si(ia,function(){return fr(null,w)})(W(W({},R),{},{renderState:{},container:w,googleReference:S,initialZoom:r,initialPosition:a,templates:P,cssClasses:_,createMarker:F,markerOptions:T,enableRefine:m,enableClearMapRefinement:g,enableRefineControl:y}))),{},{$$widgetType:"ais.geoSearch"})},hierarchicalMenu:function(e){var t=e||{},n=t.container,r=t.attributes,i=t.separator,a=t.rootPath,s=t.showParentLevel,o=t.limit,c=t.showMore,u=void 0!==c&&c,l=t.showMoreLimit,d=t.sortBy,h=t.transformItems,f=t.templates,m=void 0===f?{}:f,p=t.cssClasses,g=void 0===p?{}:p;if(!n)throw new Error(ma("The `container` option is required."));var v=ye(n),y=function(e){var u=e.cssClasses,l=e.containerNode,d=e.showMore,h=e.templates,f=e.renderState;return function(e,t){var n=e.createURL,r=e.items,i=e.refine,a=e.instantSearchInstance,s=e.isShowingMore,o=e.toggleShowMore,c=e.canToggleShowMore;t?f.templateProps=Re({defaultTemplates:fa,templatesConfig:a.templatesConfig,templates:h}):fr(Kn(ha,{createURL:n,cssClasses:u,facetValues:r,templateProps:f.templateProps,toggleRefinement:i,showMore:d,toggleShowMore:o,isShowingMore:s,canToggleShowMore:c}),l)}}({cssClasses:{root:Ei(pa(),g.root),noRefinementRoot:Ei(pa({modifierName:"noRefinement"}),g.noRefinementRoot),list:Ei(pa({descendantName:"list"}),g.list),childList:Ei(pa({descendantName:"list",modifierName:"child"}),g.childList),item:Ei(pa({descendantName:"item"}),g.item),selectedItem:Ei(pa({descendantName:"item",modifierName:"selected"}),g.selectedItem),parentItem:Ei(pa({descendantName:"item",modifierName:"parent"}),g.parentItem),link:Ei(pa({descendantName:"link"}),g.link),label:Ei(pa({descendantName:"label"}),g.label),count:Ei(pa({descendantName:"count"}),g.count),showMore:Ei(pa({descendantName:"showMore"}),g.showMore),disabledShowMore:Ei(pa({descendantName:"showMore",modifierName:"disabled"}),g.disabledShowMore)},containerNode:v,templates:m,showMore:u,renderState:{}});return W(W({},Tn(y,function(){return fr(null,v)})({attributes:r,separator:i,rootPath:a,showParentLevel:s,limit:o,showMore:u,showMoreLimit:l,sortBy:d,transformItems:h})),{},{$$widgetType:"ais.hierarchicalMenu"})},hits:function(e){var t=e||{},n=t.container,r=t.escapeHTML,i=t.transformItems,a=t.templates,s=void 0===a?{}:a,o=t.cssClasses,c=void 0===o?{}:o;if(!n)throw new Error(va("The `container` option is required."));var u=ye(n),l={root:Ei(ya(),c.root),emptyRoot:Ei(ya({modifierName:"empty"}),c.emptyRoot),list:Ei(ya({descendantName:"list"}),c.list),item:Ei(ya({descendantName:"item"}),c.item)},d=function(e){var o=e.renderState,c=e.cssClasses,u=e.containerNode,l=e.templates;return function(e,t){var n=e.hits,r=e.results,i=e.instantSearchInstance,a=e.insights,s=e.bindEvent;t?o.templateProps=Re({defaultTemplates:ga,templatesConfig:i.templatesConfig,templates:l}):fr(Kn(ba,{cssClasses:c,hits:n,results:r,templateProps:o.templateProps,insights:a,sendEvent:function(e){i.sendEventToInsights(e)},bindEvent:s}),u)}}({containerNode:u,cssClasses:l,renderState:{},templates:s});return W(W({},Mn(Cn)(d,function(){return fr(null,u)})({escapeHTML:r,transformItems:i})),{},{$$widgetType:"ais.hits"})},hitsPerPage:function(e){var t=e||{},n=t.container,r=t.items,i=t.cssClasses,a=void 0===i?{}:i,s=t.transformItems;if(!n)throw new Error(Ra("The `container` option is required."));var o=ye(n),c={root:Ei(wa(),a.root),select:Ei(wa({descendantName:"select"}),a.select),option:Ei(wa({descendantName:"option"}),a.option)},u=function(e){var a=e.containerNode,s=e.cssClasses;return function(e,t){var n=e.items,r=e.refine;if(!t){var i=(Ie(n,function(e){return e.isRefined})||{}).value;fr(Kn("div",{className:s.root},Kn(Sa,{cssClasses:s,currentValue:i,options:n,setValue:r})),a)}}}({containerNode:o,cssClasses:c});return W(W({},gr(u,function(){return fr(null,o)})({items:r,transformItems:s})),{},{$$widgetType:"ais.hitsPerPage"})},index:Nt,infiniteHits:function(e){var t=e||{},n=t.container,r=t.escapeHTML,i=t.transformItems,a=t.templates,s=void 0===a?{}:a,o=t.cssClasses,c=void 0===o?{}:o,u=t.showPrevious,l=t.cache;if(!n)throw new Error(Pa("The `container` option is required."));var d=ye(n),h={root:Ei(xa(),c.root),emptyRoot:Ei(xa({modifierName:"empty"}),c.emptyRoot),item:Ei(xa({descendantName:"item"}),c.item),list:Ei(xa({descendantName:"list"}),c.list),loadPrevious:Ei(xa({descendantName:"loadPrevious"}),c.loadPrevious),disabledLoadPrevious:Ei(xa({descendantName:"loadPrevious",modifierName:"disabled"}),c.disabledLoadPrevious),loadMore:Ei(xa({descendantName:"loadMore"}),c.loadMore),disabledLoadMore:Ei(xa({descendantName:"loadMore",modifierName:"disabled"}),c.disabledLoadMore)},f=function(e){var d=e.containerNode,h=e.cssClasses,f=e.renderState,m=e.templates,p=e.showPrevious;return function(e,t){var n=e.hits,r=e.results,i=e.showMore,a=e.showPrevious,s=e.isFirstPage,o=e.isLastPage,c=e.instantSearchInstance,u=e.insights,l=e.bindEvent;t?f.templateProps=Re({defaultTemplates:_a,templatesConfig:c.templatesConfig,templates:m}):fr(Kn(Na,{cssClasses:h,hits:n,results:r,hasShowPrevious:p,showPrevious:a,showMore:i,templateProps:f.templateProps,isFirstPage:s,isLastPage:o,insights:u,sendEvent:function(e){c.sendEventToInsights(e)},bindEvent:l}),d)}}({containerNode:d,cssClasses:h,templates:s,showPrevious:u,renderState:{}});return W(W({},Mn(Rr)(f,function(){return fr(null,d)})({escapeHTML:r,transformItems:i,showPrevious:u,cache:l})),{},{$$widgetType:"ais.infiniteHits"})},menu:function(e){var t=e||{},n=t.container,r=t.attribute,i=t.sortBy,a=t.limit,s=t.showMore,o=t.showMoreLimit,c=t.cssClasses,u=void 0===c?{}:c,l=t.templates,d=void 0===l?{}:l,h=t.transformItems;if(!n)throw new Error(Fa("The `container` option is required."));var f=ye(n),m={root:Ei(Ta(),u.root),noRefinementRoot:Ei(Ta({modifierName:"noRefinement"}),u.noRefinementRoot),list:Ei(Ta({descendantName:"list"}),u.list),item:Ei(Ta({descendantName:"item"}),u.item),selectedItem:Ei(Ta({descendantName:"item",modifierName:"selected"}),u.selectedItem),link:Ei(Ta({descendantName:"link"}),u.link),label:Ei(Ta({descendantName:"label"}),u.label),count:Ei(Ta({descendantName:"count"}),u.count),showMore:Ei(Ta({descendantName:"showMore"}),u.showMore),disabledShowMore:Ei(Ta({descendantName:"showMore",modifierName:"disabled"}),u.disabledShowMore)},p=function(e){var l=e.containerNode,d=e.cssClasses,h=e.renderState,f=e.templates,m=e.showMore;return function(e,t){var n=e.refine,r=e.items,i=e.createURL,a=e.instantSearchInstance,s=e.isShowingMore,o=e.toggleShowMore,c=e.canToggleShowMore;if(t)h.templateProps=Re({defaultTemplates:Ia,templatesConfig:a.templatesConfig,templates:f});else{var u=r.map(function(e){return W(W({},e),{},{url:i(e.value)})});fr(Kn(ha,{createURL:i,cssClasses:d,facetValues:u,showMore:m,templateProps:h.templateProps,toggleRefinement:n,toggleShowMore:o,isShowingMore:s,canToggleShowMore:c}),l)}}}({containerNode:f,cssClasses:m,renderState:{},templates:d,showMore:s});return W(W({},wr(p,function(){return fr(null,f)})({attribute:r,limit:a,showMore:s,showMoreLimit:o,sortBy:i,transformItems:h})),{},{$$widgetType:"ais.menu"})},menuSelect:function(e){var t=e||{},n=t.container,r=t.attribute,i=t.sortBy,a=void 0===i?["name:asc"]:i,s=t.limit,o=void 0===s?10:s,c=t.cssClasses,u=void 0===c?{}:c,l=t.templates,d=void 0===l?{}:l,h=t.transformItems;if(!n)throw new Error(ka("The `container` option is required."));var f=ye(n),m={root:Ei(La(),u.root),noRefinementRoot:Ei(La({modifierName:"noRefinement"}),u.noRefinementRoot),select:Ei(La({descendantName:"select"}),u.select),option:Ei(La({descendantName:"option"}),u.option)},p=function(e){var a=e.containerNode,s=e.cssClasses,o=e.renderState,c=e.templates;return function(e,t){var n=e.refine,r=e.items,i=e.instantSearchInstance;t?o.templateProps=Re({defaultTemplates:Ea,templatesConfig:i.templatesConfig,templates:c}):fr(Kn(Ca,{cssClasses:s,items:r,refine:n,templateProps:o.templateProps}),a)}}({containerNode:f,cssClasses:m,renderState:{},templates:d});return W(W({},wr(p,function(){return fr(null,f)})({attribute:r,limit:o,sortBy:a,transformItems:h})),{},{$$widgetType:"ais.menuSelect"})},numericMenu:function(e){var t=e||{},n=t.container,r=t.attribute,i=t.items,a=t.cssClasses,s=void 0===a?{}:a,o=t.templates,c=void 0===o?{}:o,u=t.transformItems;if(!n)throw new Error(Ma("The `container` option is required."));var l=ye(n),d={root:Ei(Oa(),s.root),noRefinementRoot:Ei(Oa({modifierName:"noRefinement"}),s.noRefinementRoot),list:Ei(Oa({descendantName:"list"}),s.list),item:Ei(Oa({descendantName:"item"}),s.item),selectedItem:Ei(Oa({descendantName:"item",modifierName:"selected"}),s.selectedItem),label:Ei(Oa({descendantName:"label"}),s.label),radio:Ei(Oa({descendantName:"radio"}),s.radio),labelText:Ei(Oa({descendantName:"labelText"}),s.labelText)},h=function(e){var s=e.containerNode,o=e.attribute,c=e.cssClasses,u=e.renderState,l=e.templates;return function(e,t){var n=e.createURL,r=e.instantSearchInstance,i=e.refine,a=e.items;t?u.templateProps=Re({defaultTemplates:ja,templatesConfig:r.templatesConfig,templates:l}):fr(Kn(ha,{createURL:n,cssClasses:c,facetValues:a,templateProps:u.templateProps,toggleRefinement:i,attribute:o}),s)}}({containerNode:l,attribute:r,cssClasses:d,renderState:{},templates:c});return W(W({},_r(h,function(){return fr(null,l)})({attribute:r,items:i,transformItems:u})),{},{$$widgetType:"ais.numericMenu"})},pagination:function(e){var t=e||{},n=t.container,r=t.templates,i=void 0===r?{}:r,a=t.cssClasses,s=void 0===a?{}:a,o=t.totalPages,c=t.padding,u=t.showFirst,l=void 0===u||u,d=t.showLast,h=void 0===d||d,f=t.showPrevious,m=void 0===f||f,p=t.showNext,g=void 0===p||p,v=t.scrollTo,y=void 0===v?"body":v;if(!n)throw new Error(qa("The `container` option is required."));var b=ye(n),S=!0===y?"body":y,R=!1!==S&&ye(S),w={root:Ei(Ua(),s.root),noRefinementRoot:Ei(Ua({modifierName:"noRefinement"}),s.noRefinementRoot),list:Ei(Ua({descendantName:"list"}),s.list),item:Ei(Ua({descendantName:"item"}),s.item),firstPageItem:Ei(Ua({descendantName:"item",modifierName:"firstPage"}),s.firstPageItem),lastPageItem:Ei(Ua({descendantName:"item",modifierName:"lastPage"}),s.lastPageItem),previousPageItem:Ei(Ua({descendantName:"item",modifierName:"previousPage"}),s.previousPageItem),nextPageItem:Ei(Ua({descendantName:"item",modifierName:"nextPage"}),s.nextPageItem),pageItem:Ei(Ua({descendantName:"item",modifierName:"page"}),s.pageItem),selectedItem:Ei(Ua({descendantName:"item",modifierName:"selected"}),s.selectedItem),disabledItem:Ei(Ua({descendantName:"item",modifierName:"disabled"}),s.disabledItem),link:Ei(Ua({descendantName:"link"}),s.link)},_=W(W({},Qa),i),P=function(e){var u=e.containerNode,l=e.cssClasses,d=e.templates,h=e.showFirst,f=e.showLast,m=e.showPrevious,p=e.showNext,g=e.scrollToNode;return function(e,t){var n=e.createURL,r=e.currentRefinement,i=e.nbPages,a=e.pages,s=e.isFirstPage,o=e.isLastPage,c=e.refine;if(!t){fr(Kn(Aa,{createURL:n,cssClasses:l,currentPage:r,templates:d,nbPages:i,pages:a,isFirstPage:s,isLastPage:o,setCurrentPage:function(e){c(e),!1!==g&&g.scrollIntoView()},showFirst:h,showLast:f,showPrevious:m,showNext:p}),u)}}}({containerNode:b,cssClasses:w,templates:_,showFirst:l,showLast:h,showPrevious:m,showNext:g,scrollToNode:R});return W(W({},kr(P,function(){return fr(null,b)})({totalPages:o,padding:c})),{},{$$widgetType:"ais.pagination"})},panel:function(e){var t=e||{},n=t.templates,r=void 0===n?{}:n,i=t.hidden,c=void 0===i?function(){return!1}:i,a=t.collapsed,s=t.cssClasses,o=void 0===s?{}:s,u=document.createElement("div"),l=Boolean(a),d="function"==typeof a?a:function(){return!1},h={root:Ei(ds(),o.root),noRefinementRoot:Ei(ds({modifierName:"noRefinement"}),o.noRefinementRoot),collapsibleRoot:Ei(ds({modifierName:"collapsible"}),o.collapsibleRoot),collapsedRoot:Ei(ds({modifierName:"collapsed"}),o.collapsedRoot),collapseButton:Ei(ds({descendantName:"collapseButton"}),o.collapseButton),collapseIcon:Ei(ds({descendantName:"collapseIcon"}),o.collapseIcon),body:Ei(ds({descendantName:"body"}),o.body),header:Ei(ds({descendantName:"header"}),o.header),footer:Ei(ds({descendantName:"footer"}),o.footer)};return function(t){return function(e){if(!e||!e.container)throw new Error(ls("The `container` option is required in the widget within the panel."));var i=ye(e.container),s=function(e){var a=e.containerNode,s=e.bodyContainerNode,o=e.cssClasses,c=e.templates;return function(e){var t=e.options,n=e.hidden,r=e.collapsible,i=e.collapsed;fr(Kn(os,{cssClasses:o,hidden:n,collapsible:r,isCollapsed:i,templates:c,data:t,bodyElement:s}),a)}}({containerNode:i,bodyContainerNode:u,cssClasses:h,templates:W(W({},{header:"",footer:"",collapseButtonText:function(e){var t=e.collapsed;return'\n \n ')}}),r)}),o=t(W(W({},e),{},{container:u}));return W(W({},o),{},{init:function(){for(var e=arguments.length,t=new Array(e),n=0;n { + /* Resolved - text copied to clipboard */ + console.log("Copied: " + URL + " to clipboard."); + popup.style.visibility = "visible"; + setTimeout(function () { + popup.style.visibility = "hidden"; + }, 2000); + + },() => { + /* Rejected - clipboard failed */ + console.log("Couldn't copy " + URL + " to clipboard"); + }); +} diff --git a/static/js/quick-search.js b/static/js/quick-search.js new file mode 100644 index 0000000..18b134f --- /dev/null +++ b/static/js/quick-search.js @@ -0,0 +1,98 @@ +/** +Quick Search +================================================================================ +This file's main focus is to provide the functionality for the 'quick search' +bar feature, which is available across the site. The search features are +provided by Meilisearch. Use the links below for more information. + +For more information on Meilisearch, use: + +- https://docs.meilisearch.com/ +- https://github.com/meilisearch/instant-meilisearch + +Meilisearch provides an 'InstantSearch' add-on (plug-in?) which links the +Meilisearch instance you have running to this website (link above for more +information). +*/ + +// let server = ""; +let apiKey = ""; + +if (location.hostname === "localhost" + || location.hostname === "127.0.0.1") { + apiKey= "meilisearch-beta-key"; +} else { + apiKey = "meilisearch-key"; +} + +const search = instantsearch({ + indexName: "nera", + searchClient: instantMeiliSearch( + server, + apiKey, + { + primaryKey: 'id', + } + ) +}); + +search.addWidgets([ + instantsearch.widgets.searchBox({ + container: "#searchbox", + autofocus: false, + placeholder: "Quick Search...", + }), + instantsearch.widgets.configure({ hitsPerPage: 8 }), + instantsearch.widgets.hits({ + container: "#hits", + templates: { + item: ` + + +{{#helpers.highlight}}{"attribute": "title"}{{/helpers.highlight}} + + ` + } + }) +]); + +search.start(); + +const searchBox = + document.querySelector(".ais-SearchBox-input"); + +const searchResultsBox = + document.getElementById('hits'); + +const searchResultsList = + document.querySelector(".ais-Hits-list"); + +searchBox.addEventListener("keydown", showSearchResults); + +document.onmousedown = () => { + if (document.activeElement !== searchBox) { + hideSearchResults(); + } +}; + +function showSearchResults() { + document.getElementById('hits').style.display = 'block'; + document.onkeydown = (evt) => { + if (evt.keyCode === 9) { + searchResultsBox.focus(); + } + if (evt.keyCode === 27) { + searchBox.blur(); + hideSearchResults(); + } + }; + document.onkeyup = (evt) => { + if (searchBox.value.length == 0) { + hideSearchResults(); + } + }; +} + +function hideSearchResults() { + document.getElementById('hits').style.display = 'none'; +} diff --git a/static/js/tinymce/icons/default/icons.min.js b/static/js/tinymce/icons/default/icons.min.js new file mode 100644 index 0000000..1acc76f --- /dev/null +++ b/static/js/tinymce/icons/default/icons.min.js @@ -0,0 +1 @@ +tinymce.IconManager.add("default",{icons:{"accessibility-check":'',"action-next":'',"action-prev":'',addtag:'',"align-center":'',"align-justify":'',"align-left":'',"align-none":'',"align-right":'',"arrow-left":'',"arrow-right":'',bold:'',bookmark:'',"border-style":'',"border-width":'',brightness:'',browse:'',cancel:'',"cell-background-color":'',"cell-border-color":'',"change-case":'',"character-count":'',"checklist-rtl":'',checklist:'',checkmark:'',"chevron-down":'',"chevron-left":'',"chevron-right":'',"chevron-up":'',close:'',"code-sample":'',"color-levels":'',"color-picker":'',"color-swatch-remove-color":'',"color-swatch":'',"comment-add":'',comment:'',contrast:'',copy:'',crop:'',"cut-column":'',"cut-row":'',cut:'',"document-properties":'',drag:'',"duplicate-column":'',"duplicate-row":'',duplicate:'',"edit-block":'',"edit-image":'',"embed-page":'',embed:'',emoji:'',export:'',fill:'',"flip-horizontally":'',"flip-vertically":'',footnote:'',"format-painter":'',format:'',fullscreen:'',gallery:'',gamma:'',help:'',"highlight-bg-color":'',home:'',"horizontal-rule":'',"image-options":'',image:'',indent:'',info:'',"insert-character":'',"insert-time":'',invert:'',italic:'',language:'',"line-height":'',line:'',link:'',"list-bull-circle":'',"list-bull-default":'',"list-bull-square":'',"list-num-default-rtl":'',"list-num-default":'',"list-num-lower-alpha-rtl":'',"list-num-lower-alpha":'',"list-num-lower-greek-rtl":'',"list-num-lower-greek":'',"list-num-lower-roman-rtl":'',"list-num-lower-roman":'',"list-num-upper-alpha-rtl":'',"list-num-upper-alpha":'',"list-num-upper-roman-rtl":'',"list-num-upper-roman":'',lock:'',ltr:'',"more-drawer":'',"new-document":'',"new-tab":'',"non-breaking":'',notice:'',"ordered-list-rtl":'',"ordered-list":'',orientation:'',outdent:'',"page-break":'',paragraph:'',"paste-column-after":'',"paste-column-before":'',"paste-row-after":'',"paste-row-before":'',"paste-text":'',paste:'',"permanent-pen":'',plus:'',preferences:'',preview:'',print:'',quote:'',redo:'',reload:'',"remove-formatting":'',remove:'',"resize-handle":'',resize:'',"restore-draft":'',"rotate-left":'',"rotate-right":'',rtl:'',save:'',search:'',"select-all":'',selected:'',settings:'',sharpen:'',sourcecode:'',"spell-check":'',"strike-through":'',subscript:'',superscript:'',"table-caption":'',"table-cell-classes":'',"table-cell-properties":'',"table-cell-select-all":'',"table-cell-select-inner":'',"table-classes":'',"table-delete-column":'',"table-delete-row":'',"table-delete-table":'',"table-insert-column-after":'',"table-insert-column-before":'',"table-insert-row-above":'',"table-insert-row-after":'',"table-left-header":'',"table-merge-cells":'',"table-row-numbering-rtl":'',"table-row-numbering":'',"table-row-properties":'',"table-split-cells":'',"table-top-header":'',table:'',template:'',"temporary-placeholder":'',"text-color":'',toc:'',translate:'',underline:'',undo:'',unlink:'',unlock:'',"unordered-list":'',unselected:'',upload:'',user:'',"vertical-align":'',visualblocks:'',visualchars:'',warning:'',"zoom-in":'',"zoom-out":''}}); \ No newline at end of file diff --git a/static/js/tinymce/langs/README.md b/static/js/tinymce/langs/README.md new file mode 100644 index 0000000..a52bf03 --- /dev/null +++ b/static/js/tinymce/langs/README.md @@ -0,0 +1,3 @@ +This is where language files should be placed. + +Please DO NOT translate these directly use this service: https://www.transifex.com/projects/p/tinymce/ diff --git a/static/js/tinymce/license.txt b/static/js/tinymce/license.txt new file mode 100644 index 0000000..3a49f66 --- /dev/null +++ b/static/js/tinymce/license.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Ephox Corporation DBA Tiny Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/static/js/tinymce/models/dom/model.min.js b/static/js/tinymce/models/dom/model.min.js new file mode 100644 index 0000000..e8fef1e --- /dev/null +++ b/static/js/tinymce/models/dom/model.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.2.0 (2022-09-08) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.ModelManager");const t=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(o=n=e,(r=String).prototype.isPrototypeOf(o)||(null===(s=n.constructor)||void 0===s?void 0:s.name)===r.name)?"string":t;var o,n,r,s})(t)===e,o=e=>t=>typeof t===e,n=e=>t=>e===t,r=t("string"),s=t("object"),l=t("array"),a=n(null),c=o("boolean"),i=n(void 0),m=e=>!(e=>null==e)(e),d=o("function"),u=o("number"),f=()=>{},g=e=>()=>e,h=e=>e,p=(e,t)=>e===t;function w(e,...t){return(...o)=>{const n=t.concat(o);return e.apply(null,n)}}const b=e=>t=>!e(t),v=e=>e(),y=g(!1),x=g(!0);class C{constructor(e,t){this.tag=e,this.value=t}static some(e){return new C(!0,e)}static none(){return C.singletonNone}fold(e,t){return this.tag?t(this.value):e()}isSome(){return this.tag}isNone(){return!this.tag}map(e){return this.tag?C.some(e(this.value)):C.none()}bind(e){return this.tag?e(this.value):C.none()}exists(e){return this.tag&&e(this.value)}forall(e){return!this.tag||e(this.value)}filter(e){return!this.tag||e(this.value)?this:C.none()}getOr(e){return this.tag?this.value:e}or(e){return this.tag?this:e}getOrThunk(e){return this.tag?this.value:e()}orThunk(e){return this.tag?this:e()}getOrDie(e){if(this.tag)return this.value;throw new Error(null!=e?e:"Called getOrDie on None")}static from(e){return m(e)?C.some(e):C.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(e){this.tag&&e(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}C.singletonNone=new C(!1);const S=Array.prototype.slice,T=Array.prototype.indexOf,R=Array.prototype.push,D=(e,t)=>{return o=e,n=t,T.call(o,n)>-1;var o,n},O=(e,t)=>{for(let o=0,n=e.length;o{const o=[];for(let n=0;n{const o=e.length,n=new Array(o);for(let r=0;r{for(let o=0,n=e.length;o{const o=[],n=[];for(let r=0,s=e.length;r{const o=[];for(let n=0,r=e.length;n(((e,t)=>{for(let o=e.length-1;o>=0;o--)t(e[o],o)})(e,((e,n)=>{o=t(o,e,n)})),o),W=(e,t,o)=>(N(e,((e,n)=>{o=t(o,e,n)})),o),L=(e,t)=>((e,t,o)=>{for(let n=0,r=e.length;n{for(let o=0,n=e.length;o{const t=[];for(let o=0,n=e.length;oM(E(e,t)),I=(e,t)=>{for(let o=0,n=e.length;o{const o={};for(let n=0,r=e.length;nt>=0&&tF(e,0),q=e=>F(e,e.length-1),V=(e,t)=>{for(let o=0;o{const o=$(e);for(let n=0,r=o.length;nY(e,((e,o)=>({k:o,v:t(e,o)}))),Y=(e,t)=>{const o={};return G(e,((e,n)=>{const r=t(e,n);o[r.k]=r.v})),o},J=(e,t)=>{const o=[];return G(e,((e,n)=>{o.push(t(e,n))})),o},Q=e=>J(e,h),X=(e,t)=>U.call(e,t);"undefined"!=typeof window?window:Function("return this;")();const Z=e=>e.dom.nodeName.toLowerCase(),ee=e=>e.dom.nodeType,te=e=>t=>ee(t)===e,oe=e=>8===ee(e)||"#comment"===Z(e),ne=te(1),re=te(3),se=te(9),le=te(11),ae=e=>t=>ne(t)&&Z(t)===e,ce=(e,t,o)=>{if(!(r(o)||c(o)||u(o)))throw console.error("Invalid call to Attribute.set. Key ",t,":: Value ",o,":: Element ",e),new Error("Attribute value was not simple");e.setAttribute(t,o+"")},ie=(e,t,o)=>{ce(e.dom,t,o)},me=(e,t)=>{const o=e.dom;G(t,((e,t)=>{ce(o,t,e)}))},de=(e,t)=>{const o=e.dom.getAttribute(t);return null===o?void 0:o},ue=(e,t)=>C.from(de(e,t)),fe=(e,t)=>{e.dom.removeAttribute(t)},ge=e=>W(e.dom.attributes,((e,t)=>(e[t.name]=t.value,e)),{}),he=e=>{if(null==e)throw new Error("Node cannot be null or undefined");return{dom:e}},pe={fromHtml:(e,t)=>{const o=(t||document).createElement("div");if(o.innerHTML=e,!o.hasChildNodes()||o.childNodes.length>1){const t="HTML does not have a single root node";throw console.error(t,e),new Error(t)}return he(o.childNodes[0])},fromTag:(e,t)=>{const o=(t||document).createElement(e);return he(o)},fromText:(e,t)=>{const o=(t||document).createTextNode(e);return he(o)},fromDom:he,fromPoint:(e,t,o)=>C.from(e.dom.elementFromPoint(t,o)).map(he)},we=(e,t)=>{const o=e.dom;if(1!==o.nodeType)return!1;{const e=o;if(void 0!==e.matches)return e.matches(t);if(void 0!==e.msMatchesSelector)return e.msMatchesSelector(t);if(void 0!==e.webkitMatchesSelector)return e.webkitMatchesSelector(t);if(void 0!==e.mozMatchesSelector)return e.mozMatchesSelector(t);throw new Error("Browser lacks native selectors")}},be=e=>1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType||0===e.childElementCount,ve=(e,t)=>{const o=void 0===t?document:t.dom;return be(o)?C.none():C.from(o.querySelector(e)).map(pe.fromDom)},ye=(e,t)=>e.dom===t.dom,xe=(e,t)=>{const o=e.dom,n=t.dom;return o!==n&&o.contains(n)},Ce=we,Se=e=>pe.fromDom(e.dom.ownerDocument),Te=e=>se(e)?e:Se(e),Re=e=>C.from(e.dom.parentNode).map(pe.fromDom),De=(e,t)=>{const o=d(t)?t:y;let n=e.dom;const r=[];for(;null!==n.parentNode&&void 0!==n.parentNode;){const e=n.parentNode,t=pe.fromDom(e);if(r.push(t),!0===o(t))break;n=e}return r},Oe=e=>C.from(e.dom.previousSibling).map(pe.fromDom),ke=e=>C.from(e.dom.nextSibling).map(pe.fromDom),Ee=e=>E(e.dom.childNodes,pe.fromDom),Ne=(e,t)=>{const o=e.dom.childNodes;return C.from(o[t]).map(pe.fromDom)},Be=(e,t)=>{Re(e).each((o=>{o.dom.insertBefore(t.dom,e.dom)}))},ze=(e,t)=>{ke(e).fold((()=>{Re(e).each((e=>{We(e,t)}))}),(e=>{Be(e,t)}))},Ae=(e,t)=>{const o=(e=>Ne(e,0))(e);o.fold((()=>{We(e,t)}),(o=>{e.dom.insertBefore(t.dom,o.dom)}))},We=(e,t)=>{e.dom.appendChild(t.dom)},Le=(e,t)=>{Be(e,t),We(t,e)},_e=(e,t)=>{N(t,((o,n)=>{const r=0===n?e:t[n-1];ze(r,o)}))},Me=(e,t)=>{N(t,(t=>{We(e,t)}))},je=e=>{e.dom.textContent="",N(Ee(e),(e=>{Ie(e)}))},Ie=e=>{const t=e.dom;null!==t.parentNode&&t.parentNode.removeChild(t)},Pe=e=>{const t=Ee(e);t.length>0&&_e(e,t),Ie(e)},Fe=(e,t)=>pe.fromDom(e.dom.cloneNode(t)),He=e=>Fe(e,!1),qe=e=>Fe(e,!0),Ve=(e,t)=>{const o=pe.fromTag(t),n=ge(e);return me(o,n),o},$e=["tfoot","thead","tbody","colgroup"],Ue=(e,t,o)=>({element:e,rowspan:t,colspan:o}),Ge=(e,t,o)=>({element:e,cells:t,section:o}),Ke=(e,t,o)=>({element:e,isNew:t,isLocked:o}),Ye=(e,t,o,n)=>({element:e,cells:t,section:o,isNew:n}),Je=d(Element.prototype.attachShadow)&&d(Node.prototype.getRootNode),Qe=g(Je),Xe=Je?e=>pe.fromDom(e.dom.getRootNode()):Te,Ze=e=>pe.fromDom(e.dom.host),et=e=>{const t=re(e)?e.dom.parentNode:e.dom;if(null==t||null===t.ownerDocument)return!1;const o=t.ownerDocument;return(e=>{const t=Xe(e);return le(o=t)&&m(o.dom.host)?C.some(t):C.none();var o})(pe.fromDom(t)).fold((()=>o.body.contains(t)),(n=et,r=Ze,e=>n(r(e))));var n,r},tt=e=>{const t=e.dom.body;if(null==t)throw new Error("Body is not available yet");return pe.fromDom(t)},ot=(e,t)=>{let o=[];return N(Ee(e),(e=>{t(e)&&(o=o.concat([e])),o=o.concat(ot(e,t))})),o},nt=(e,t,o)=>((e,o,n)=>z(De(e,n),(e=>we(e,t))))(e,0,o),rt=(e,t)=>((e,o)=>z(Ee(e),(e=>we(e,t))))(e),st=(e,t)=>((e,t)=>{const o=void 0===t?document:t.dom;return be(o)?[]:E(o.querySelectorAll(e),pe.fromDom)})(t,e);var lt=(e,t,o,n,r)=>e(o,n)?C.some(o):d(r)&&r(o)?C.none():t(o,n,r);const at=(e,t,o)=>{let n=e.dom;const r=d(o)?o:y;for(;n.parentNode;){n=n.parentNode;const e=pe.fromDom(n);if(t(e))return C.some(e);if(r(e))break}return C.none()},ct=(e,t,o)=>at(e,(e=>we(e,t)),o),it=(e,t)=>((e,o)=>L(e.dom.childNodes,(e=>{return o=pe.fromDom(e),we(o,t);var o})).map(pe.fromDom))(e),mt=(e,t)=>ve(t,e),dt=(e,t,o)=>lt(((e,t)=>we(e,t)),ct,e,t,o),ut=(e,t,o=p)=>e.exists((e=>o(e,t))),ft=e=>{const t=[],o=e=>{t.push(e)};for(let t=0;te?C.some(t):C.none(),ht=(e,t,o)=>""===t||e.length>=t.length&&e.substr(o,o+t.length)===t,pt=(e,t,o=0,n)=>{const r=e.indexOf(t,o);return-1!==r&&(!!i(n)||r+t.length<=n)},wt=(e,t)=>ht(e,t,0),bt=(e,t)=>ht(e,t,e.length-t.length),vt=(e=>t=>t.replace(e,""))(/^\s+|\s+$/g),yt=e=>e.length>0,xt=e=>void 0!==e.style&&d(e.style.getPropertyValue),Ct=(e,t,o)=>{if(!r(o))throw console.error("Invalid call to CSS.set. Property ",t,":: Value ",o,":: Element ",e),new Error("CSS value must be a string: "+o);xt(e)&&e.style.setProperty(t,o)},St=(e,t,o)=>{const n=e.dom;Ct(n,t,o)},Tt=(e,t)=>{const o=e.dom;G(t,((e,t)=>{Ct(o,t,e)}))},Rt=(e,t)=>{const o=e.dom,n=window.getComputedStyle(o).getPropertyValue(t);return""!==n||et(e)?n:Dt(o,t)},Dt=(e,t)=>xt(e)?e.style.getPropertyValue(t):"",Ot=(e,t)=>{const o=e.dom,n=Dt(o,t);return C.from(n).filter((e=>e.length>0))},kt=(e,t)=>{((e,t)=>{xt(e)&&e.style.removeProperty(t)})(e.dom,t),ut(ue(e,"style").map(vt),"")&&fe(e,"style")},Et=(e,t,o=0)=>ue(e,t).map((e=>parseInt(e,10))).getOr(o),Nt=(e,t)=>Et(e,t,1),Bt=e=>ae("col")(e)?Et(e,"span",1)>1:Nt(e,"colspan")>1,zt=e=>Nt(e,"rowspan")>1,At=(e,t)=>parseInt(Rt(e,t),10),Wt=g(10),Lt=g(10),_t=(e,t)=>Mt(e,t,x),Mt=(e,t,o)=>j(Ee(e),(e=>we(e,t)?o(e)?[e]:[]:Mt(e,t,o))),jt=(e,t)=>((e,t,o=y)=>o(t)?C.none():D(e,Z(t))?C.some(t):ct(t,e.join(","),(e=>we(e,"table")||o(e))))(["td","th"],e,t),It=e=>_t(e,"th,td"),Pt=e=>we(e,"colgroup")?rt(e,"col"):j(qt(e),(e=>rt(e,"col"))),Ft=(e,t)=>dt(e,"table",t),Ht=e=>_t(e,"tr"),qt=e=>Ft(e).fold(g([]),(e=>rt(e,"colgroup"))),Vt=(e,t)=>E(e,(e=>{if("colgroup"===Z(e)){const t=E(Pt(e),(e=>{const t=Et(e,"span",1);return Ue(e,1,t)}));return Ge(e,t,"colgroup")}{const o=E(It(e),(e=>{const t=Et(e,"rowspan",1),o=Et(e,"colspan",1);return Ue(e,t,o)}));return Ge(e,o,t(e))}})),$t=e=>Re(e).map((e=>{const t=Z(e);return(e=>D($e,e))(t)?t:"tbody"})).getOr("tbody"),Ut=e=>{const t=Ht(e),o=[...qt(e),...t];return Vt(o,$t)},Gt=e=>{let t,o=!1;return(...n)=>(o||(o=!0,t=e.apply(null,n)),t)},Kt=()=>Yt(0,0),Yt=(e,t)=>({major:e,minor:t}),Jt={nu:Yt,detect:(e,t)=>{const o=String(t).toLowerCase();return 0===e.length?Kt():((e,t)=>{const o=((e,t)=>{for(let o=0;oNumber(t.replace(o,"$"+e));return Yt(n(1),n(2))})(e,o)},unknown:Kt},Qt=(e,t)=>{const o=String(t).toLowerCase();return L(e,(e=>e.search(o)))},Xt=/.*?version\/\ ?([0-9]+)\.([0-9]+).*/,Zt=e=>t=>pt(t,e),eo=[{name:"Edge",versionRegexes:[/.*?edge\/ ?([0-9]+)\.([0-9]+)$/],search:e=>pt(e,"edge/")&&pt(e,"chrome")&&pt(e,"safari")&&pt(e,"applewebkit")},{name:"Chromium",brand:"Chromium",versionRegexes:[/.*?chrome\/([0-9]+)\.([0-9]+).*/,Xt],search:e=>pt(e,"chrome")&&!pt(e,"chromeframe")},{name:"IE",versionRegexes:[/.*?msie\ ?([0-9]+)\.([0-9]+).*/,/.*?rv:([0-9]+)\.([0-9]+).*/],search:e=>pt(e,"msie")||pt(e,"trident")},{name:"Opera",versionRegexes:[Xt,/.*?opera\/([0-9]+)\.([0-9]+).*/],search:Zt("opera")},{name:"Firefox",versionRegexes:[/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/],search:Zt("firefox")},{name:"Safari",versionRegexes:[Xt,/.*?cpu os ([0-9]+)_([0-9]+).*/],search:e=>(pt(e,"safari")||pt(e,"mobile/"))&&pt(e,"applewebkit")}],to=[{name:"Windows",search:Zt("win"),versionRegexes:[/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/]},{name:"iOS",search:e=>pt(e,"iphone")||pt(e,"ipad"),versionRegexes:[/.*?version\/\ ?([0-9]+)\.([0-9]+).*/,/.*cpu os ([0-9]+)_([0-9]+).*/,/.*cpu iphone os ([0-9]+)_([0-9]+).*/]},{name:"Android",search:Zt("android"),versionRegexes:[/.*?android\ ?([0-9]+)\.([0-9]+).*/]},{name:"macOS",search:Zt("mac os x"),versionRegexes:[/.*?mac\ os\ x\ ?([0-9]+)_([0-9]+).*/]},{name:"Linux",search:Zt("linux"),versionRegexes:[]},{name:"Solaris",search:Zt("sunos"),versionRegexes:[]},{name:"FreeBSD",search:Zt("freebsd"),versionRegexes:[]},{name:"ChromeOS",search:Zt("cros"),versionRegexes:[/.*?chrome\/([0-9]+)\.([0-9]+).*/]}],oo={browsers:g(eo),oses:g(to)},no="Edge",ro="Chromium",so="Opera",lo="Firefox",ao="Safari",co=e=>{const t=e.current,o=e.version,n=e=>()=>t===e;return{current:t,version:o,isEdge:n(no),isChromium:n(ro),isIE:n("IE"),isOpera:n(so),isFirefox:n(lo),isSafari:n(ao)}},io=()=>co({current:void 0,version:Jt.unknown()}),mo=co,uo=(g(no),g(ro),g("IE"),g(so),g(lo),g(ao),"Windows"),fo="Android",go="Linux",ho="macOS",po="Solaris",wo="FreeBSD",bo="ChromeOS",vo=e=>{const t=e.current,o=e.version,n=e=>()=>t===e;return{current:t,version:o,isWindows:n(uo),isiOS:n("iOS"),isAndroid:n(fo),isMacOS:n(ho),isLinux:n(go),isSolaris:n(po),isFreeBSD:n(wo),isChromeOS:n(bo)}},yo=()=>vo({current:void 0,version:Jt.unknown()}),xo=vo,Co=(g(uo),g("iOS"),g(fo),g(go),g(ho),g(po),g(wo),g(bo),e=>window.matchMedia(e).matches);let So=Gt((()=>((e,t,o)=>{const n=oo.browsers(),r=oo.oses(),s=t.bind((e=>((e,t)=>V(t.brands,(t=>{const o=t.brand.toLowerCase();return L(e,(e=>{var t;return o===(null===(t=e.brand)||void 0===t?void 0:t.toLowerCase())})).map((e=>({current:e.name,version:Jt.nu(parseInt(t.version,10),0)})))})))(n,e))).orThunk((()=>((e,t)=>Qt(e,t).map((e=>{const o=Jt.detect(e.versionRegexes,t);return{current:e.name,version:o}})))(n,e))).fold(io,mo),l=((e,t)=>Qt(e,t).map((e=>{const o=Jt.detect(e.versionRegexes,t);return{current:e.name,version:o}})))(r,e).fold(yo,xo),a=((e,t,o,n)=>{const r=e.isiOS()&&!0===/ipad/i.test(o),s=e.isiOS()&&!r,l=e.isiOS()||e.isAndroid(),a=l||n("(pointer:coarse)"),c=r||!s&&l&&n("(min-device-width:768px)"),i=s||l&&!c,m=t.isSafari()&&e.isiOS()&&!1===/safari/i.test(o),d=!i&&!c&&!m;return{isiPad:g(r),isiPhone:g(s),isTablet:g(c),isPhone:g(i),isTouch:g(a),isAndroid:e.isAndroid,isiOS:e.isiOS,isWebView:g(m),isDesktop:g(d)}})(l,s,e,o);return{browser:s,os:l,deviceType:a}})(navigator.userAgent,C.from(navigator.userAgentData),Co)));const To=()=>So(),Ro=(e,t)=>{const o=o=>{const n=t(o);if(n<=0||null===n){const t=Rt(o,e);return parseFloat(t)||0}return n},n=(e,t)=>W(t,((t,o)=>{const n=Rt(e,o),r=void 0===n?0:parseInt(n,10);return isNaN(r)?t:t+r}),0);return{set:(t,o)=>{if(!u(o)&&!o.match(/^[0-9]+$/))throw new Error(e+".set accepts only positive integer values. Value was "+o);const n=t.dom;xt(n)&&(n.style[e]=o+"px")},get:o,getOuter:o,aggregate:n,max:(e,t,o)=>{const r=n(e,o);return t>r?t-r:0}}},Do=(e,t,o)=>((e,t)=>(e=>{const t=parseFloat(e);return isNaN(t)?C.none():C.some(t)})(e).getOr(t))(Rt(e,t),o),Oo=Ro("width",(e=>e.dom.offsetWidth)),ko=e=>Oo.get(e),Eo=e=>Oo.getOuter(e),No=e=>((e,t)=>{const o=e.dom,n=o.getBoundingClientRect().width||o.offsetWidth;return"border-box"===t?n:((e,t,o,n)=>t-Do(e,"padding-left",0)-Do(e,"padding-right",0)-Do(e,"border-left-width",0)-Do(e,"border-right-width",0))(e,n)})(e,"content-box"),Bo=(e,t,o)=>{const n=e.cells,r=n.slice(0,t),s=n.slice(t),l=r.concat(o).concat(s);return Wo(e,l)},zo=(e,t,o)=>Bo(e,t,[o]),Ao=(e,t,o)=>{e.cells[t]=o},Wo=(e,t)=>Ye(e.element,t,e.section,e.isNew),Lo=(e,t)=>e.cells[t],_o=(e,t)=>Lo(e,t).element,Mo=e=>e.cells.length,jo=e=>{const t=B(e,(e=>"colgroup"===e.section));return{rows:t.fail,cols:t.pass}},Io=(e,t,o)=>{const n=E(e.cells,o);return Ye(t(e.element),n,e.section,!0)},Po="data-snooker-locked-cols",Fo=e=>ue(e,Po).bind((e=>C.from(e.match(/\d+/g)))).map((e=>P(e,x))),Ho=e=>{const t=W(jo(e).rows,((e,t)=>(N(t.cells,((t,o)=>{t.isLocked&&(e[o]=!0)})),e)),{}),o=J(t,((e,t)=>parseInt(t,10)));return((e,t)=>{const o=S.call(e,0);return o.sort(void 0),o})(o)},qo=(e,t)=>e+","+t,Vo=(e,t)=>{const o=j(e.all,(e=>e.cells));return z(o,t)},$o=e=>{const t={},o=[],n=H(e).map((e=>e.element)).bind(Ft).bind(Fo).getOr({});let r=0,s=0,l=0;const{pass:a,fail:c}=B(e,(e=>"colgroup"===e.section));N(c,(e=>{const a=[];N(e.cells,(e=>{let o=0;for(;void 0!==t[qo(l,o)];)o++;const r=((e,t)=>X(e,t)&&void 0!==e[t]&&null!==e[t])(n,o.toString()),c=((e,t,o,n,r,s)=>({element:e,rowspan:t,colspan:o,row:n,column:r,isLocked:s}))(e.element,e.rowspan,e.colspan,l,o,r);for(let n=0;n{const t=(e=>{const t={};let o=0;return N(e.cells,(e=>{const n=e.colspan;k(n,(r=>{const s=o+r;t[s]=((e,t,o)=>({element:e,colspan:t,column:o}))(e.element,n,s)})),o+=n})),t})(e),o=((e,t)=>({element:e,columns:t}))(e.element,Q(t));return{colgroups:[o],columns:t}})).getOrThunk((()=>({colgroups:[],columns:{}}))),d=((e,t)=>({rows:e,columns:t}))(r,s);return{grid:d,access:t,all:o,columns:i,colgroups:m}},Uo=e=>{const t=Ut(e);return $o(t)},Go=$o,Ko=(e,t,o)=>C.from(e.access[qo(t,o)]),Yo=(e,t,o)=>{const n=Vo(e,(e=>o(t,e.element)));return n.length>0?C.some(n[0]):C.none()},Jo=Vo,Qo=e=>j(e.all,(e=>e.cells)),Xo=e=>Q(e.columns),Zo=e=>$(e.columns).length>0,en=(e,t)=>C.from(e.columns[t]),tn=(e,t=x)=>{const o=e.grid,n=k(o.columns,h),r=k(o.rows,h);return E(n,(o=>on((()=>j(r,(t=>Ko(e,t,o).filter((e=>e.column===o)).toArray()))),(e=>1===e.colspan&&t(e.element)),(()=>Ko(e,0,o)))))},on=(e,t,o)=>{const n=e();return L(n,t).orThunk((()=>C.from(n[0]).orThunk(o))).map((e=>e.element))},nn=e=>{const t=e.grid,o=k(t.rows,h),n=k(t.columns,h);return E(o,(t=>on((()=>j(n,(o=>Ko(e,t,o).filter((e=>e.row===t)).fold(g([]),(e=>[e]))))),(e=>1===e.rowspan),(()=>Ko(e,t,0)))))},rn=(e,t)=>o=>"rtl"===sn(o)?t:e,sn=e=>"rtl"===Rt(e,"direction")?"rtl":"ltr",ln=Ro("height",(e=>{const t=e.dom;return et(e)?t.getBoundingClientRect().height:t.offsetHeight})),an=e=>ln.get(e),cn=e=>ln.getOuter(e),mn=(e,t)=>({left:e,top:t,translate:(o,n)=>mn(e+o,t+n)}),dn=mn,un=(e,t)=>void 0!==e?e:void 0!==t?t:0,fn=e=>{const t=e.dom.ownerDocument,o=t.body,n=t.defaultView,r=t.documentElement;if(o===e.dom)return dn(o.offsetLeft,o.offsetTop);const s=un(null==n?void 0:n.pageYOffset,r.scrollTop),l=un(null==n?void 0:n.pageXOffset,r.scrollLeft),a=un(r.clientTop,o.clientTop),c=un(r.clientLeft,o.clientLeft);return gn(e).translate(l-c,s-a)},gn=e=>{const t=e.dom,o=t.ownerDocument.body;return o===t?dn(o.offsetLeft,o.offsetTop):et(e)?(e=>{const t=e.getBoundingClientRect();return dn(t.left,t.top)})(t):dn(0,0)},hn=(e,t)=>({row:e,y:t}),pn=(e,t)=>({col:e,x:t}),wn=e=>fn(e).left+Eo(e),bn=e=>fn(e).left,vn=(e,t)=>pn(e,bn(t)),yn=(e,t)=>pn(e,wn(t)),xn=e=>fn(e).top,Cn=(e,t)=>hn(e,xn(t)),Sn=(e,t)=>hn(e,xn(t)+cn(t)),Tn=(e,t,o)=>{if(0===o.length)return[];const n=E(o.slice(1),((t,o)=>t.map((t=>e(o,t))))),r=o[o.length-1].map((e=>t(o.length-1,e)));return n.concat([r])},Rn={delta:h,positions:e=>Tn(Cn,Sn,e),edge:xn},Dn=rn({delta:h,edge:bn,positions:e=>Tn(vn,yn,e)},{delta:e=>-e,edge:wn,positions:e=>Tn(yn,vn,e)}),On={delta:(e,t)=>Dn(t).delta(e,t),positions:(e,t)=>Dn(t).positions(e,t),edge:e=>Dn(e).edge(e)},kn={unsupportedLength:["em","ex","cap","ch","ic","rem","lh","rlh","vw","vh","vi","vb","vmin","vmax","cm","mm","Q","in","pc","pt","px"],fixed:["px","pt"],relative:["%"],empty:[""]},En=(()=>{const e="[0-9]+",t="[eE][+-]?[0-9]+",o=e=>`(?:${e})?`,n=["Infinity","[0-9]+\\."+o(e)+o(t),"\\.[0-9]+"+o(t),e+o(t)].join("|");return new RegExp(`^([+-]?(?:${n}))(.*)$`)})(),Nn=/(\d+(\.\d+)?)%/,Bn=/(\d+(\.\d+)?)px|em/,zn=ae("col"),An=(e,t,o)=>{const n=(r=e,C.from(r.dom.parentElement).map(pe.fromDom)).getOrThunk((()=>tt(Se(e))));var r;return t(e)/o(n)*100},Wn=(e,t)=>{St(e,"width",t+"px")},Ln=(e,t)=>{St(e,"width",t+"%")},_n=(e,t)=>{St(e,"height",t+"px")},Mn=e=>{const t=(e=>{return Do(t=e,"height",t.dom.offsetHeight)+"px";var t})(e);return t?((e,t,o,n)=>{const r=parseFloat(e);return bt(e,"%")&&"table"!==Z(t)?((e,t,o,n)=>{const r=Ft(e).map((e=>{const n=o(e);return Math.floor(t/100*n)})).getOr(t);return n(e,r),r})(t,r,o,n):r})(t,e,an,_n):an(e)},jn=(e,t)=>Ot(e,t).orThunk((()=>ue(e,t).map((e=>e+"px")))),In=e=>jn(e,"width"),Pn=e=>An(e,ko,No),Fn=e=>{return zn(e)?ko(e):Do(t=e,"width",t.dom.offsetWidth);var t},Hn=e=>((e,t,o)=>o(e)/Nt(e,"rowspan"))(e,0,Mn),qn=(e,t,o)=>{St(e,"width",t+o)},Vn=e=>An(e,ko,No)+"%",$n=g(Nn),Un=ae("col"),Gn=e=>In(e).getOrThunk((()=>Fn(e)+"px")),Kn=e=>{return(t=e,jn(t,"height")).getOrThunk((()=>Hn(e)+"px"));var t},Yn=(e,t,o,n,r,s)=>e.filter(n).fold((()=>s(((e,t)=>{if(t<0||t>=e.length-1)return C.none();const o=e[t].fold((()=>{const o=(e=>{const t=S.call(e,0);return t.reverse(),t})(e.slice(0,t));return V(o,((e,t)=>e.map((e=>({value:e,delta:t+1})))))}),(e=>C.some({value:e,delta:0}))),n=e[t+1].fold((()=>{const o=e.slice(t+1);return V(o,((e,t)=>e.map((e=>({value:e,delta:t+1})))))}),(e=>C.some({value:e,delta:1})));return o.bind((e=>n.map((t=>{const o=t.delta+e.delta;return Math.abs(t.value-e.value)/o}))))})(o,t))),(e=>r(e))),Jn=(e,t,o,n)=>{const r=tn(e),s=Zo(e)?(e=>E(Xo(e),(e=>C.from(e.element))))(e):r,l=[C.some(On.edge(t))].concat(E(On.positions(r,t),(e=>e.map((e=>e.x))))),a=b(Bt);return E(s,((e,t)=>Yn(e,t,l,a,(e=>{if((e=>{const t=To().browser,o=t.isChromium()||t.isFirefox();return!Un(e)||o})(e))return o(e);{const e=null!=(s=r[t])?h(s):C.none();return Yn(e,t,l,a,(e=>n(C.some(ko(e)))),n)}var s}),n)))},Qn=e=>e.map((e=>e+"px")).getOr(""),Xn=(e,t,o)=>Jn(e,t,Fn,(e=>e.getOrThunk(o.minCellWidth))),Zn=(e,t,o,n,r)=>{const s=nn(e),l=[C.some(o.edge(t))].concat(E(o.positions(s,t),(e=>e.map((e=>e.y)))));return E(s,((e,t)=>Yn(e,t,l,b(zt),n,r)))},er=(e,t)=>()=>et(e)?t(e):parseFloat(Ot(e,"width").getOr("0")),tr=e=>{const t=er(e,(e=>parseFloat(Vn(e)))),o=er(e,ko);return{width:t,pixelWidth:o,getWidths:(t,o)=>((e,t,o)=>Jn(e,t,Pn,(e=>e.fold((()=>o.minCellWidth()),(e=>e/o.pixelWidth()*100)))))(t,e,o),getCellDelta:e=>e/o()*100,singleColumnWidth:(e,t)=>[100-e],minCellWidth:()=>Wt()/o()*100,setElementWidth:Ln,adjustTableWidth:o=>{const n=t();Ln(e,n+o/100*n)},isRelative:!0,label:"percent"}},or=e=>{const t=er(e,ko);return{width:t,pixelWidth:t,getWidths:(t,o)=>Xn(t,e,o),getCellDelta:h,singleColumnWidth:(e,t)=>[Math.max(Wt(),e+t)-e],minCellWidth:Wt,setElementWidth:Wn,adjustTableWidth:o=>{const n=t()+o;Wn(e,n)},isRelative:!1,label:"pixel"}},nr=e=>In(e).fold((()=>(e=>{const t=er(e,ko),o=g(0);return{width:t,pixelWidth:t,getWidths:(t,o)=>Xn(t,e,o),getCellDelta:o,singleColumnWidth:g([0]),minCellWidth:o,setElementWidth:f,adjustTableWidth:f,isRelative:!0,label:"none"}})(e)),(t=>((e,t)=>null!==$n().exec(t)?tr(e):or(e))(e,t))),rr=or,sr=tr,lr=(e,t,o)=>{const n=e[o].element,r=pe.fromTag("td");We(r,pe.fromTag("br")),(t?We:Ae)(n,r)},ar=((e,t)=>{const o=t=>e(t)?C.from(t.dom.nodeValue):C.none();return{get:t=>{if(!e(t))throw new Error("Can only get text value of a text node");return o(t).getOr("")},getOption:o,set:(t,o)=>{if(!e(t))throw new Error("Can only set raw text value of a text node");t.dom.nodeValue=o}}})(re),cr=e=>ar.get(e),ir=e=>ar.getOption(e),mr=(e,t)=>ar.set(e,t),dr=e=>"img"===Z(e)?1:ir(e).fold((()=>Ee(e).length),(e=>e.length)),ur=["img","br"],fr=e=>ir(e).filter((e=>0!==e.trim().length||e.indexOf("\xa0")>-1)).isSome()||D(ur,Z(e)),gr=e=>((e,t)=>{const o=e=>{for(let n=0;npr(e,fr),pr=(e,t)=>{const o=e=>{const n=Ee(e);for(let e=n.length-1;e>=0;e--){const r=n[e];if(t(r))return C.some(r);const s=o(r);if(s.isSome())return s}return C.none()};return o(e)},wr={scope:["row","col"]},br=e=>()=>{const t=pe.fromTag("td",e.dom);return We(t,pe.fromTag("br",e.dom)),t},vr=e=>()=>pe.fromTag("col",e.dom),yr=e=>()=>pe.fromTag("colgroup",e.dom),xr=e=>()=>pe.fromTag("tr",e.dom),Cr=(e,t,o)=>{const n=((e,t)=>{const o=Ve(e,t),n=Ee(qe(e));return Me(o,n),o})(e,t);return G(o,((e,t)=>{null===e?fe(n,t):ie(n,t,e)})),n},Sr=e=>e,Tr=(e,t,o)=>{const n=(e,t)=>{((e,t)=>{const o=e.dom,n=t.dom;xt(o)&&xt(n)&&(n.style.cssText=o.style.cssText)})(e.element,t),kt(t,"height"),1!==e.colspan&&kt(t,"width")};return{col:o=>{const r=pe.fromTag(Z(o.element),t.dom);return n(o,r),e(o.element,r),r},colgroup:yr(t),row:xr(t),cell:r=>{const s=pe.fromTag(Z(r.element),t.dom),l=o.getOr(["strong","em","b","i","span","font","h1","h2","h3","h4","h5","h6","p","div"]),a=l.length>0?((e,t,o)=>gr(e).map((n=>{const r=o.join(","),s=nt(n,r,(t=>ye(t,e)));return A(s,((e,t)=>{const o=He(t);return fe(o,"contenteditable"),We(e,o),o}),t)})).getOr(t))(r.element,s,l):s;return We(a,pe.fromTag("br")),n(r,s),((e,t)=>{G(wr,((o,n)=>ue(e,n).filter((e=>D(o,e))).each((e=>ie(t,n,e)))))})(r.element,s),e(r.element,s),s},replace:Cr,colGap:vr(t),gap:br(t)}},Rr=e=>({col:vr(e),colgroup:yr(e),row:xr(e),cell:br(e),replace:Sr,colGap:vr(e),gap:br(e)}),Dr=e=>pe.fromDom(e.getBody()),Or=e=>t=>ye(t,Dr(e)),kr=e=>{fe(e,"data-mce-style");const t=e=>fe(e,"data-mce-style");N(It(e),t),N(Pt(e),t),N(Ht(e),t)},Er=e=>pe.fromDom(e.selection.getStart()),Nr=e=>e.getBoundingClientRect().width,Br=e=>e.getBoundingClientRect().height,zr=(e,t)=>{const o=t.column,n=t.column+t.colspan-1,r=t.row,s=t.row+t.rowspan-1;return o<=e.finishCol&&n>=e.startCol&&r<=e.finishRow&&s>=e.startRow},Ar=(e,t)=>t.column>=e.startCol&&t.column+t.colspan-1<=e.finishCol&&t.row>=e.startRow&&t.row+t.rowspan-1<=e.finishRow,Wr=(e,t,o)=>{const n=Yo(e,t,ye),r=Yo(e,o,ye);return n.bind((e=>r.map((t=>{return o=e,n=t,{startRow:Math.min(o.row,n.row),startCol:Math.min(o.column,n.column),finishRow:Math.max(o.row+o.rowspan-1,n.row+n.rowspan-1),finishCol:Math.max(o.column+o.colspan-1,n.column+n.colspan-1)};var o,n}))))},Lr=(e,t,o)=>Wr(e,t,o).map((t=>{const o=Jo(e,w(zr,t));return E(o,(e=>e.element))})),_r=(e,t)=>Yo(e,t,((e,t)=>xe(t,e))).map((e=>e.element)),Mr=(e,t,o)=>{const n=Ir(e);return Lr(n,t,o)},jr=(e,t,o,n,r)=>{const s=Ir(e),l=ye(e,o)?C.some(t):_r(s,t),a=ye(e,r)?C.some(n):_r(s,n);return l.bind((e=>a.bind((t=>Lr(s,e,t)))))},Ir=Uo;var Pr=["body","p","div","article","aside","figcaption","figure","footer","header","nav","section","ol","ul","li","table","thead","tbody","tfoot","caption","tr","td","th","h1","h2","h3","h4","h5","h6","blockquote","pre","address"],Fr=()=>({up:g({selector:ct,closest:dt,predicate:at,all:De}),down:g({selector:st,predicate:ot}),styles:g({get:Rt,getRaw:Ot,set:St,remove:kt}),attrs:g({get:de,set:ie,remove:fe,copyTo:(e,t)=>{const o=ge(e);me(t,o)}}),insert:g({before:Be,after:ze,afterAll:_e,append:We,appendAll:Me,prepend:Ae,wrap:Le}),remove:g({unwrap:Pe,remove:Ie}),create:g({nu:pe.fromTag,clone:e=>pe.fromDom(e.dom.cloneNode(!1)),text:pe.fromText}),query:g({comparePosition:(e,t)=>e.dom.compareDocumentPosition(t.dom),prevSibling:Oe,nextSibling:ke}),property:g({children:Ee,name:Z,parent:Re,document:e=>Te(e).dom,isText:re,isComment:oe,isElement:ne,isSpecial:e=>{const t=Z(e);return D(["script","noscript","iframe","noframes","noembed","title","style","textarea","xmp"],t)},getLanguage:e=>ne(e)?ue(e,"lang"):C.none(),getText:cr,setText:mr,isBoundary:e=>!!ne(e)&&("body"===Z(e)||D(Pr,Z(e))),isEmptyTag:e=>!!ne(e)&&D(["br","img","hr","input"],Z(e)),isNonEditable:e=>ne(e)&&"false"===de(e,"contenteditable")}),eq:ye,is:Ce});const Hr=(e,t,o,n)=>{const r=t(e,o);return A(n,((o,n)=>{const r=t(e,n);return qr(e,o,r)}),r)},qr=(e,t,o)=>t.bind((t=>o.filter(w(e.eq,t)))),Vr=Fr(),$r=(e,t)=>((e,t,o)=>o.length>0?((e,t,o,n)=>n(e,t,o[0],o.slice(1)))(e,t,o,Hr):C.none())(Vr,((t,o)=>e(o)),t),Ur=e=>ct(e,"table"),Gr=(e,t,o)=>{const n=e=>t=>void 0!==o&&o(t)||ye(t,e);return ye(e,t)?C.some({boxes:C.some([e]),start:e,finish:t}):Ur(e).bind((r=>Ur(t).bind((s=>{if(ye(r,s))return C.some({boxes:Mr(r,e,t),start:e,finish:t});if(xe(r,s)){const o=nt(t,"td,th",n(r)),l=o.length>0?o[o.length-1]:t;return C.some({boxes:jr(r,e,r,t,s),start:e,finish:l})}if(xe(s,r)){const o=nt(e,"td,th",n(s)),l=o.length>0?o[o.length-1]:e;return C.some({boxes:jr(s,e,r,t,s),start:e,finish:l})}return((e,t,o)=>((e,t,o,n=y)=>{const r=[t].concat(e.up().all(t)),s=[o].concat(e.up().all(o)),l=e=>_(e,n).fold((()=>e),(t=>e.slice(0,t+1))),a=l(r),c=l(s),i=L(a,(t=>O(c,((e,t)=>w(e.eq,t))(e,t))));return{firstpath:a,secondpath:c,shared:i}})(Vr,e,t,void 0))(e,t).shared.bind((l=>dt(l,"table",o).bind((o=>{const l=nt(t,"td,th",n(o)),a=l.length>0?l[l.length-1]:t,c=nt(e,"td,th",n(o)),i=c.length>0?c[c.length-1]:e;return C.some({boxes:jr(o,e,r,t,s),start:i,finish:a})}))))}))))},Kr=(e,t)=>{const o=st(e,t);return o.length>0?C.some(o):C.none()},Yr=(e,t,o)=>mt(e,t).bind((t=>mt(e,o).bind((e=>$r(Ur,[t,e]).map((o=>({first:t,last:e,table:o}))))))),Jr=(e,t,o,n,r)=>((e,t)=>L(e,(e=>we(e,t))))(e,r).bind((e=>((e,t,o)=>Ft(e).bind((n=>((e,t,o,n)=>Yo(e,t,ye).bind((t=>{const r=o>0?t.row+t.rowspan-1:t.row,s=n>0?t.column+t.colspan-1:t.column;return Ko(e,r+o,s+n).map((e=>e.element))})))(Ir(n),e,t,o))))(e,t,o).bind((e=>((e,t)=>ct(e,"table").bind((o=>mt(o,t).bind((t=>Gr(t,e).bind((e=>e.boxes.map((t=>({boxes:t,start:e.start,finish:e.finish}))))))))))(e,n))))),Qr=(e,t)=>Kr(e,t),Xr=(e,t,o)=>Yr(e,t,o).bind((t=>{const o=t=>ye(e,t),n="thead,tfoot,tbody,table",r=ct(t.first,n,o),s=ct(t.last,n,o);return r.bind((e=>s.bind((o=>ye(e,o)?((e,t,o)=>((e,t,o)=>Wr(e,t,o).bind((t=>((e,t)=>{let o=!0;const n=w(Ar,t);for(let r=t.startRow;r<=t.finishRow;r++)for(let s=t.startCol;s<=t.finishCol;s++)o=o&&Ko(e,r,s).exists(n);return o?C.some(t):C.none()})(e,t))))(Ir(e),t,o))(t.table,t.first,t.last):C.none()))))})),Zr=h,es=e=>{const t=(e,t)=>ue(e,t).exists((e=>parseInt(e,10)>1));return e.length>0&&I(e,(e=>t(e,"rowspan")||t(e,"colspan")))?C.some(e):C.none()},ts=(e,t,o)=>t.length<=1?C.none():Xr(e,o.firstSelectedSelector,o.lastSelectedSelector).map((e=>({bounds:e,cells:t}))),os={selected:"data-mce-selected",selectedSelector:"td[data-mce-selected],th[data-mce-selected]",firstSelected:"data-mce-first-selected",firstSelectedSelector:"td[data-mce-first-selected],th[data-mce-first-selected]",lastSelected:"data-mce-last-selected",lastSelectedSelector:"td[data-mce-last-selected],th[data-mce-last-selected]"},ns=(e,t,o)=>({element:o,mergable:ts(t,e,os),unmergable:es(e),selection:Zr(e)}),rs=e=>(t,o)=>{const n=Z(t),r="col"===n||"colgroup"===n?Ft(s=t).bind((e=>Qr(e,os.firstSelectedSelector))).fold(g(s),(e=>e[0])):t;var s;return dt(r,e,o)},ss=rs("th,td,caption"),ls=rs("th,td"),as=e=>{return t=e.model.table.getSelectedCells(),E(t,pe.fromDom);var t},cs=(e,t)=>{e.on("BeforeGetContent",(t=>{const o=o=>{t.preventDefault(),(e=>Ft(e[0]).map((e=>{const t=((e,t)=>{const o=e=>we(e.element,t),n=qe(e),r=Ut(n),s=nr(e),l=Go(r),a=((e,t)=>{const o=e.grid.columns;let n=e.grid.rows,r=o,s=0,l=0;const a=[],c=[];return G(e.access,(e=>{if(a.push(e),t(e)){c.push(e);const t=e.row,o=t+e.rowspan-1,a=e.column,i=a+e.colspan-1;ts&&(s=o),al&&(l=i)}})),((e,t,o,n,r,s)=>({minRow:e,minCol:t,maxRow:o,maxCol:n,allCells:r,selectedCells:s}))(n,r,s,l,a,c)})(l,o),c="th:not("+t+"),td:not("+t+")",i=Mt(n,"th,td",(e=>we(e,c)));N(i,Ie),((e,t,o,n)=>{const r=z(e,(e=>"colgroup"!==e.section)),s=t.grid.columns,l=t.grid.rows;for(let e=0;eo.maxRow||ao.maxCol||(Ko(t,e,a).filter(n).isNone()?lr(r,l,e):l=!0)}})(r,l,a,o);const m=((e,t,o,n)=>{if(0===n.minCol&&t.grid.columns===n.maxCol+1)return 0;const r=Xn(t,e,o),s=W(r,((e,t)=>e+t),0),l=W(r.slice(n.minCol,n.maxCol+1),((e,t)=>e+t),0),a=l/s*o.pixelWidth()-o.pixelWidth();return o.getCellDelta(a)})(e,Uo(e),s,a);return((e,t,o,n)=>{G(o.columns,(e=>{(e.columnt.maxCol)&&Ie(e.element)}));const r=z(_t(e,"tr"),(e=>0===e.dom.childElementCount));N(r,Ie),t.minCol!==t.maxCol&&t.minRow!==t.maxRow||N(_t(e,"th,td"),(e=>{fe(e,"rowspan"),fe(e,"colspan")})),fe(e,Po),fe(e,"data-snooker-col-series"),nr(e).adjustTableWidth(n)})(n,a,l,m),n})(e,"[data-mce-selected]");return kr(t),[t]})))(o).each((o=>{t.content="text"===t.format?(e=>E(e,(e=>e.dom.innerText)).join(""))(o):((e,t)=>E(t,(t=>e.selection.serializer.serialize(t.dom,{}))).join(""))(e,o)}))};if(!0===t.selection){const t=(e=>z(as(e),(e=>we(e,os.selectedSelector))))(e);t.length>=1&&o(t)}})),e.on("BeforeSetContent",(o=>{if(!0===o.selection&&!0===o.paste){const n=as(e);H(n).each((n=>{Ft(n).each((r=>{const s=z(((e,t)=>{const o=document.createElement("div");return o.innerHTML=e,Ee(pe.fromDom(o))})(o.content),(e=>"meta"!==Z(e))),l=ae("table");if(1===s.length&&l(s[0])){o.preventDefault();const l=pe.fromDom(e.getDoc()),a=Rr(l),c=((e,t,o)=>({element:e,clipboard:t,generators:o}))(n,s[0],a);t.pasteCells(r,c).each((()=>{e.focus()}))}}))}))}}))},is=(e,t)=>({element:e,offset:t}),ms=(e,t,o)=>e.property().isText(t)&&0===e.property().getText(t).trim().length||e.property().isComment(t)?o(t).bind((t=>ms(e,t,o).orThunk((()=>C.some(t))))):C.none(),ds=(e,t)=>e.property().isText(t)?e.property().getText(t).length:e.property().children(t).length,us=(e,t)=>{const o=ms(e,t,e.query().prevSibling).getOr(t);if(e.property().isText(o))return is(o,ds(e,o));const n=e.property().children(o);return n.length>0?us(e,n[n.length-1]):is(o,ds(e,o))},fs=us,gs=Fr(),hs=(e,t)=>{if(!Bt(e)){const o=(e=>In(e).bind((e=>{return t=e,o=["fixed","relative","empty"],C.from(En.exec(t)).bind((e=>{const t=Number(e[1]),n=e[2];return((e,t)=>O(t,(t=>O(kn[t],(t=>e===t)))))(n,o)?C.some({value:t,unit:n}):C.none()}));var t,o})))(e);o.each((o=>{const n=o.value/2;qn(e,n,o.unit),qn(t,n,o.unit)}))}},ps=e=>E(e,g(0)),ws=(e,t,o,n,r)=>r(e.slice(0,t)).concat(n).concat(r(e.slice(o))),bs=e=>(t,o,n,r)=>{if(e(n)){const e=Math.max(r,t[o]-Math.abs(n)),s=Math.abs(e-t[o]);return n>=0?s:-s}return n},vs=bs((e=>e<0)),ys=bs(x),xs=()=>{const e=(e,t,o,n)=>{const r=(100+o)/100,s=Math.max(n,(e[t]+o)/r);return E(e,((e,o)=>(o===t?s:e/r)-e))},t=(t,o,n,r,s,l)=>l?e(t,o,r,s):((e,t,o,n,r)=>{const s=vs(e,t,n,r);return ws(e,t,o+1,[s,0],ps)})(t,o,n,r,s);return{resizeTable:(e,t)=>e(t),clampTableDelta:vs,calcLeftEdgeDeltas:t,calcMiddleDeltas:(e,o,n,r,s,l,a)=>t(e,n,r,s,l,a),calcRightEdgeDeltas:(t,o,n,r,s,l)=>{if(l)return e(t,n,r,s);{const e=vs(t,n,r,s);return ps(t.slice(0,n)).concat([e])}},calcRedestributedWidths:(e,t,o,n)=>{if(n){const n=(t+o)/t,r=E(e,(e=>e/n));return{delta:100*n-100,newSizes:r}}return{delta:o,newSizes:e}}}},Cs=()=>{const e=(e,t,o,n,r)=>{const s=ys(e,n>=0?o:t,n,r);return ws(e,t,o+1,[s,-s],ps)};return{resizeTable:(e,t,o)=>{o&&e(t)},clampTableDelta:(e,t,o,n,r)=>{if(r){if(o>=0)return o;{const t=W(e,((e,t)=>e+t-n),0);return Math.max(-t,o)}}return vs(e,t,o,n)},calcLeftEdgeDeltas:e,calcMiddleDeltas:(t,o,n,r,s,l)=>e(t,n,r,s,l),calcRightEdgeDeltas:(e,t,o,n,r,s)=>{if(s)return ps(e);{const t=n/e.length;return E(e,g(t))}},calcRedestributedWidths:(e,t,o,n)=>({delta:0,newSizes:e})}},Ss=e=>Uo(e).grid,Ts=ae("th"),Rs=e=>I(e,(e=>Ts(e.element))),Ds=(e,t)=>e&&t?"sectionCells":e?"section":"cells",Os=e=>{const t="thead"===e.section,o=ut(ks(e.cells),"th");return"tfoot"===e.section?{type:"footer"}:t||o?{type:"header",subType:Ds(t,o)}:{type:"body"}},ks=e=>{const t=z(e,(e=>Ts(e.element)));return 0===t.length?C.some("td"):t.length===e.length?C.some("th"):C.none()},Es=(e,t,o)=>Ke(o(e.element,t),!0,e.isLocked),Ns=(e,t)=>e.section!==t?Ye(e.element,e.cells,t,e.isNew):e,Bs=()=>({transformRow:Ns,transformCell:(e,t,o)=>{const n=o(e.element,t),r="td"!==Z(n)?((e,t)=>{const o=Ve(e,"td");ze(e,o);const n=Ee(e);return Me(o,n),Ie(e),o})(n):n;return Ke(r,e.isNew,e.isLocked)}}),zs=()=>({transformRow:Ns,transformCell:Es}),As=()=>({transformRow:(e,t)=>Ns(e,"thead"===t?"tbody":t),transformCell:Es}),Ws=Bs,Ls=zs,_s=As,Ms=()=>({transformRow:h,transformCell:Es}),js=e=>dt(e,"[contenteditable]"),Is=(e,t=!1)=>et(e)?e.dom.isContentEditable:js(e).fold(g(t),(e=>"true"===Ps(e))),Ps=e=>e.dom.contentEditable,Fs=(e,t,o,n)=>{o===n?fe(e,t):ie(e,t,o)},Hs=(e,t,o)=>{q(rt(e,t)).fold((()=>Ae(e,o)),(e=>ze(e,o)))},qs=(e,t)=>{const o=[],n=[],r=e=>E(e,(e=>{e.isNew&&o.push(e.element);const t=e.element;return je(t),N(e.cells,(e=>{e.isNew&&n.push(e.element),Fs(e.element,"colspan",e.colspan,1),Fs(e.element,"rowspan",e.rowspan,1),We(t,e.element)})),t})),s=e=>j(e,(e=>E(e.cells,(e=>(Fs(e.element,"span",e.colspan,1),e.element))))),l=(t,o)=>{const n=((e,t)=>{const o=it(e,t).getOrThunk((()=>{const o=pe.fromTag(t,Se(e).dom);return"thead"===t?Hs(e,"caption,colgroup",o):"colgroup"===t?Hs(e,"caption",o):We(e,o),o}));return je(o),o})(e,o),l=("colgroup"===o?s:r)(t);Me(n,l)},a=(t,o)=>{t.length>0?l(t,o):(t=>{it(e,t).each(Ie)})(o)},c=[],i=[],m=[],d=[];return N(t,(e=>{switch(e.section){case"thead":c.push(e);break;case"tbody":i.push(e);break;case"tfoot":m.push(e);break;case"colgroup":d.push(e)}})),a(d,"colgroup"),a(c,"thead"),a(i,"tbody"),a(m,"tfoot"),{newRows:o,newCells:n}},Vs=(e,t)=>{if(0===e.length)return 0;const o=e[0];return _(e,(e=>!t(o.element,e.element))).getOr(e.length)},$s=(e,t)=>{const o=E(e,(e=>E(e.cells,y)));return E(e,((n,r)=>{const s=j(n.cells,((n,s)=>{if(!1===o[r][s]){const m=((e,t,o,n)=>{const r=((e,t)=>e[t])(e,t),s="colgroup"===r.section,l=Vs(r.cells.slice(o),n),a=s?1:Vs(((e,t)=>E(e,(e=>Lo(e,t))))(e.slice(t),o),n);return{colspan:l,rowspan:a}})(e,r,s,t);return((e,t,n,r)=>{for(let s=e;s({element:e,cells:t,section:o,isNew:n}))(n.element,s,n.section,n.isNew)}))},Us=(e,t,o)=>{const n=[];N(e.colgroups,(r=>{const s=[];for(let n=0;nKe(e.element,o,!1))).getOrThunk((()=>Ke(t.colGap(),!0,!1)));s.push(r)}n.push(Ye(r.element,s,"colgroup",o))}));for(let r=0;rKe(e.element,o,e.isLocked))).getOrThunk((()=>Ke(t.gap(),!0,!1)));s.push(l)}const l=e.all[r],a=Ye(l.element,s,l.section,o);n.push(a)}return n},Gs=e=>$s(e,ye),Ks=(e,t)=>V(e.all,(e=>L(e.cells,(e=>ye(t,e.element))))),Ys=(e,t,o)=>{const n=E(t.selection,(t=>jt(t).bind((t=>Ks(e,t))).filter(o))),r=ft(n);return gt(r.length>0,r)},Js=(e,t,o,n,r)=>(s,l,a,c)=>{const i=Uo(s),m=C.from(null==c?void 0:c.section).getOrThunk(Ms);return t(i,l).map((t=>{const o=((e,t)=>Us(e,t,!1))(i,a),n=e(o,t,ye,r(a),m),s=Ho(n.grid);return{info:t,grid:Gs(n.grid),cursor:n.cursor,lockedColumns:s}})).bind((e=>{const t=qs(s,e.grid),r=C.from(null==c?void 0:c.sizing).getOrThunk((()=>nr(s))),l=C.from(null==c?void 0:c.resize).getOrThunk(Cs);return o(s,e.grid,e.info,{sizing:r,resize:l,section:m}),n(s),fe(s,Po),e.lockedColumns.length>0&&ie(s,Po,e.lockedColumns.join(",")),C.some({cursor:e.cursor,newRows:t.newRows,newCells:t.newCells})}))},Qs=(e,t)=>Ys(e,t,x).map((e=>({cells:e,generators:t.generators,clipboard:t.clipboard}))),Xs=(e,t)=>Ys(e,t,x),Zs=(e,t)=>Ys(e,t,(e=>!e.isLocked)),el=(e,t)=>I(t,(t=>((e,t)=>Ks(e,t).exists((e=>!e.isLocked)))(e,t))),tl=(e,t,o,n)=>{const r=jo(e).rows;let s=!0;for(let e=0;e{const t=t=>t(e),o=g(e),n=()=>r,r={tag:!0,inner:e,fold:(t,o)=>o(e),isValue:x,isError:y,map:t=>rl.value(t(e)),mapError:n,bind:t,exists:t,forall:t,getOr:o,or:n,getOrThunk:o,orThunk:n,getOrDie:o,each:t=>{t(e)},toOptional:()=>C.some(e)};return r},nl=e=>{const t=()=>o,o={tag:!1,inner:e,fold:(t,o)=>t(e),isValue:y,isError:x,map:t,mapError:t=>rl.error(t(e)),bind:t,exists:y,forall:x,getOr:h,or:h,getOrThunk:v,orThunk:v,getOrDie:(n=String(e),()=>{throw new Error(n)}),each:f,toOptional:C.none};var n;return o},rl={value:ol,error:nl,fromOption:(e,t)=>e.fold((()=>nl(t)),ol)},sl=(e,t)=>({rowDelta:0,colDelta:Mo(e[0])-Mo(t[0])}),ll=(e,t)=>({rowDelta:e.length-t.length,colDelta:0}),al=(e,t,o,n)=>{const r="colgroup"===t.section?o.col:o.cell;return k(e,(e=>Ke(r(),!0,n(e))))},cl=(e,t,o,n)=>{const r=e[e.length-1];return e.concat(k(t,(()=>{const e="colgroup"===r.section?o.colgroup:o.row,t=Io(r,e,h),s=al(t.cells.length,t,o,(e=>X(n,e.toString())));return Wo(t,s)})))},il=(e,t,o,n)=>E(e,(e=>{const r=al(t,e,o,y);return Bo(e,n,r)})),ml=(e,t,o)=>{const n=t.colDelta<0?il:h,r=t.rowDelta<0?cl:h,s=Ho(e),l=Mo(e[0]),a=O(s,(e=>e===l-1)),c=n(e,Math.abs(t.colDelta),o,a?l-1:l),i=Ho(c);return r(c,Math.abs(t.rowDelta),o,P(i,x))},dl=(e,t,o,n)=>{const r=w(n,Lo(e[t],o).element),s=e[t];return e.length>1&&Mo(s)>1&&(o>0&&r(_o(s,o-1))||o0&&r(_o(e[t-1],o))||tz(o,(o=>o>=e.column&&o<=Mo(t[0])+e.column)),fl=(e,t,o,n,r)=>{((e,t,o,n)=>{t>0&&t{const r=e.cells[t-1];let s=0;const l=n();for(;e.cells.length>t+s&&o(r.element,e.cells[t+s].element);)Ao(e,t+s,Ke(l,!0,e.cells[t+s].isLocked)),s++}))})(t,e,r,n.cell);const s=ll(o,t),l=ml(o,s,n),a=ll(t,l),c=ml(t,a,n);return E(c,((t,o)=>Bo(t,e,l[o].cells)))},gl=(e,t,o,n,r)=>{((e,t,o,n)=>{const r=jo(e).rows;if(t>0&&tW(e,((e,o)=>O(e,(e=>t(e.element,o.element)))?e:e.concat([o])),[]))(r[t-1].cells,o);N(e,(e=>{let s=C.none();for(let l=t;l{Ao(a,t,Ke(e,!0,c.isLocked))})))}}))}})(t,e,r,n.cell);const s=Ho(t),l=sl(t,o),a={...l,colDelta:l.colDelta-s.length},c=ml(t,a,n),{cols:i,rows:m}=jo(c),d=Ho(c),u=sl(o,t),f={...u,colDelta:u.colDelta+d.length},g=(p=n,w=d,E(o,(e=>W(w,((t,o)=>{const n=al(1,e,p,x)[0];return zo(t,o,n)}),e)))),h=ml(g,f,n);var p,w;return[...i,...m.slice(0,e),...h,...m.slice(e,m.length)]},hl=(e,t,o,n,r)=>{const{rows:s,cols:l}=jo(e),a=s.slice(0,t),c=s.slice(t);return[...l,...a,((e,t,o,n)=>Io(e,(e=>n(e,o)),t))(s[o],((e,o)=>t>0&&tE(e,(e=>{const s=t>0&&t{if("colgroup"!==o&&n)return Lo(e,t);{const t=Lo(e,r);return Ke(l(t.element,s),!0,!1)}})(e,t,e.section,s,o,n,r);return zo(e,t,l)})),wl=(e,t,o,n)=>((e,t,o,n)=>void 0!==_o(e[t],o)&&t>0&&n(_o(e[t-1],o),_o(e[t],o)))(e,t,o,n)||((e,t,o)=>t>0&&o(_o(e,t-1),_o(e,t)))(e[t],o,n),bl=(e,t,o,n)=>{const r=e=>(e=>"row"===e?zt(t):Bt(t))(e)?`${e}group`:e;return e?Ts(t)?r(o):null:n&&Ts(t)?r("row"===o?"col":"row"):null},vl=(e,t,o)=>Ke(o(e.element,t),!0,e.isLocked),yl=(e,t,o,n,r,s,l)=>E(e,((e,a)=>((e,c)=>{const i=e.cells,m=E(i,((e,c)=>{if((e=>O(t,(t=>o(e.element,t.element))))(e)){const t=l(e,a,c)?r(e,o,n):e;return s(t,a,c).each((e=>{var o,n;o=t.element,n={scope:C.from(e)},G(n,((e,t)=>{e.fold((()=>{fe(o,t)}),(e=>{ce(o.dom,t,e)}))}))})),t}return e}));return Ye(e.element,m,e.section,e.isNew)})(e))),xl=(e,t,o)=>j(e,((n,r)=>wl(e,r,t,o)?[]:[Lo(n,t)])),Cl=(e,t,o,n,r)=>{const s=jo(e).rows,l=j(t,(e=>xl(s,e,n))),a=E(s,(e=>Rs(e.cells))),c=((e,t)=>I(t,h)&&Rs(e)?x:(e,o,n)=>!("th"===Z(e.element)&&t[o]))(l,a),i=((e,t)=>(o,n)=>C.some(bl(e,o.element,"row",t[n])))(o,a);return yl(e,l,n,r,vl,i,c)},Sl=(e,t,o,n)=>{const r=jo(e).rows,s=E(t,(e=>Lo(r[e.row],e.column)));return yl(e,s,o,n,vl,C.none,x)},Tl=e=>{if(!l(e))throw new Error("cases must be an array");if(0===e.length)throw new Error("there must be at least one case");const t=[],o={};return N(e,((n,r)=>{const s=$(n);if(1!==s.length)throw new Error("one and only one name per case");const a=s[0],c=n[a];if(void 0!==o[a])throw new Error("duplicate key detected:"+a);if("cata"===a)throw new Error("cannot have a case named cata (sorry)");if(!l(c))throw new Error("case arguments must be an array");t.push(a),o[a]=(...o)=>{const n=o.length;if(n!==c.length)throw new Error("Wrong number of arguments to case "+a+". Expected "+c.length+" ("+c+"), got "+n);return{fold:(...t)=>{if(t.length!==e.length)throw new Error("Wrong number of arguments to fold. Expected "+e.length+", got "+t.length);return t[r].apply(null,o)},match:e=>{const n=$(e);if(t.length!==n.length)throw new Error("Wrong number of arguments to match. Expected: "+t.join(",")+"\nActual: "+n.join(","));if(!I(t,(e=>D(n,e))))throw new Error("Not all branches were specified when using match. Specified: "+n.join(", ")+"\nRequired: "+t.join(", "));return e[a].apply(null,o)},log:e=>{console.log(e,{constructors:t,constructor:a,params:o})}}}})),o},Rl={...Tl([{none:[]},{only:["index"]},{left:["index","next"]},{middle:["prev","index","next"]},{right:["prev","index"]}])},Dl=(e,t,o)=>{let n=0;for(let r=e;r{const o=Qo(e);return E(o,(e=>{const o=Dl(e.row,e.row+e.rowspan,t);return{element:e.element,height:o,rowspan:e.rowspan}}))},kl=(e,t,o)=>{const n=((e,t)=>Zo(e)?((e,t)=>{const o=Xo(e);return E(o,((e,o)=>({element:e.element,width:t[o],colspan:e.colspan})))})(e,t):((e,t)=>{const o=Qo(e);return E(o,(e=>{const o=Dl(e.column,e.column+e.colspan,t);return{element:e.element,width:o,colspan:e.colspan}}))})(e,t))(e,t);N(n,(e=>{o.setElementWidth(e.element,e.width)}))},El=(e,t,o,n,r)=>{const s=Uo(e),l=r.getCellDelta(t),a=r.getWidths(s,r),c=o===s.grid.columns-1,i=n.clampTableDelta(a,o,l,r.minCellWidth(),c),m=((e,t,o,n,r)=>{const s=e.slice(0),l=((e,t)=>0===e.length?Rl.none():1===e.length?Rl.only(0):0===t?Rl.left(0,1):t===e.length-1?Rl.right(t-1,t):t>0&&tn.singleColumnWidth(s[e],o)),((e,t)=>r.calcLeftEdgeDeltas(s,e,t,o,n.minCellWidth(),n.isRelative)),((e,t,l)=>r.calcMiddleDeltas(s,e,t,l,o,n.minCellWidth(),n.isRelative)),((e,t)=>r.calcRightEdgeDeltas(s,e,t,o,n.minCellWidth(),n.isRelative)))})(a,o,i,r,n),d=E(m,((e,t)=>e+a[t]));kl(s,d,r),n.resizeTable(r.adjustTableWidth,i,c)},Nl=e=>W(e,((e,t)=>O(e,(e=>e.column===t.column))?e:e.concat([t])),[]).sort(((e,t)=>e.column-t.column)),Bl=ae("col"),zl=ae("colgroup"),Al=e=>"tr"===Z(e)||zl(e),Wl=e=>({element:e,colspan:Et(e,"colspan",1),rowspan:Et(e,"rowspan",1)}),Ll=e=>ue(e,"scope").map((e=>e.substr(0,3))),_l=(e,t=Wl)=>{const o=o=>{if(Al(o))return zl((r={element:o}).element)?e.colgroup(r):e.row(r);{const r=o,s=(t=>Bl(t.element)?e.col(t):e.cell(t))(t(r));return n=C.some({item:r,replacement:s}),s}var r};let n=C.none();return{getOrInit:(e,t)=>n.fold((()=>o(e)),(n=>t(e,n.item)?n.replacement:o(e)))}},Ml=e=>t=>{const o=[],n=n=>{const r="td"===e?{scope:null}:{},s=t.replace(n,e,r);return o.push({item:n,sub:s}),s};return{replaceOrInit:(e,t)=>{if(Al(e)||Bl(e))return e;{const r=e;return((e,t)=>L(o,(o=>t(o.item,e))))(r,t).fold((()=>n(r)),(o=>t(e,o.item)?o.sub:n(r)))}}}},jl=e=>({unmerge:t=>{const o=Ll(t);return o.each((e=>ie(t,"scope",e))),()=>{const n=e.cell({element:t,colspan:1,rowspan:1});return kt(n,"width"),kt(t,"width"),o.each((e=>ie(n,"scope",e))),n}},merge:e=>(kt(e[0],"width"),(()=>{const t=ft(E(e,Ll));if(0===t.length)return C.none();{const e=t[0],o=["row","col"];return O(t,(t=>t!==e&&D(o,t)))?C.none():C.from(e)}})().fold((()=>fe(e[0],"scope")),(t=>ie(e[0],"scope",t+"group"))),g(e[0]))}),Il=["body","p","div","article","aside","figcaption","figure","footer","header","nav","section","ol","ul","table","thead","tfoot","tbody","caption","tr","td","th","h1","h2","h3","h4","h5","h6","blockquote","pre","address"],Pl=Fr(),Fl=e=>((e,t)=>{const o=e.property().name(t);return D(Il,o)})(Pl,e),Hl=e=>((e,t)=>{const o=e.property().name(t);return D(["ol","ul"],o)})(Pl,e),ql=e=>{const t=ae("br"),o=e=>hr(e).bind((o=>{const n=ke(o).map((e=>!!Fl(e)||!!((e,t)=>D(["br","img","hr","input"],e.property().name(t)))(Pl,e)&&"img"!==Z(e))).getOr(!1);return Re(o).map((r=>{return!0===n||("li"===Z(s=r)||at(s,Hl).isSome())||t(o)||Fl(r)&&!ye(e,r)?[]:[pe.fromTag("br")];var s}))})).getOr([]),n=(()=>{const n=j(e,(e=>{const n=Ee(e);return(e=>I(e,(e=>t(e)||re(e)&&0===cr(e).trim().length)))(n)?[]:n.concat(o(e))}));return 0===n.length?[pe.fromTag("br")]:n})();je(e[0]),Me(e[0],n)},Vl=e=>Is(e,!0),$l=e=>{0===It(e).length&&Ie(e)},Ul=(e,t)=>({grid:e,cursor:t}),Gl=(e,t,o)=>{const n=((e,t,o)=>{var n,r;const s=jo(e).rows;return C.from(null===(r=null===(n=s[t])||void 0===n?void 0:n.cells[o])||void 0===r?void 0:r.element).filter(Vl).orThunk((()=>(e=>V(e,(e=>V(e.cells,(e=>{const t=e.element;return gt(Vl(t),t)})))))(s)))})(e,t,o);return Ul(e,n)},Kl=e=>W(e,((e,t)=>O(e,(e=>e.row===t.row))?e:e.concat([t])),[]).sort(((e,t)=>e.row-t.row)),Yl=(e,t)=>(o,n,r,s,l)=>{const a=Kl(n),c=E(a,(e=>e.row)),i=((e,t,o,n,r,s,l)=>{const{cols:a,rows:c}=jo(e),i=c[t[0]],m=j(t,(e=>((e,t,o)=>{const n=e[t];return j(n.cells,((n,r)=>wl(e,t,r,o)?[]:[n]))})(c,e,r))),d=E(i.cells,((e,t)=>Rs(xl(c,t,r)))),u=[...c];N(t,(e=>{u[e]=l.transformRow(c[e],o)}));const f=[...a,...u],g=((e,t)=>I(t,h)&&Rs(e.cells)?x:(e,o,n)=>!("th"===Z(e.element)&&t[n]))(i,d),p=((e,t)=>(o,n,r)=>C.some(bl(e,o.element,"col",t[r])))(n,d);return yl(f,m,r,s,l.transformCell,p,g)})(o,c,e,t,r,s.replaceOrInit,l);return Gl(i,n[0].row,n[0].column)},Jl=Yl("thead",!0),Ql=Yl("tbody",!1),Xl=Yl("tfoot",!1),Zl=(e,t,o)=>{const n=((e,t)=>Vt(e,(()=>t)))(e,o.section),r=Go(n);return Us(r,t,!0)},ea=(e,t,o,n)=>((e,t,o,n)=>{const r=Go(t),s=n.getWidths(r,n);kl(r,s,n)})(0,t,0,n.sizing),ta=(e,t,o,n)=>((e,t,o,n,r)=>{const s=Go(t),l=n.getWidths(s,n),a=n.pixelWidth(),{newSizes:c,delta:i}=r.calcRedestributedWidths(l,a,o.pixelDelta,n.isRelative);kl(s,c,n),n.adjustTableWidth(i)})(0,t,o,n.sizing,n.resize),oa=(e,t)=>O(t,(e=>0===e.column&&e.isLocked)),na=(e,t)=>O(t,(t=>t.column+t.colspan>=e.grid.columns&&t.isLocked)),ra=(e,t)=>{const o=tn(e),n=Nl(t);return W(n,((e,t)=>e+o[t.column].map(Eo).getOr(0)),0)},sa=e=>(t,o)=>Xs(t,o).filter((o=>!(e?oa:na)(t,o))).map((e=>({details:e,pixelDelta:ra(t,e)}))),la=e=>(t,o)=>Qs(t,o).filter((o=>!(e?oa:na)(t,o.cells))),aa=Ml("th"),ca=Ml("td"),ia=Js(((e,t,o,n)=>{const r=t[0].row,s=Kl(t),l=A(s,((e,t)=>({grid:hl(e.grid,r,t.row+e.delta,o,n.getOrInit),delta:e.delta+1})),{grid:e,delta:0}).grid;return Gl(l,r,t[0].column)}),Xs,f,f,_l),ma=Js(((e,t,o,n)=>{const r=Kl(t),s=r[r.length-1],l=s.row+s.rowspan,a=A(r,((e,t)=>hl(e,l,t.row,o,n.getOrInit)),e);return Gl(a,l,t[0].column)}),Xs,f,f,_l),da=Js(((e,t,o,n)=>{const r=t.details,s=Nl(r),l=s[0].column,a=A(s,((e,t)=>({grid:pl(e.grid,l,t.column+e.delta,o,n.getOrInit),delta:e.delta+1})),{grid:e,delta:0}).grid;return Gl(a,r[0].row,l)}),sa(!0),ta,f,_l),ua=Js(((e,t,o,n)=>{const r=t.details,s=r[r.length-1],l=s.column+s.colspan,a=Nl(r),c=A(a,((e,t)=>pl(e,l,t.column,o,n.getOrInit)),e);return Gl(c,r[0].row,l)}),sa(!1),ta,f,_l),fa=Js(((e,t,o,n)=>{const r=Nl(t.details),s=((e,t)=>j(e,(e=>{const o=e.cells,n=A(t,((e,t)=>t>=0&&t0?[Ye(e.element,n,e.section,e.isNew)]:[]})))(e,E(r,(e=>e.column))),l=s.length>0?s[0].cells.length-1:0;return Gl(s,r[0].row,Math.min(r[0].column,l))}),((e,t)=>Zs(e,t).map((t=>({details:t,pixelDelta:-ra(e,t)})))),ta,$l,_l),ga=Js(((e,t,o,n)=>{const r=Kl(t),s=((e,t,o)=>{const{rows:n,cols:r}=jo(e);return[...r,...n.slice(0,t),...n.slice(o+1)]})(e,r[0].row,r[r.length-1].row),l=s.length>0?s.length-1:0;return Gl(s,Math.min(t[0].row,l),t[0].column)}),Xs,f,$l,_l),ha=Js(((e,t,o,n)=>{const r=Nl(t),s=E(r,(e=>e.column)),l=Cl(e,s,!0,o,n.replaceOrInit);return Gl(l,t[0].row,t[0].column)}),Zs,f,f,aa),pa=Js(((e,t,o,n)=>{const r=Nl(t),s=E(r,(e=>e.column)),l=Cl(e,s,!1,o,n.replaceOrInit);return Gl(l,t[0].row,t[0].column)}),Zs,f,f,ca),wa=Js(Jl,Zs,f,f,aa),ba=Js(Ql,Zs,f,f,ca),va=Js(Xl,Zs,f,f,ca),ya=Js(((e,t,o,n)=>{const r=Sl(e,t,o,n.replaceOrInit);return Gl(r,t[0].row,t[0].column)}),Zs,f,f,aa),xa=Js(((e,t,o,n)=>{const r=Sl(e,t,o,n.replaceOrInit);return Gl(r,t[0].row,t[0].column)}),Zs,f,f,ca),Ca=Js(((e,t,o,n)=>{const r=t.cells;ql(r);const s=((e,t,o,n)=>{const r=jo(e).rows;if(0===r.length)return e;for(let e=t.startRow;e<=t.finishRow;e++)for(let o=t.startCol;o<=t.finishCol;o++){const t=r[e],s=Lo(t,o).isLocked;Ao(t,o,Ke(n(),!1,s))}return e})(e,t.bounds,0,n.merge(r));return Ul(s,C.from(r[0]))}),((e,t)=>((e,t)=>t.mergable)(0,t).filter((t=>el(e,t.cells)))),ea,f,jl),Sa=Js(((e,t,o,n)=>{const r=A(t,((e,t)=>tl(e,t,o,n.unmerge(t))),e);return Ul(r,C.from(t[0]))}),((e,t)=>((e,t)=>t.unmergable)(0,t).filter((t=>el(e,t)))),ea,f,jl),Ta=Js(((e,t,o,n)=>{const r=((e,t)=>{const o=Uo(e);return Us(o,t,!0)})(t.clipboard,t.generators);var s,l;return((e,t,o,n,r)=>{const s=Ho(t),l=((e,t,o)=>{const n=Mo(t[0]),r=jo(t).cols.length+e.row,s=k(n-e.column,(t=>t+e.column));return{row:r,column:L(s,(e=>I(o,(t=>t!==e)))).getOr(n-1)}})(e,t,s),a=jo(o).rows,c=ul(l,a,s),i=((e,t,o)=>{if(e.row>=t.length||e.column>Mo(t[0]))return rl.error("invalid start address out of table bounds, row: "+e.row+", column: "+e.column);const n=t.slice(e.row),r=n[0].cells.slice(e.column),s=Mo(o[0]),l=o.length;return rl.value({rowDelta:n.length-l,colDelta:r.length-s})})(l,t,a);return i.map((e=>{const o={...e,colDelta:e.colDelta-c.length},s=ml(t,o,n),i=Ho(s),m=ul(l,a,i);return((e,t,o,n,r,s)=>{const l=e.row,a=e.column,c=l+o.length,i=a+Mo(o[0])+s.length,m=P(s,x);for(let e=l;eUl(e,C.some(t.element))),(e=>Gl(e,t.row,t.column)))}),((e,t)=>jt(t.element).bind((o=>Ks(e,o).map((e=>({...e,generators:t.generators,clipboard:t.clipboard})))))),ea,f,_l),Ra=Js(((e,t,o,n)=>{const r=jo(e).rows,s=t.cells[0].column,l=r[t.cells[0].row],a=Zl(t.clipboard,t.generators,l),c=fl(s,e,a,t.generators,o);return Gl(c,t.cells[0].row,t.cells[0].column)}),la(!0),f,f,_l),Da=Js(((e,t,o,n)=>{const r=jo(e).rows,s=t.cells[t.cells.length-1].column+t.cells[t.cells.length-1].colspan,l=r[t.cells[0].row],a=Zl(t.clipboard,t.generators,l),c=fl(s,e,a,t.generators,o);return Gl(c,t.cells[0].row,t.cells[0].column)}),la(!1),f,f,_l),Oa=Js(((e,t,o,n)=>{const r=jo(e).rows,s=t.cells[0].row,l=r[s],a=Zl(t.clipboard,t.generators,l),c=gl(s,e,a,t.generators,o);return Gl(c,t.cells[0].row,t.cells[0].column)}),Qs,f,f,_l),ka=Js(((e,t,o,n)=>{const r=jo(e).rows,s=t.cells[t.cells.length-1].row+t.cells[t.cells.length-1].rowspan,l=r[t.cells[0].row],a=Zl(t.clipboard,t.generators,l),c=gl(s,e,a,t.generators,o);return Gl(c,t.cells[0].row,t.cells[0].column)}),Qs,f,f,_l),Ea=(e,t)=>{const o=Uo(e);return Xs(o,t).bind((e=>{const t=e[e.length-1],n=e[0].column,r=t.column+t.colspan,s=M(E(o.all,(e=>z(e.cells,(e=>e.column>=n&&e.column{const o=Uo(e);return Xs(o,t).bind(ks).getOr("")},Ba=(e,t)=>{const o=Uo(e);return Xs(o,t).bind((e=>{const t=e[e.length-1],n=e[0].row,r=t.row+t.rowspan;return(e=>{const t=E(e,(e=>Os(e).type)),o=D(t,"header"),n=D(t,"footer");if(o||n){const e=D(t,"body");return!o||e||n?o||e||!n?C.none():C.some("footer"):C.some("header")}return C.some("body")})(o.all.slice(n,r))})).getOr("")},za=(e,t)=>e.dispatch("NewRow",{node:t}),Aa=(e,t)=>e.dispatch("NewCell",{node:t}),Wa=(e,t,o)=>{e.dispatch("TableModified",{...o,table:t})},La={structure:!1,style:!0},_a={structure:!0,style:!1},Ma={structure:!0,style:!0},ja=e=>t=>t.options.get(e),Ia="100%",Pa=e=>{var t;const o=e.dom,n=null!==(t=o.getParent(e.selection.getStart(),o.isBlock))&&void 0!==t?t:e.getBody();return No(pe.fromDom(n))+"px"},Fa=e=>C.from(e.options.get("table_clone_elements")),Ha=ja("table_header_type"),qa=ja("table_column_resizing"),Va=e=>"preservetable"===qa(e),$a=e=>"resizetable"===qa(e),Ua=ja("table_sizing_mode"),Ga=e=>"relative"===Ua(e),Ka=e=>"fixed"===Ua(e),Ya=e=>"responsive"===Ua(e),Ja=ja("table_resize_bars"),Qa=ja("table_style_by_css"),Xa=e=>{const t=e.options,o=t.get("table_default_attributes");return t.isSet("table_default_attributes")?o:((e,t)=>Ya(e)||Qa(e)?t:Ka(e)?{...t,width:Pa(e)}:{...t,width:Ia})(e,o)},Za=ja("table_use_colgroups"),ec=(e,t)=>Ga(e)?sr(t):Ka(e)?rr(t):nr(t),tc=(e,t,o)=>{const n=e=>"table"===Z(Dr(e)),r=Fa(e),s=$a(e)?f:hs,l=t=>{switch(Ha(e)){case"section":return Ws();case"sectionCells":return Ls();case"cells":return _s();default:return((e,t)=>{var o;switch((o=Uo(e),V(o.all,(e=>{const t=Os(e);return"header"===t.type?C.from(t.subType):C.none()}))).getOr(t)){case"section":return Bs();case"sectionCells":return zs();case"cells":return As()}})(t,"section")}},a=(n,s,a,c)=>(i,m,d=!1)=>{kr(i);const u=pe.fromDom(e.getDoc()),f=Tr(a,u,r),g={sizing:ec(e,i),resize:$a(e)?xs():Cs(),section:l(i)};return s(i)?n(i,m,f,g).bind((n=>{t.refresh(i.dom),N(n.newRows,(t=>{za(e,t.dom)})),N(n.newCells,(t=>{Aa(e,t.dom)}));const r=((t,n)=>n.cursor.fold((()=>{const n=It(t);return H(n).filter(et).map((n=>{o.clearSelectedCells(t.dom);const r=e.dom.createRng();return r.selectNode(n.dom),e.selection.setRng(r),ie(n,"data-mce-selected","1"),r}))}),(n=>{const r=fs(gs,n),s=e.dom.createRng();return s.setStart(r.element.dom,r.offset),s.setEnd(r.element.dom,r.offset),e.selection.setRng(s),o.clearSelectedCells(t.dom),C.some(s)})))(i,n);return et(i)&&(kr(i),d||Wa(e,i.dom,c)),r.map((e=>({rng:e,effect:c})))})):C.none()},c=a(ga,(t=>!n(e)||Ss(t).rows>1),f,_a),i=a(fa,(t=>!n(e)||Ss(t).columns>1),f,_a);return{deleteRow:c,deleteColumn:i,insertRowsBefore:a(ia,x,f,_a),insertRowsAfter:a(ma,x,f,_a),insertColumnsBefore:a(da,x,s,_a),insertColumnsAfter:a(ua,x,s,_a),mergeCells:a(Ca,x,f,_a),unmergeCells:a(Sa,x,f,_a),pasteColsBefore:a(Ra,x,f,_a),pasteColsAfter:a(Da,x,f,_a),pasteRowsBefore:a(Oa,x,f,_a),pasteRowsAfter:a(ka,x,f,_a),pasteCells:a(Ta,x,f,Ma),makeCellsHeader:a(ya,x,f,_a),unmakeCellsHeader:a(xa,x,f,_a),makeColumnsHeader:a(ha,x,f,_a),unmakeColumnsHeader:a(pa,x,f,_a),makeRowsHeader:a(wa,x,f,_a),makeRowsBody:a(ba,x,f,_a),makeRowsFooter:a(va,x,f,_a),getTableRowType:Ba,getTableCellType:Na,getTableColType:Ea}},oc=(e,t,o)=>{const n=Et(e,t,1);1===o||n<=1?fe(e,t):ie(e,t,Math.min(o,n))},nc=(e,t)=>o=>{const n=o.column+o.colspan-1,r=o.column;return n>=e&&r{const n=o.substring(0,o.length-e.length),r=parseFloat(n);return n===r.toString()?t(r):rc.invalid(o)},lc={...rc,from:e=>bt(e,"%")?sc("%",rc.percent,e):bt(e,"px")?sc("px",rc.pixels,e):rc.invalid(e)},ac=(e,t,o)=>{const n=lc.from(o),r=I(e,(e=>"0px"===e))?((e,t)=>{const o=e.fold((()=>g("")),(e=>g(e/t+"px")),(()=>g(100/t+"%")));return k(t,o)})(n,e.length):((e,t,o)=>e.fold((()=>t),(e=>((e,t,o)=>{const n=o/t;return E(e,(e=>lc.from(e).fold((()=>e),(e=>e*n+"px"),(e=>e/100*o+"px"))))})(t,o,e)),(e=>((e,t)=>E(e,(e=>lc.from(e).fold((()=>e),(e=>e/t*100+"%"),(e=>e+"%")))))(t,o))))(n,e,t);return mc(r)},cc=(e,t)=>0===e.length?t:A(e,((e,t)=>lc.from(t).fold(g(0),h,h)+e),0),ic=(e,t)=>lc.from(e).fold(g(e),(e=>e+t+"px"),(e=>e+t+"%")),mc=e=>{if(0===e.length)return e;const t=A(e,((e,t)=>{const o=lc.from(t).fold((()=>({value:t,remainder:0})),(e=>((e,t)=>{const o=Math.floor(e);return{value:o+"px",remainder:e-o}})(e)),(e=>({value:e+"%",remainder:0})));return{output:[o.value].concat(e.output),remainder:e.remainder+o.remainder}}),{output:[],remainder:0}),o=t.output;return o.slice(0,o.length-1).concat([ic(o[o.length-1],Math.round(t.remainder))])},dc=lc.from,uc=e=>dc(e).fold(g("px"),g("px"),g("%")),fc=(e,t,o)=>{const n=Uo(e),r=n.all,s=Qo(n),l=Xo(n);t.each((t=>{const o=uc(t),r=ko(e),a=((e,t)=>Jn(e,t,Gn,Qn))(n,e),c=ac(a,r,t);Zo(n)?((e,t,o)=>{N(t,((t,n)=>{const r=cc([e[n]],Wt());St(t.element,"width",r+o)}))})(c,l,o):((e,t,o)=>{N(t,(t=>{const n=e.slice(t.column,t.colspan+t.column),r=cc(n,Wt());St(t.element,"width",r+o)}))})(c,s,o),St(e,"width",t)})),o.each((t=>{const o=uc(t),l=an(e),a=((e,t,o)=>Zn(e,t,o,Kn,Qn))(n,e,Rn);((e,t,o,n)=>{N(o,(t=>{const o=e.slice(t.row,t.rowspan+t.row),r=cc(o,Lt());St(t.element,"height",r+n)})),N(t,((t,o)=>{St(t.element,"height",e[o])}))})(ac(a,l,t),r,s,o),St(e,"height",t)}))},gc=e=>In(e).exists((e=>Nn.test(e))),hc=e=>In(e).exists((e=>Bn.test(e))),pc=e=>In(e).isNone(),wc=e=>{fe(e,"width")},bc=e=>{const t=Vn(e);fc(e,C.some(t),C.none()),wc(e)},vc=e=>{const t=(e=>ko(e)+"px")(e);fc(e,C.some(t),C.none()),wc(e)},yc=e=>{kt(e,"width");const t=Pt(e),o=t.length>0?t:It(e);N(o,(e=>{kt(e,"width"),wc(e)})),wc(e)},xc={styles:{"border-collapse":"collapse",width:"100%"},attributes:{border:"1"},colGroups:!1},Cc=(e,t,o,n)=>k(e,(e=>((e,t,o,n)=>{const r=pe.fromTag("tr");for(let s=0;s{e.selection.select(t.dom,!0),e.selection.collapse(!0)},Tc=(e,t,o,n,s)=>{const l=(e=>{const t=e.options,o=t.get("table_default_styles");return t.isSet("table_default_styles")?o:((e,t)=>Ya(e)||!Qa(e)?t:Ka(e)?{...t,width:Pa(e)}:{...t,width:Ia})(e,o)})(e),a={styles:l,attributes:Xa(e),colGroups:Za(e)};return e.undoManager.ignore((()=>{const r=((e,t,o,n,r,s=xc)=>{const l=pe.fromTag("table"),a="cells"!==r;Tt(l,s.styles),me(l,s.attributes),s.colGroups&&We(l,(e=>{const t=pe.fromTag("colgroup");return k(e,(()=>We(t,pe.fromTag("col")))),t})(t));const c=Math.min(e,o);if(a&&o>0){const e=pe.fromTag("thead");We(l,e);const s=Cc(o,t,"sectionCells"===r?c:0,n);Me(e,s)}const i=pe.fromTag("tbody");We(l,i);const m=Cc(a?e-c:e,t,a?0:o,n);return Me(i,m),l})(o,t,s,n,Ha(e),a);ie(r,"data-mce-id","__mce");const l=(e=>{const t=pe.fromTag("div"),o=pe.fromDom(e.dom.cloneNode(!0));return We(t,o),(e=>e.dom.innerHTML)(t)})(r);e.insertContent(l),e.addVisual()})),mt(Dr(e),'table[data-mce-id="__mce"]').map((t=>(Ka(e)?vc(t):Ya(e)?yc(t):(Ga(e)||(e=>r(e)&&-1!==e.indexOf("%"))(l.width))&&bc(t),kr(t),fe(t,"data-mce-id"),((e,t)=>{N(st(t,"tr"),(t=>{za(e,t.dom),N(st(t,"th,td"),(t=>{Aa(e,t.dom)}))}))})(e,t),((e,t)=>{mt(t,"td,th").each(w(Sc,e))})(e,t),t.dom))).getOrNull()};var Rc=tinymce.util.Tools.resolve("tinymce.FakeClipboard");const Dc="x-tinymce/dom-table-",Oc=Dc+"rows",kc=Dc+"columns",Ec=e=>{const t=Rc.FakeClipboardItem(e);Rc.write([t])},Nc=e=>{var t;const o=null!==(t=Rc.read())&&void 0!==t?t:[];return V(o,(t=>C.from(t.getType(e))))},Bc=e=>{Nc(e).isSome()&&Rc.clear()},zc=e=>{e.fold(Wc,(e=>Ec({[Oc]:e})))},Ac=()=>Nc(Oc),Wc=()=>Bc(Oc),Lc=e=>{e.fold(Mc,(e=>Ec({[kc]:e})))},_c=()=>Nc(kc),Mc=()=>Bc(kc),jc=e=>ss(Er(e),Or(e)),Ic=(e,t)=>{const o=Or(e),n=e=>Ft(e,o),l=t=>(e=>ls(Er(e),Or(e)))(e).bind((e=>n(e).map((o=>t(o,e))))),a=t=>{e.focus()},c=(t,o=!1)=>l(((n,r)=>{const s=ns(as(e),n,r);t(n,s,o).each(a)})),i=()=>l(((t,o)=>((e,t,o)=>{const n=Uo(e);return Xs(n,t).bind((e=>{const t=Us(n,o,!1),r=jo(t).rows.slice(e[0].row,e[e.length-1].row+e[e.length-1].rowspan),s=j(r,(e=>{const t=z(e.cells,(e=>!e.isLocked));return t.length>0?[{...e,cells:t}]:[]})),l=Gs(s);return gt(l.length>0,l)})).map((e=>E(e,(e=>{const t=He(e.element);return N(e.cells,(e=>{const o=qe(e.element);Fs(o,"colspan",e.colspan,1),Fs(o,"rowspan",e.rowspan,1),We(t,o)})),t}))))})(t,ns(as(e),t,o),Tr(f,pe.fromDom(e.getDoc()),C.none())))),m=()=>l(((t,o)=>((e,t)=>{const o=Uo(e);return Zs(o,t).map((e=>{const t=e[e.length-1],n=e[0].column,r=t.column+t.colspan,s=((e,t,o)=>{if(Zo(e)){const n=z(Xo(e),nc(t,o)),r=E(n,(e=>{const n=qe(e.element);return oc(n,"span",o-t),n})),s=pe.fromTag("colgroup");return Me(s,r),[s]}return[]})(o,n,r),l=((e,t,o)=>E(e.all,(e=>{const n=z(e.cells,nc(t,o)),r=E(n,(e=>{const n=qe(e.element);return oc(n,"colspan",o-t),n})),s=pe.fromTag("tr");return Me(s,r),s})))(o,n,r);return[...s,...l]}))})(t,ns(as(e),t,o)))),d=(t,o)=>o().each((o=>{const n=E(o,(e=>qe(e)));l(((o,r)=>{const s=Rr(pe.fromDom(e.getDoc())),l=((e,t,o,n)=>({selection:Zr(e),clipboard:o,generators:n}))(as(e),0,n,s);t(o,l).each(a)}))})),g=e=>(t,o)=>((e,t)=>X(e,t)?C.from(e.type):C.none())(o,"type").each((t=>{c(e(t),o.no_events)}));G({mceTableSplitCells:()=>c(t.unmergeCells),mceTableMergeCells:()=>c(t.mergeCells),mceTableInsertRowBefore:()=>c(t.insertRowsBefore),mceTableInsertRowAfter:()=>c(t.insertRowsAfter),mceTableInsertColBefore:()=>c(t.insertColumnsBefore),mceTableInsertColAfter:()=>c(t.insertColumnsAfter),mceTableDeleteCol:()=>c(t.deleteColumn),mceTableDeleteRow:()=>c(t.deleteRow),mceTableCutCol:()=>m().each((e=>{Lc(e),c(t.deleteColumn)})),mceTableCutRow:()=>i().each((e=>{zc(e),c(t.deleteRow)})),mceTableCopyCol:()=>m().each((e=>Lc(e))),mceTableCopyRow:()=>i().each((e=>zc(e))),mceTablePasteColBefore:()=>d(t.pasteColsBefore,_c),mceTablePasteColAfter:()=>d(t.pasteColsAfter,_c),mceTablePasteRowBefore:()=>d(t.pasteRowsBefore,Ac),mceTablePasteRowAfter:()=>d(t.pasteRowsAfter,Ac),mceTableDelete:()=>jc(e).each((t=>{Ft(t,o).filter(b(o)).each((t=>{const o=pe.fromText("");if(ze(t,o),Ie(t),e.dom.isEmpty(e.getBody()))e.setContent(""),e.selection.setCursorLocation();else{const t=e.dom.createRng();t.setStart(o.dom,0),t.setEnd(o.dom,0),e.selection.setRng(t),e.nodeChanged()}}))})),mceTableCellToggleClass:(t,o)=>{l((t=>{const n=as(e),r=I(n,(t=>e.formatter.match("tablecellclass",{value:o},t.dom))),s=r?e.formatter.remove:e.formatter.apply;N(n,(e=>s("tablecellclass",{value:o},e.dom))),Wa(e,t.dom,La)}))},mceTableToggleClass:(t,o)=>{l((t=>{e.formatter.toggle("tableclass",{value:o},t.dom),Wa(e,t.dom,La)}))},mceTableToggleCaption:()=>{jc(e).each((t=>{Ft(t,o).each((o=>{it(o,"caption").fold((()=>{const t=pe.fromTag("caption");We(t,pe.fromText("Caption")),((e,t,o)=>{Ne(e,0).fold((()=>{We(e,t)}),(e=>{Be(e,t)}))})(o,t),e.selection.setCursorLocation(t.dom,0)}),(n=>{ae("caption")(t)&&ve("td",o).each((t=>e.selection.setCursorLocation(t.dom,0))),Ie(n)})),Wa(e,o.dom,_a)}))}))},mceTableSizingMode:(t,n)=>(t=>jc(e).each((n=>{Ya(e)||Ka(e)||Ga(e)||Ft(n,o).each((o=>{"relative"!==t||gc(o)?"fixed"!==t||hc(o)?"responsive"!==t||pc(o)||yc(o):vc(o):bc(o),kr(o),Wa(e,o.dom,_a)}))})))(n),mceTableCellType:g((e=>"th"===e?t.makeCellsHeader:t.unmakeCellsHeader)),mceTableColType:g((e=>"th"===e?t.makeColumnsHeader:t.unmakeColumnsHeader)),mceTableRowType:g((e=>{switch(e){case"header":return t.makeRowsHeader;case"footer":return t.makeRowsFooter;default:return t.makeRowsBody}}))},((t,o)=>e.addCommand(o,t))),e.addCommand("mceInsertTable",((t,o)=>{((e,t,o,n={})=>{const r=e=>u(e)&&e>0;if(r(t)&&r(o)){const r=n.headerRows||0,s=n.headerColumns||0;return Tc(e,o,t,s,r)}console.error("Invalid values for mceInsertTable - rows and columns values are required to insert a table.")})(e,o.rows,o.columns,o.options)})),e.addCommand("mceTableApplyCellStyle",((t,o)=>{const l=e=>"tablecell"+e.toLowerCase().replace("-","");if(!s(o))return;const a=as(e);if(0===a.length)return;const c=((e,t)=>{const o={};return((e,t,o,n)=>{G(e,((e,r)=>{(t(e,r)?o:n)(e,r)}))})(e,t,(e=>(t,o)=>{e[o]=t})(o),f),o})(o,((t,o)=>e.formatter.has(l(o))&&r(t)));(e=>{for(const t in e)if(U.call(e,t))return!1;return!0})(c)||(G(c,((t,o)=>{const n=l(o);N(a,(o=>{""===t?e.formatter.remove(n,{value:null},o.dom,!0):e.formatter.apply(n,{value:t},o.dom)}))})),n(a[0]).each((t=>Wa(e,t.dom,La))))}))},Pc=Tl([{before:["element"]},{on:["element","offset"]},{after:["element"]}]),Fc={before:Pc.before,on:Pc.on,after:Pc.after,cata:(e,t,o,n)=>e.fold(t,o,n),getStart:e=>e.fold(h,h,h)},Hc=(e,t)=>({selection:e,kill:t}),qc=(e,t)=>{const o=e.document.createRange();return o.selectNode(t.dom),o},Vc=(e,t)=>{const o=e.document.createRange();return $c(o,t),o},$c=(e,t)=>e.selectNodeContents(t.dom),Uc=(e,t,o)=>{const n=e.document.createRange();var r;return r=n,t.fold((e=>{r.setStartBefore(e.dom)}),((e,t)=>{r.setStart(e.dom,t)}),(e=>{r.setStartAfter(e.dom)})),((e,t)=>{t.fold((t=>{e.setEndBefore(t.dom)}),((t,o)=>{e.setEnd(t.dom,o)}),(t=>{e.setEndAfter(t.dom)}))})(n,o),n},Gc=(e,t,o,n,r)=>{const s=e.document.createRange();return s.setStart(t.dom,o),s.setEnd(n.dom,r),s},Kc=e=>({left:e.left,top:e.top,right:e.right,bottom:e.bottom,width:e.width,height:e.height}),Yc=Tl([{ltr:["start","soffset","finish","foffset"]},{rtl:["start","soffset","finish","foffset"]}]),Jc=(e,t,o)=>t(pe.fromDom(o.startContainer),o.startOffset,pe.fromDom(o.endContainer),o.endOffset),Qc=(e,t)=>{const o=((e,t)=>t.match({domRange:e=>({ltr:g(e),rtl:C.none}),relative:(t,o)=>({ltr:Gt((()=>Uc(e,t,o))),rtl:Gt((()=>C.some(Uc(e,o,t))))}),exact:(t,o,n,r)=>({ltr:Gt((()=>Gc(e,t,o,n,r))),rtl:Gt((()=>C.some(Gc(e,n,r,t,o))))})}))(e,t);return((e,t)=>{const o=t.ltr();return o.collapsed?t.rtl().filter((e=>!1===e.collapsed)).map((e=>Yc.rtl(pe.fromDom(e.endContainer),e.endOffset,pe.fromDom(e.startContainer),e.startOffset))).getOrThunk((()=>Jc(0,Yc.ltr,o))):Jc(0,Yc.ltr,o)})(0,o)},Xc=(e,t)=>Qc(e,t).match({ltr:(t,o,n,r)=>{const s=e.document.createRange();return s.setStart(t.dom,o),s.setEnd(n.dom,r),s},rtl:(t,o,n,r)=>{const s=e.document.createRange();return s.setStart(n.dom,r),s.setEnd(t.dom,o),s}});Yc.ltr,Yc.rtl;const Zc=(e,t,o,n)=>({start:e,soffset:t,finish:o,foffset:n}),ei=(e,t,o,n)=>({start:Fc.on(e,t),finish:Fc.on(o,n)}),ti=(e,t)=>{const o=Xc(e,t);return Zc(pe.fromDom(o.startContainer),o.startOffset,pe.fromDom(o.endContainer),o.endOffset)},oi=ei,ni=(e,t,o,n,r)=>ye(o,n)?C.none():Gr(o,n,t).bind((t=>{const n=t.boxes.getOr([]);return n.length>1?(r(e,n,t.start,t.finish),C.some(Hc(C.some(oi(o,0,o,dr(o))),!0))):C.none()})),ri=(e,t)=>({item:e,mode:t}),si=(e,t,o,n=li)=>e.property().parent(t).map((e=>ri(e,n))),li=(e,t,o,n=ai)=>o.sibling(e,t).map((e=>ri(e,n))),ai=(e,t,o,n=ai)=>{const r=e.property().children(t);return o.first(r).map((e=>ri(e,n)))},ci=[{current:si,next:li,fallback:C.none()},{current:li,next:ai,fallback:C.some(si)},{current:ai,next:ai,fallback:C.some(li)}],ii=(e,t,o,n,r=ci)=>L(r,(e=>e.current===o)).bind((o=>o.current(e,t,n,o.next).orThunk((()=>o.fallback.bind((o=>ii(e,t,o,n))))))),mi=(e,t,o,n,r,s)=>ii(e,t,n,r).bind((t=>s(t.item)?C.none():o(t.item)?C.some(t.item):mi(e,t.item,o,t.mode,r,s))),di=e=>t=>0===e.property().children(t).length,ui=(e,t,o,n)=>mi(e,t,o,li,{sibling:(e,t)=>e.query().prevSibling(t),first:e=>e.length>0?C.some(e[e.length-1]):C.none()},n),fi=(e,t,o,n)=>mi(e,t,o,li,{sibling:(e,t)=>e.query().nextSibling(t),first:e=>e.length>0?C.some(e[0]):C.none()},n),gi=Fr(),hi=(e,t)=>((e,t,o)=>ui(e,t,di(e),o))(gi,e,t),pi=(e,t)=>((e,t,o)=>fi(e,t,di(e),o))(gi,e,t),wi=Tl([{none:["message"]},{success:[]},{failedUp:["cell"]},{failedDown:["cell"]}]),bi=e=>dt(e,"tr"),vi={...wi,verify:(e,t,o,n,r,s,l)=>dt(n,"td,th",l).bind((o=>dt(t,"td,th",l).map((t=>ye(o,t)?ye(n,o)&&dr(o)===r?s(t):wi.none("in same cell"):$r(bi,[o,t]).fold((()=>((e,t,o)=>{const n=e.getRect(t),r=e.getRect(o);return r.right>n.left&&r.lefts(t))))))).getOr(wi.none("default")),cata:(e,t,o,n,r)=>e.fold(t,o,n,r)},yi=ae("br"),xi=(e,t,o)=>t(e,o).bind((e=>re(e)&&0===cr(e).trim().length?xi(e,t,o):C.some(e))),Ci=(e,t,o,n)=>((e,t)=>Ne(e,t).filter(yi).orThunk((()=>Ne(e,t-1).filter(yi))))(t,o).bind((t=>n.traverse(t).fold((()=>xi(t,n.gather,e).map(n.relative)),(e=>(e=>Re(e).bind((t=>{const o=Ee(t);return((e,t)=>_(e,w(ye,t)))(o,e).map((n=>((e,t,o,n)=>({parent:e,children:t,element:o,index:n}))(t,o,e,n)))})))(e).map((e=>Fc.on(e.parent,e.index))))))),Si=(e,t)=>({left:e.left,top:e.top+t,right:e.right,bottom:e.bottom+t}),Ti=(e,t)=>({left:e.left,top:e.top-t,right:e.right,bottom:e.bottom-t}),Ri=(e,t,o)=>({left:e.left+t,top:e.top+o,right:e.right+t,bottom:e.bottom+o}),Di=e=>({left:e.left,top:e.top,right:e.right,bottom:e.bottom}),Oi=(e,t)=>C.some(e.getRect(t)),ki=(e,t,o)=>ne(t)?Oi(e,t).map(Di):re(t)?((e,t,o)=>o>=0&&o0?e.getRangedRect(t,o-1,t,o):C.none())(e,t,o).map(Di):C.none(),Ei=(e,t)=>ne(t)?Oi(e,t).map(Di):re(t)?e.getRangedRect(t,0,t,dr(t)).map(Di):C.none(),Ni=Tl([{none:[]},{retry:["caret"]}]),Bi=(e,t,o)=>{return(n=t,r=Fl,lt(((e,t)=>t(e)),at,n,r,undefined)).fold(y,(t=>Ei(e,t).exists((e=>((e,t)=>e.leftt.right)(o,e)))));var n,r},zi={point:e=>e.bottom,adjuster:(e,t,o,n,r)=>{const s=Si(r,5);return Math.abs(o.bottom-n.bottom)<1||o.top>r.bottom?Ni.retry(s):o.top===r.bottom?Ni.retry(Si(r,1)):Bi(e,t,r)?Ni.retry(Ri(s,5,0)):Ni.none()},move:Si,gather:pi},Ai=(e,t,o,n,r)=>0===r?C.some(n):((e,t,o)=>e.elementFromPoint(t,o).filter((e=>"table"===Z(e))).isSome())(e,n.left,t.point(n))?((e,t,o,n,r)=>Ai(e,t,o,t.move(n,5),r))(e,t,o,n,r-1):e.situsFromPoint(n.left,t.point(n)).bind((s=>s.start.fold(C.none,(s=>Ei(e,s).bind((l=>t.adjuster(e,s,l,o,n).fold(C.none,(n=>Ai(e,t,o,n,r-1))))).orThunk((()=>C.some(n)))),C.none))),Wi=(e,t,o)=>{const n=e.move(o,5),r=Ai(t,e,o,n,100).getOr(n);return((e,t,o)=>e.point(t)>o.getInnerHeight()?C.some(e.point(t)-o.getInnerHeight()):e.point(t)<0?C.some(-e.point(t)):C.none())(e,r,t).fold((()=>t.situsFromPoint(r.left,e.point(r))),(o=>(t.scrollBy(0,o),t.situsFromPoint(r.left,e.point(r)-o))))},Li={tryUp:w(Wi,{point:e=>e.top,adjuster:(e,t,o,n,r)=>{const s=Ti(r,5);return Math.abs(o.top-n.top)<1||o.bottome.getSelection().bind((n=>((e,t,o,n)=>{const r=yi(t)?((e,t,o)=>o.traverse(t).orThunk((()=>xi(t,o.gather,e))).map(o.relative))(e,t,n):Ci(e,t,o,n);return r.map((e=>({start:e,finish:e})))})(t,n.finish,n.foffset,o).fold((()=>C.some(is(n.finish,n.foffset))),(r=>{const s=e.fromSitus(r);return l=vi.verify(e,n.finish,n.foffset,s.finish,s.foffset,o.failure,t),vi.cata(l,(e=>C.none()),(()=>C.none()),(e=>C.some(is(e,0))),(e=>C.some(is(e,dr(e)))));var l})))),Mi=(e,t,o,n,r,s)=>0===s?C.none():Pi(e,t,o,n,r).bind((l=>{const a=e.fromSitus(l),c=vi.verify(e,o,n,a.finish,a.foffset,r.failure,t);return vi.cata(c,(()=>C.none()),(()=>C.some(l)),(l=>ye(o,l)&&0===n?ji(e,o,n,Ti,r):Mi(e,t,l,0,r,s-1)),(l=>ye(o,l)&&n===dr(l)?ji(e,o,n,Si,r):Mi(e,t,l,dr(l),r,s-1)))})),ji=(e,t,o,n,r)=>ki(e,t,o).bind((t=>Ii(e,r,n(t,Li.getJumpSize())))),Ii=(e,t,o)=>{const n=To().browser;return n.isChromium()||n.isSafari()||n.isFirefox()?t.retry(e,o):C.none()},Pi=(e,t,o,n,r)=>ki(e,o,n).bind((t=>Ii(e,r,t))),Fi=(e,t,o,n,r)=>dt(n,"td,th",t).bind((n=>dt(n,"table",t).bind((s=>((e,t)=>at(e,(e=>Re(e).exists((e=>ye(e,t)))),void 0).isSome())(r,s)?((e,t,o)=>_i(e,t,o).bind((n=>Mi(e,t,n.element,n.offset,o,20).map(e.fromSitus))))(e,t,o).bind((e=>dt(e.finish,"td,th",t).map((t=>({start:n,finish:t,range:e}))))):C.none())))),Hi=(e,t,o,n,r,s)=>s(n,t).orThunk((()=>Fi(e,t,o,n,r).map((e=>{const t=e.range;return Hc(C.some(oi(t.start,t.soffset,t.finish,t.foffset)),!0)})))),qi=(e,t)=>dt(e,"tr",t).bind((e=>dt(e,"table",t).bind((o=>{const n=st(o,"tr");return ye(e,n[0])?((e,t,o)=>ui(gi,e,(e=>hr(e).isSome()),o))(o,0,t).map((e=>{const t=dr(e);return Hc(C.some(oi(e,t,e,t)),!0)})):C.none()})))),Vi=(e,t)=>dt(e,"tr",t).bind((e=>dt(e,"table",t).bind((o=>{const n=st(o,"tr");return ye(e,n[n.length-1])?((e,t,o)=>fi(gi,e,(e=>gr(e).isSome()),o))(o,0,t).map((e=>Hc(C.some(oi(e,0,e,0)),!0))):C.none()})))),$i=(e,t,o,n,r,s,l)=>Fi(e,o,n,r,s).bind((e=>ni(t,o,e.start,e.finish,l))),Ui=e=>{let t=e;return{get:()=>t,set:e=>{t=e}}},Gi=()=>{const e=(e=>{const t=Ui(C.none()),o=()=>t.get().each(e);return{clear:()=>{o(),t.set(C.none())},isSet:()=>t.get().isSome(),get:()=>t.get(),set:e=>{o(),t.set(C.some(e))}}})(f);return{...e,on:t=>e.get().each(t)}},Ki=(e,t)=>dt(e,"td,th",t),Yi={traverse:ke,gather:pi,relative:Fc.before,retry:Li.tryDown,failure:vi.failedDown},Ji={traverse:Oe,gather:hi,relative:Fc.before,retry:Li.tryUp,failure:vi.failedUp},Qi=e=>t=>t===e,Xi=Qi(38),Zi=Qi(40),em=e=>e>=37&&e<=40,tm={isBackward:Qi(37),isForward:Qi(39)},om={isBackward:Qi(39),isForward:Qi(37)},nm=Tl([{domRange:["rng"]},{relative:["startSitu","finishSitu"]},{exact:["start","soffset","finish","foffset"]}]),rm={domRange:nm.domRange,relative:nm.relative,exact:nm.exact,exactFromRange:e=>nm.exact(e.start,e.soffset,e.finish,e.foffset),getWin:e=>{const t=(e=>e.match({domRange:e=>pe.fromDom(e.startContainer),relative:(e,t)=>Fc.getStart(e),exact:(e,t,o,n)=>e}))(e);return pe.fromDom(Te(t).dom.defaultView)},range:Zc},sm=document.caretPositionFromPoint?(e,t,o)=>{var n,r;return C.from(null===(r=(n=e.dom).caretPositionFromPoint)||void 0===r?void 0:r.call(n,t,o)).bind((t=>{if(null===t.offsetNode)return C.none();const o=e.dom.createRange();return o.setStart(t.offsetNode,t.offset),o.collapse(),C.some(o)}))}:document.caretRangeFromPoint?(e,t,o)=>{var n,r;return C.from(null===(r=(n=e.dom).caretRangeFromPoint)||void 0===r?void 0:r.call(n,t,o))}:C.none,lm=(e,t)=>{const o=Z(e);return"input"===o?Fc.after(e):D(["br","img"],o)?0===t?Fc.before(e):Fc.after(e):Fc.on(e,t)},am=e=>C.from(e.getSelection()),cm=(e,t)=>{am(e).each((e=>{e.removeAllRanges(),e.addRange(t)}))},im=(e,t,o,n,r)=>{const s=Gc(e,t,o,n,r);cm(e,s)},mm=(e,t)=>Qc(e,t).match({ltr:(t,o,n,r)=>{im(e,t,o,n,r)},rtl:(t,o,n,r)=>{am(e).each((s=>{if(s.setBaseAndExtent)s.setBaseAndExtent(t.dom,o,n.dom,r);else if(s.extend)try{((e,t,o,n,r,s)=>{t.collapse(o.dom,n),t.extend(r.dom,s)})(0,s,t,o,n,r)}catch(s){im(e,n,r,t,o)}else im(e,n,r,t,o)}))}}),dm=(e,t,o,n,r)=>{const s=((e,t,o,n)=>{const r=lm(e,t),s=lm(o,n);return rm.relative(r,s)})(t,o,n,r);mm(e,s)},um=(e,t,o)=>{const n=((e,t)=>{const o=e.fold(Fc.before,lm,Fc.after),n=t.fold(Fc.before,lm,Fc.after);return rm.relative(o,n)})(t,o);mm(e,n)},fm=e=>{if(e.rangeCount>0){const t=e.getRangeAt(0),o=e.getRangeAt(e.rangeCount-1);return C.some(Zc(pe.fromDom(t.startContainer),t.startOffset,pe.fromDom(o.endContainer),o.endOffset))}return C.none()},gm=e=>{if(null===e.anchorNode||null===e.focusNode)return fm(e);{const t=pe.fromDom(e.anchorNode),o=pe.fromDom(e.focusNode);return((e,t,o,n)=>{const r=((e,t,o,n)=>{const r=Se(e).dom.createRange();return r.setStart(e.dom,t),r.setEnd(o.dom,n),r})(e,t,o,n),s=ye(e,o)&&t===n;return r.collapsed&&!s})(t,e.anchorOffset,o,e.focusOffset)?C.some(Zc(t,e.anchorOffset,o,e.focusOffset)):fm(e)}},hm=(e,t,o=!0)=>{const n=(o?Vc:qc)(e,t);cm(e,n)},pm=e=>(e=>am(e).filter((e=>e.rangeCount>0)).bind(gm))(e).map((e=>rm.exact(e.start,e.soffset,e.finish,e.foffset))),wm=e=>({elementFromPoint:(t,o)=>pe.fromPoint(pe.fromDom(e.document),t,o),getRect:e=>e.dom.getBoundingClientRect(),getRangedRect:(t,o,n,r)=>{const s=rm.exact(t,o,n,r);return((e,t)=>(e=>{const t=e.getClientRects(),o=t.length>0?t[0]:e.getBoundingClientRect();return o.width>0||o.height>0?C.some(o).map(Kc):C.none()})(Xc(e,t)))(e,s)},getSelection:()=>pm(e).map((t=>ti(e,t))),fromSitus:t=>{const o=rm.relative(t.start,t.finish);return ti(e,o)},situsFromPoint:(t,o)=>((e,t,o)=>((e,t,o)=>{const n=pe.fromDom(e.document);return sm(n,t,o).map((e=>Zc(pe.fromDom(e.startContainer),e.startOffset,pe.fromDom(e.endContainer),e.endOffset)))})(e,t,o))(e,t,o).map((e=>ei(e.start,e.soffset,e.finish,e.foffset))),clearSelection:()=>{(e=>{am(e).each((e=>e.removeAllRanges()))})(e)},collapseSelection:(t=!1)=>{pm(e).each((o=>o.fold((e=>e.collapse(t)),((o,n)=>{const r=t?o:n;um(e,r,r)}),((o,n,r,s)=>{const l=t?o:r,a=t?n:s;dm(e,l,a,l,a)}))))},setSelection:t=>{dm(e,t.start,t.soffset,t.finish,t.foffset)},setRelativeSelection:(t,o)=>{um(e,t,o)},selectNode:t=>{hm(e,t,!1)},selectContents:t=>{hm(e,t)},getInnerHeight:()=>e.innerHeight,getScrollY:()=>(e=>{const t=void 0!==e?e.dom:document,o=t.body.scrollLeft||t.documentElement.scrollLeft,n=t.body.scrollTop||t.documentElement.scrollTop;return dn(o,n)})(pe.fromDom(e.document)).top,scrollBy:(t,o)=>{((e,t,o)=>{const n=(void 0!==o?o.dom:document).defaultView;n&&n.scrollBy(e,t)})(t,o,pe.fromDom(e.document))}}),bm=(e,t)=>({rows:e,cols:t}),vm=e=>void 0!==e.dom.classList,ym=(e,t)=>((e,t,o)=>{const n=((e,t)=>{const o=de(e,t);return void 0===o||""===o?[]:o.split(" ")})(e,t).concat([o]);return ie(e,t,n.join(" ")),!0})(e,"class",t),xm=(e,t)=>{vm(e)?e.dom.classList.add(t):ym(e,t)},Cm=(e,t)=>vm(e)&&e.dom.classList.contains(t),Sm=()=>({tag:"none"}),Tm=e=>({tag:"multiple",elements:e}),Rm=e=>({tag:"single",element:e}),Dm=e=>{const t=pe.fromDom((e=>{if(Qe()&&m(e.target)){const t=pe.fromDom(e.target);if(ne(t)&&m(t.dom.shadowRoot)&&e.composed&&e.composedPath){const t=e.composedPath();if(t)return H(t)}}return C.from(e.target)})(e).getOr(e.target)),o=()=>e.stopPropagation(),n=()=>e.preventDefault(),r=(s=n,l=o,(...e)=>s(l.apply(null,e)));var s,l;return((e,t,o,n,r,s,l)=>({target:e,x:t,y:o,stop:n,prevent:r,kill:s,raw:l}))(t,e.clientX,e.clientY,o,n,r,e)},Om=(e,t,o,n)=>{e.dom.removeEventListener(t,o,n)},km=x,Em=(e,t,o)=>((e,t,o,n)=>((e,t,o,n,r)=>{const s=((e,t)=>o=>{e(o)&&t(Dm(o))})(o,n);return e.dom.addEventListener(t,s,r),{unbind:w(Om,e,t,s,r)}})(e,t,o,n,!1))(e,t,km,o),Nm=Dm,Bm=e=>!Cm(pe.fromDom(e.target),"ephox-snooker-resizer-bar"),zm=(e,t)=>{const o=(r=os.selectedSelector,{get:()=>Qr(pe.fromDom(e.getBody()),r).fold((()=>ls(Er(e),Or(e)).fold(Sm,Rm)),Tm)}),n=((e,t,o)=>{const n=t=>{fe(t,e.selected),fe(t,e.firstSelected),fe(t,e.lastSelected)},r=t=>{ie(t,e.selected,"1")},s=e=>{l(e),o()},l=t=>{const o=st(t,`${e.selectedSelector},${e.firstSelectedSelector},${e.lastSelectedSelector}`);N(o,n)};return{clearBeforeUpdate:l,clear:s,selectRange:(o,n,l,a)=>{s(o),N(n,r),ie(l,e.firstSelected,"1"),ie(a,e.lastSelected,"1"),t(n,l,a)},selectedSelector:e.selectedSelector,firstSelectedSelector:e.firstSelectedSelector,lastSelectedSelector:e.lastSelectedSelector}})(os,((t,o,n)=>{Ft(o).each((r=>{const s=Fa(e),l=Tr(f,pe.fromDom(e.getDoc()),s),a=((e,t,o)=>{const n=Uo(e);return Xs(n,t).map((e=>{const t=Us(n,o,!1),{rows:r}=jo(t),s=((e,t)=>{const o=e.slice(0,t[t.length-1].row+1),n=Gs(o);return j(n,(e=>{const o=e.cells.slice(0,t[t.length-1].column+1);return E(o,(e=>e.element))}))})(r,e),l=((e,t)=>{const o=e.slice(t[0].row+t[0].rowspan-1,e.length),n=Gs(o);return j(n,(e=>{const o=e.cells.slice(t[0].column+t[0].colspan-1,e.cells.length);return E(o,(e=>e.element))}))})(r,e);return{upOrLeftCells:s,downOrRightCells:l}}))})(r,{selection:as(e)},l);((e,t,o,n,r)=>{e.dispatch("TableSelectionChange",{cells:t,start:o,finish:n,otherCells:r})})(e,t,o,n,a)}))}),(()=>(e=>{e.dispatch("TableSelectionClear")})(e)));var r;return e.on("init",(o=>{const r=e.getWin(),s=Dr(e),l=Or(e),a=((e,t,o,n)=>{const r=((e,t,o,n)=>{const r=Gi(),s=r.clear,l=s=>{r.on((r=>{n.clearBeforeUpdate(t),Ki(s.target,o).each((l=>{Gr(r,l,o).each((o=>{const r=o.boxes.getOr([]);if(1===r.length){const o=r[0],l="false"===Ps(o),a=ut(js(s.target),o,ye);l&&a&&(n.selectRange(t,r,o,o),e.selectContents(o))}else r.length>1&&(n.selectRange(t,r,o.start,o.finish),e.selectContents(l))}))}))}))};return{clearstate:s,mousedown:e=>{n.clear(t),Ki(e.target,o).each(r.set)},mouseover:e=>{l(e)},mouseup:e=>{l(e),s()}}})(wm(e),t,o,n);return{clearstate:r.clearstate,mousedown:r.mousedown,mouseover:r.mouseover,mouseup:r.mouseup}})(r,s,l,n),c=((e,t,o,n)=>{const r=wm(e),s=()=>(n.clear(t),C.none());return{keydown:(e,l,a,c,i,m)=>{const d=e.raw,u=d.which,f=!0===d.shiftKey,g=Kr(t,n.selectedSelector).fold((()=>(em(u)&&!f&&n.clearBeforeUpdate(t),Zi(u)&&f?w($i,r,t,o,Yi,c,l,n.selectRange):Xi(u)&&f?w($i,r,t,o,Ji,c,l,n.selectRange):Zi(u)?w(Hi,r,o,Yi,c,l,Vi):Xi(u)?w(Hi,r,o,Ji,c,l,qi):C.none)),(e=>{const o=o=>()=>{const s=V(o,(o=>((e,t,o,n,r)=>Jr(n,e,t,r.firstSelectedSelector,r.lastSelectedSelector).map((e=>(r.clearBeforeUpdate(o),r.selectRange(o,e.boxes,e.start,e.finish),e.boxes))))(o.rows,o.cols,t,e,n)));return s.fold((()=>Yr(t,n.firstSelectedSelector,n.lastSelectedSelector).map((e=>{const o=Zi(u)||m.isForward(u)?Fc.after:Fc.before;return r.setRelativeSelection(Fc.on(e.first,0),o(e.table)),n.clear(t),Hc(C.none(),!0)}))),(e=>C.some(Hc(C.none(),!0))))};return Zi(u)&&f?o([bm(1,0)]):Xi(u)&&f?o([bm(-1,0)]):m.isBackward(u)&&f?o([bm(0,-1),bm(-1,0)]):m.isForward(u)&&f?o([bm(0,1),bm(1,0)]):em(u)&&!f?s:C.none}));return g()},keyup:(e,r,s,l,a)=>Kr(t,n.selectedSelector).fold((()=>{const c=e.raw,i=c.which;return!0===c.shiftKey&&em(i)?((e,t,o,n,r,s,l)=>ye(o,r)&&n===s?C.none():dt(o,"td,th",t).bind((o=>dt(r,"td,th",t).bind((n=>ni(e,t,o,n,l))))))(t,o,r,s,l,a,n.selectRange):C.none()}),C.none)}})(r,s,l,n),i=((e,t,o,n)=>{const r=wm(e);return(e,s)=>{n.clearBeforeUpdate(t),Gr(e,s,o).each((e=>{const o=e.boxes.getOr([]);n.selectRange(t,o,e.start,e.finish),r.selectContents(s),r.collapseSelection()}))}})(r,s,l,n);e.on("TableSelectorChange",(e=>i(e.start,e.finish)));const m=(t,o)=>{(e=>!0===e.raw.shiftKey)(t)&&(o.kill&&t.kill(),o.selection.each((t=>{const o=rm.relative(t.start,t.finish),n=Xc(r,o);e.selection.setRng(n)})))},d=e=>0===e.button,u=(()=>{const e=Ui(pe.fromDom(s)),t=Ui(0);return{touchEnd:o=>{const n=pe.fromDom(o.target);if(ae("td")(n)||ae("th")(n)){const r=e.get(),s=t.get();ye(r,n)&&o.timeStamp-s<300&&(o.preventDefault(),i(n,n))}e.set(n),t.set(o.timeStamp)}}})();e.on("dragstart",(e=>{a.clearstate()})),e.on("mousedown",(e=>{d(e)&&Bm(e)&&a.mousedown(Nm(e))})),e.on("mouseover",(e=>{var t;void 0!==(t=e).buttons&&0==(1&t.buttons)||!Bm(e)||a.mouseover(Nm(e))})),e.on("mouseup",(e=>{d(e)&&Bm(e)&&a.mouseup(Nm(e))})),e.on("touchend",u.touchEnd),e.on("keyup",(t=>{const o=Nm(t);if(o.raw.shiftKey&&em(o.raw.which)){const t=e.selection.getRng(),n=pe.fromDom(t.startContainer),r=pe.fromDom(t.endContainer);c.keyup(o,n,t.startOffset,r,t.endOffset).each((e=>{m(o,e)}))}})),e.on("keydown",(o=>{const n=Nm(o);t.hide();const r=e.selection.getRng(),s=pe.fromDom(r.startContainer),l=pe.fromDom(r.endContainer),a=rn(tm,om)(pe.fromDom(e.selection.getStart()));c.keydown(n,s,r.startOffset,l,r.endOffset,a).each((e=>{m(n,e)})),t.show()})),e.on("NodeChange",(()=>{const t=e.selection,o=pe.fromDom(t.getStart()),r=pe.fromDom(t.getEnd());$r(Ft,[o,r]).fold((()=>n.clear(s)),f)}))})),e.on("PreInit",(()=>{e.serializer.addTempAttr(os.firstSelected),e.serializer.addTempAttr(os.lastSelected)})),{getSelectedCells:()=>((e,t,o,n)=>{switch(e.tag){case"none":return t();case"single":return(e=>[e.dom])(e.element);case"multiple":return(e=>E(e,(e=>e.dom)))(e.elements)}})(o.get(),g([])),clearSelectedCells:e=>n.clear(pe.fromDom(e))}},Am=e=>{let t=[];return{bind:e=>{if(void 0===e)throw new Error("Event bind error: undefined handler");t.push(e)},unbind:e=>{t=z(t,(t=>t!==e))},trigger:(...o)=>{const n={};N(e,((e,t)=>{n[e]=o[t]})),N(t,(e=>{e(n)}))}}},Wm=e=>({registry:K(e,(e=>({bind:e.bind,unbind:e.unbind}))),trigger:K(e,(e=>e.trigger))}),Lm=e=>e.slice(0).sort(),_m=(e,t)=>{const o=z(t,(t=>!D(e,t)));o.length>0&&(e=>{throw new Error("Unsupported keys for object: "+Lm(e).join(", "))})(o)},Mm=e=>((e,t)=>((e,t,o)=>{if(0===t.length)throw new Error("You must specify at least one required field.");return((e,t)=>{if(!l(t))throw new Error("The required fields must be an array. Was: "+t+".");N(t,(t=>{if(!r(t))throw new Error("The value "+t+" in the "+e+" fields was not a string.")}))})("required",t),(e=>{const t=Lm(e);L(t,((e,o)=>o{throw new Error("The field: "+e+" occurs more than once in the combined fields: ["+t.join(", ")+"].")}))})(t),n=>{const r=$(n);I(t,(e=>D(r,e)))||((e,t)=>{throw new Error("All required keys ("+Lm(e).join(", ")+") were not specified. Specified keys were: "+Lm(t).join(", ")+".")})(t,r),e(t,r);const s=z(t,(e=>!o.validate(n[e],e)));return s.length>0&&((e,t)=>{throw new Error("All values need to be of type: "+t+". Keys ("+Lm(e).join(", ")+") were not.")})(s,o.label),n}})(e,t,{validate:d,label:"function"}))(_m,e),jm=Mm(["compare","extract","mutate","sink"]),Im=Mm(["element","start","stop","destroy"]),Pm=Mm(["forceDrop","drop","move","delayDrop"]),Fm=()=>{const e=(()=>{const e=Wm({move:Am(["info"])});return{onEvent:f,reset:f,events:e.registry}})(),t=(()=>{let e=C.none();const t=Wm({move:Am(["info"])});return{onEvent:(o,n)=>{n.extract(o).each((o=>{const r=((t,o)=>{const n=e.map((e=>t.compare(e,o)));return e=C.some(o),n})(n,o);r.each((e=>{t.trigger.move(e)}))}))},reset:()=>{e=C.none()},events:t.registry}})();let o=e;return{on:()=>{o.reset(),o=t},off:()=>{o.reset(),o=e},isOn:()=>o===t,onEvent:(e,t)=>{o.onEvent(e,t)},events:t.events}},Hm=e=>{const t=e.replace(/\./g,"-");return{resolve:e=>t+"-"+e}},qm=Hm("ephox-dragster").resolve;var Vm=jm({compare:(e,t)=>dn(t.left-e.left,t.top-e.top),extract:e=>C.some(dn(e.x,e.y)),sink:(e,t)=>{const o=(e=>{const t={layerClass:qm("blocker"),...e},o=pe.fromTag("div");return ie(o,"role","presentation"),Tt(o,{position:"fixed",left:"0px",top:"0px",width:"100%",height:"100%"}),xm(o,qm("blocker")),xm(o,t.layerClass),{element:g(o),destroy:()=>{Ie(o)}}})(t),n=Em(o.element(),"mousedown",e.forceDrop),r=Em(o.element(),"mouseup",e.drop),s=Em(o.element(),"mousemove",e.move),l=Em(o.element(),"mouseout",e.delayDrop);return Im({element:o.element,start:e=>{We(e,o.element())},stop:()=>{Ie(o.element())},destroy:()=>{o.destroy(),r.unbind(),s.unbind(),l.unbind(),n.unbind()}})},mutate:(e,t)=>{e.mutate(t.left,t.top)}});const $m=Hm("ephox-snooker").resolve,Um=$m("resizer-bar"),Gm=$m("resizer-rows"),Km=$m("resizer-cols"),Ym=e=>{const t=st(e.parent(),"."+Um);N(t,Ie)},Jm=(e,t,o)=>{const n=e.origin();N(t,(t=>{t.each((t=>{const r=o(n,t);xm(r,Um),We(e.parent(),r)}))}))},Qm=(e,t,o,n,r)=>{const s=fn(o),l=t.isResizable,a=n.length>0?Rn.positions(n,o):[],c=a.length>0?((e,t)=>j(e.all,((e,o)=>t(e.element)?[o]:[])))(e,l):[];((e,t,o,n)=>{Jm(e,t,((e,t)=>{const r=((e,t,o,n,r)=>{const s=pe.fromTag("div");return Tt(s,{position:"absolute",left:t+"px",top:o-3.5+"px",height:"7px",width:n+"px"}),me(s,{"data-row":e,role:"presentation"}),s})(t.row,o.left-e.left,t.y-e.top,n);return xm(r,Gm),r}))})(t,z(a,((e,t)=>O(c,(e=>t===e)))),s,Eo(o));const i=r.length>0?On.positions(r,o):[],m=i.length>0?((e,t)=>{const o=[];return k(e.grid.columns,(n=>{en(e,n).map((e=>e.element)).forall(t)&&o.push(n)})),z(o,(o=>{const n=Jo(e,(e=>e.column===o));return I(n,(e=>t(e.element)))}))})(e,l):[];((e,t,o,n)=>{Jm(e,t,((e,t)=>{const r=((e,t,o,n,r)=>{const s=pe.fromTag("div");return Tt(s,{position:"absolute",left:t-3.5+"px",top:o+"px",height:r+"px",width:"7px"}),me(s,{"data-column":e,role:"presentation"}),s})(t.col,t.x-e.left,o.top-e.top,0,n);return xm(r,Km),r}))})(t,z(i,((e,t)=>O(m,(e=>t===e)))),s,cn(o))},Xm=(e,t)=>{if(Ym(e),e.isResizable(t)){const o=Uo(t),n=nn(o),r=tn(o);Qm(o,e,t,n,r)}},Zm=(e,t)=>{const o=st(e.parent(),"."+Um);N(o,t)},ed=e=>{Zm(e,(e=>{St(e,"display","none")}))},td=e=>{Zm(e,(e=>{St(e,"display","block")}))},od=$m("resizer-bar-dragging"),nd=e=>{const t=(()=>{const e=Wm({drag:Am(["xDelta","yDelta","target"])});let t=C.none();const o=(()=>{const e=Wm({drag:Am(["xDelta","yDelta"])});return{mutate:(t,o)=>{e.trigger.drag(t,o)},events:e.registry}})();return o.events.drag.bind((o=>{t.each((t=>{e.trigger.drag(o.xDelta,o.yDelta,t)}))})),{assign:e=>{t=C.some(e)},get:()=>t,mutate:o.mutate,events:e.registry}})(),o=((e,t={})=>{var o;return((e,t,o)=>{let n=!1;const r=Wm({start:Am([]),stop:Am([])}),s=Fm(),l=()=>{m.stop(),s.isOn()&&(s.off(),r.trigger.stop())},c=((e,t)=>{let o=null;const n=()=>{a(o)||(clearTimeout(o),o=null)};return{cancel:n,throttle:(...t)=>{n(),o=setTimeout((()=>{o=null,e.apply(null,t)}),200)}}})(l);s.events.move.bind((o=>{t.mutate(e,o.info)}));const i=e=>(...t)=>{n&&e.apply(null,t)},m=t.sink(Pm({forceDrop:l,drop:i(l),move:i((e=>{c.cancel(),s.onEvent(e,t)})),delayDrop:i(c.throttle)}),o);return{element:m.element,go:e=>{m.start(e),s.on(),r.trigger.start()},on:()=>{n=!0},off:()=>{n=!1},destroy:()=>{m.destroy()},events:r.registry}})(e,null!==(o=t.mode)&&void 0!==o?o:Vm,t)})(t,{});let n=C.none();const r=(e,t)=>C.from(de(e,t));t.events.drag.bind((e=>{r(e.target,"data-row").each((t=>{const o=At(e.target,"top");St(e.target,"top",o+e.yDelta+"px")})),r(e.target,"data-column").each((t=>{const o=At(e.target,"left");St(e.target,"left",o+e.xDelta+"px")}))}));const s=(e,t)=>At(e,t)-Et(e,"data-initial-"+t,0);o.events.stop.bind((()=>{t.get().each((t=>{n.each((o=>{r(t,"data-row").each((e=>{const n=s(t,"top");fe(t,"data-initial-top"),d.trigger.adjustHeight(o,n,parseInt(e,10))})),r(t,"data-column").each((e=>{const n=s(t,"left");fe(t,"data-initial-left"),d.trigger.adjustWidth(o,n,parseInt(e,10))})),Xm(e,o)}))}))}));const l=(n,r)=>{d.trigger.startAdjust(),t.assign(n),ie(n,"data-initial-"+r,At(n,r)),xm(n,od),St(n,"opacity","0.2"),o.go(e.parent())},c=Em(e.parent(),"mousedown",(e=>{var t;t=e.target,Cm(t,Gm)&&l(e.target,"top"),(e=>Cm(e,Km))(e.target)&&l(e.target,"left")})),i=t=>ye(t,e.view()),m=Em(e.view(),"mouseover",(t=>{var o;(o=t.target,dt(o,"table",i).filter(Is)).fold((()=>{et(t.target)&&Ym(e)}),(t=>{n=C.some(t),Xm(e,t)}))})),d=Wm({adjustHeight:Am(["table","delta","row"]),adjustWidth:Am(["table","delta","column"]),startAdjust:Am([])});return{destroy:()=>{c.unbind(),m.unbind(),o.destroy(),Ym(e)},refresh:t=>{Xm(e,t)},on:o.on,off:o.off,hideBars:w(ed,e),showBars:w(td,e),events:d.registry}},rd=(e,t,o)=>{const n=Rn,r=On,s=nd(e),l=Wm({beforeResize:Am(["table","type"]),afterResize:Am(["table","type"]),startDrag:Am([])});return s.events.adjustHeight.bind((e=>{const t=e.table;l.trigger.beforeResize(t,"row");((e,t,o,n)=>{const r=Uo(e),s=((e,t,o)=>Zn(e,t,o,Hn,(e=>e.getOrThunk(Lt))))(r,e,n),l=E(s,((e,n)=>o===n?Math.max(t+e,Lt()):e)),a=Ol(r,l),c=((e,t)=>E(e.all,((e,o)=>({element:e.element,height:t[o]}))))(r,l);N(c,(e=>{_n(e.element,e.height)})),N(a,(e=>{_n(e.element,e.height)}));const i=A(l,((e,t)=>e+t),0);_n(e,i)})(t,n.delta(e.delta,t),e.row,n),l.trigger.afterResize(t,"row")})),s.events.startAdjust.bind((e=>{l.trigger.startDrag()})),s.events.adjustWidth.bind((e=>{const n=e.table;l.trigger.beforeResize(n,"col");const s=r.delta(e.delta,n),a=o(n);El(n,s,e.column,t,a),l.trigger.afterResize(n,"col")})),{on:s.on,off:s.off,refreshBars:s.refresh,hideBars:s.hideBars,showBars:s.showBars,destroy:s.destroy,events:l.registry}},sd=e=>m(e)&&"TABLE"===e.nodeName,ld="bar-",ad=e=>"false"!==de(e,"data-mce-resize"),cd=e=>{const t=Gi(),o=Gi(),n=Gi();let r,s;const l=t=>ec(e,t),a=()=>Va(e)?Cs():xs();return e.on("init",(()=>{const r=((e,t)=>e.inline?((e,t,o)=>({parent:g(t),view:g(e),origin:g(dn(0,0)),isResizable:o}))(pe.fromDom(e.getBody()),(()=>{const e=pe.fromTag("div");return Tt(e,{position:"static",height:"0",width:"0",padding:"0",margin:"0",border:"0"}),We(tt(pe.fromDom(document)),e),e})(),t):((e,t)=>{const o=se(e)?(e=>pe.fromDom(Te(e).dom.documentElement))(e):e;return{parent:g(o),view:g(e),origin:g(dn(0,0)),isResizable:t}})(pe.fromDom(e.getDoc()),t))(e,ad);if(n.set(r),(e=>{const t=e.options.get("object_resizing");return D(t.split(","),"table")})(e)&&Ja(e)){const n=a(),s=rd(r,n,l);s.on(),s.events.startDrag.bind((o=>{t.set(e.selection.getRng())})),s.events.beforeResize.bind((t=>{const o=t.table.dom;((e,t,o,n,r)=>{e.dispatch("ObjectResizeStart",{target:t,width:o,height:n,origin:r})})(e,o,Nr(o),Br(o),ld+t.type)})),s.events.afterResize.bind((o=>{const n=o.table,r=n.dom;kr(n),t.on((t=>{e.selection.setRng(t),e.focus()})),((e,t,o,n,r)=>{e.dispatch("ObjectResized",{target:t,width:o,height:n,origin:r})})(e,r,Nr(r),Br(r),ld+o.type),e.undoManager.add()})),o.set(s)}})),e.on("ObjectResizeStart",(t=>{const o=t.target;if(sd(o)){const n=pe.fromDom(o);N(e.dom.select(".mce-clonedresizable"),(t=>{e.dom.addClass(t,"mce-"+qa(e)+"-columns")})),!hc(n)&&Ka(e)?vc(n):!gc(n)&&Ga(e)&&bc(n),pc(n)&&wt(t.origin,ld)&&bc(n),r=t.width,s=Ya(e)?"":((e,t)=>{const o=e.dom.getStyle(t,"width")||e.dom.getAttrib(t,"width");return C.from(o).filter(yt)})(e,o).getOr("")}})),e.on("ObjectResized",(t=>{const o=t.target;if(sd(o)){const n=pe.fromDom(o),c=t.origin;wt(c,"corner-")&&((t,o,n)=>{const c=bt(o,"e");if(""===s&&bc(t),n!==r&&""!==s){St(t,"width",s);const o=a(),i=l(t),m=Va(e)||c?(e=>Ss(e).columns)(t)-1:0;El(t,n-r,m,o,i)}else if((e=>/^(\d+(\.\d+)?)%$/.test(e))(s)){const e=parseFloat(s.replace("%",""));St(t,"width",n*e/r+"%")}(e=>/^(\d+(\.\d+)?)px$/.test(e))(s)&&(e=>{const t=Uo(e);Zo(t)||N(It(e),(e=>{const t=Rt(e,"width");St(e,"width",t),fe(e,"width")}))})(t)})(n,c,t.width),kr(n),Wa(e,n.dom,La)}})),e.on("SwitchMode",(()=>{o.on((t=>{e.mode.isReadOnly()?t.hideBars():t.showBars()}))})),e.on("remove",(()=>{o.on((e=>{e.destroy()})),n.on((t=>{((e,t)=>{e.inline&&Ie(t.parent())})(e,t)}))})),{refresh:e=>{o.on((t=>t.refreshBars(pe.fromDom(e))))},hide:()=>{o.on((e=>e.hideBars()))},show:()=>{o.on((e=>e.showBars()))}}},id=e=>{(e=>{const t=e.options.register;t("table_clone_elements",{processor:"string[]"}),t("table_use_colgroups",{processor:"boolean",default:!0}),t("table_header_type",{processor:e=>{const t=D(["section","cells","sectionCells","auto"],e);return t?{value:e,valid:t}:{valid:!1,message:"Must be one of: section, cells, sectionCells or auto."}},default:"section"}),t("table_sizing_mode",{processor:"string",default:"auto"}),t("table_default_attributes",{processor:"object",default:{border:"1"}}),t("table_default_styles",{processor:"object",default:{"border-collapse":"collapse"}}),t("table_column_resizing",{processor:e=>{const t=D(["preservetable","resizetable"],e);return t?{value:e,valid:t}:{valid:!1,message:"Must be preservetable, or resizetable."}},default:"preservetable"}),t("table_resize_bars",{processor:"boolean",default:!0}),t("table_style_by_css",{processor:"boolean",default:!0})})(e);const t=cd(e),o=zm(e,t),n=tc(e,t,o);return Ic(e,n),((e,t)=>{const o=Or(e),n=t=>ls(Er(e)).bind((n=>Ft(n,o).map((o=>{const r=ns(as(e),o,n);return t(o,r)})))).getOr("");G({mceTableRowType:()=>n(t.getTableRowType),mceTableCellType:()=>n(t.getTableCellType),mceTableColType:()=>n(t.getTableColType)},((t,o)=>e.addQueryValueHandler(o,t)))})(e,n),cs(e,n),{getSelectedCells:o.getSelectedCells,clearSelectedCells:o.clearSelectedCells}};e.add("dom",(e=>({table:id(e)})))}(); \ No newline at end of file diff --git a/static/js/tinymce/plugins/advlist/plugin.min.js b/static/js/tinymce/plugins/advlist/plugin.min.js new file mode 100644 index 0000000..5af99b5 --- /dev/null +++ b/static/js/tinymce/plugins/advlist/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.2.0 (2022-09-08) + */ +!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=(t,e,r)=>{const s="UL"===e?"InsertUnorderedList":"InsertOrderedList";t.execCommand(s,!1,!1===r?null:{"list-style-type":r})},r=t=>e=>e.options.get(t),s=r("advlist_number_styles"),n=r("advlist_bullet_styles"),l=t=>null==t,i=t=>!l(t);var o=tinymce.util.Tools.resolve("tinymce.util.Tools");class a{constructor(t,e){this.tag=t,this.value=e}static some(t){return new a(!0,t)}static none(){return a.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?a.some(t(this.value)):a.none()}bind(t){return this.tag?t(this.value):a.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:a.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return i(t)?a.some(t):a.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}a.singletonNone=new a(!1);const u=t=>i(t)&&/^(TH|TD)$/.test(t.nodeName),d=t=>l(t)||"default"===t?"":t,g=(t,e)=>r=>{const s=s=>{r.setActive(((t,e,r)=>{const s=((t,e)=>{for(let r=0;re=>i(e)&&/^(OL|UL|DL)$/.test(e.nodeName)&&((t,e)=>t.dom.isChildOf(e,t.getBody()))(t,e))(t));return l.length>0&&l[0].nodeName===r})(t,s,e)),r.setEnabled(!((t,e)=>{const r=t.dom.getParent(e,"ol,ul,dl");return((t,e)=>null!==e&&"false"===t.dom.getContentEditableParent(e))(t,r)})(t,s.element))};return t.on("NodeChange",s),()=>t.off("NodeChange",s)},h=(t,r,s,n,l,i)=>{i.length>1?((t,r,s,n,l,i)=>{t.ui.registry.addSplitButton(r,{tooltip:s,icon:"OL"===l?"ordered-list":"unordered-list",presets:"listpreview",columns:3,fetch:t=>{t(o.map(i,(t=>{const e="OL"===l?"num":"bull",r="disc"===t||"decimal"===t?"default":t,s=d(t),n=(t=>t.replace(/\-/g," ").replace(/\b\w/g,(t=>t.toUpperCase())))(t);return{type:"choiceitem",value:s,icon:"list-"+e+"-"+r,text:n}})))},onAction:()=>t.execCommand(n),onItemAction:(r,s)=>{e(t,l,s)},select:e=>{const r=(t=>{const e=t.dom.getParent(t.selection.getNode(),"ol,ul"),r=t.dom.getStyle(e,"listStyleType");return a.from(r)})(t);return r.map((t=>e===t)).getOr(!1)},onSetup:g(t,l)})})(t,r,s,n,l,i):((t,r,s,n,l,i)=>{t.ui.registry.addToggleButton(r,{active:!1,tooltip:s,icon:"OL"===l?"ordered-list":"unordered-list",onSetup:g(t,l),onAction:()=>t.queryCommandState(n)||""===i?t.execCommand(n):e(t,l,i)})})(t,r,s,n,l,d(i[0]))};t.add("advlist",(t=>{t.hasPlugin("lists")?((t=>{const e=t.options.register;e("advlist_number_styles",{processor:"string[]",default:"default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman".split(",")}),e("advlist_bullet_styles",{processor:"string[]",default:"default,circle,square".split(",")})})(t),(t=>{h(t,"numlist","Numbered list","InsertOrderedList","OL",s(t)),h(t,"bullist","Bullet list","InsertUnorderedList","UL",n(t))})(t),(t=>{t.addCommand("ApplyUnorderedListStyle",((r,s)=>{e(t,"UL",s["list-style-type"])})),t.addCommand("ApplyOrderedListStyle",((r,s)=>{e(t,"OL",s["list-style-type"])}))})(t)):console.error("Please use the Lists plugin together with the Advanced List plugin.")}))}(); \ No newline at end of file diff --git a/static/js/tinymce/plugins/anchor/plugin.min.js b/static/js/tinymce/plugins/anchor/plugin.min.js new file mode 100644 index 0000000..fa21014 --- /dev/null +++ b/static/js/tinymce/plugins/anchor/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.2.0 (2022-09-08) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.dom.RangeUtils"),o=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=("allow_html_in_named_anchor",e=>e.options.get("allow_html_in_named_anchor"));const a="a:not([href])",r=e=>!e,i=e=>e.getAttribute("id")||e.getAttribute("name")||"",l=e=>(e=>"a"===e.nodeName.toLowerCase())(e)&&!e.getAttribute("href")&&""!==i(e),s=e=>e.dom.getParent(e.selection.getStart(),a),d=(e,a)=>{const r=s(e);r?((e,t,o)=>{o.removeAttribute("name"),o.id=t,e.addVisual(),e.undoManager.add()})(e,a,r):((e,a)=>{e.undoManager.transact((()=>{n(e)||e.selection.collapse(!0),e.selection.isCollapsed()?e.insertContent(e.dom.createHTML("a",{id:a})):((e=>{const n=e.dom;t(n).walk(e.selection.getRng(),(e=>{o.each(e,(e=>{var t;l(t=e)&&!t.firstChild&&n.remove(e,!1)}))}))})(e),e.formatter.remove("namedAnchor",void 0,void 0,!0),e.formatter.apply("namedAnchor",{value:a}),e.addVisual())}))})(e,a),e.focus()},c=e=>(e=>r(e.attr("href"))&&!r(e.attr("id")||e.attr("name")))(e)&&!e.firstChild,m=e=>t=>{for(let o=0;o{(e=>{(0,e.options.register)("allow_html_in_named_anchor",{processor:"boolean",default:!1})})(e),(e=>{e.on("PreInit",(()=>{e.parser.addNodeFilter("a",m("false")),e.serializer.addNodeFilter("a",m(null))}))})(e),(e=>{e.addCommand("mceAnchor",(()=>{(e=>{const t=(e=>{const t=s(e);return t?i(t):""})(e);e.windowManager.open({title:"Anchor",size:"normal",body:{type:"panel",items:[{name:"id",type:"input",label:"ID",placeholder:"example"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{id:t},onSubmit:t=>{((e,t)=>/^[A-Za-z][A-Za-z0-9\-:._]*$/.test(t)?(d(e,t),!0):(e.windowManager.alert("ID should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores."),!1))(e,t.getData().id)&&t.close()}})})(e)}))})(e),(e=>{const t=()=>e.execCommand("mceAnchor");e.ui.registry.addToggleButton("anchor",{icon:"bookmark",tooltip:"Anchor",onAction:t,onSetup:t=>e.selection.selectorChangedWithUnbind("a:not([href])",t.setActive).unbind}),e.ui.registry.addMenuItem("anchor",{icon:"bookmark",text:"Anchor...",onAction:t})})(e),e.on("PreInit",(()=>{(e=>{e.formatter.register("namedAnchor",{inline:"a",selector:a,remove:"all",split:!0,deep:!0,attributes:{id:"%value"},onmatch:(e,t,o)=>l(e)})})(e)}))}))}(); \ No newline at end of file diff --git a/static/js/tinymce/plugins/autolink/plugin.min.js b/static/js/tinymce/plugins/autolink/plugin.min.js new file mode 100644 index 0000000..9362b94 --- /dev/null +++ b/static/js/tinymce/plugins/autolink/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.2.0 (2022-09-08) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>t.options.get(e),n=t("autolink_pattern"),o=t("link_default_target"),r=t("link_default_protocol"),a=t("allow_unsafe_link_target"),s=("string",e=>"string"===(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=o=e,(r=String).prototype.isPrototypeOf(n)||(null===(a=o.constructor)||void 0===a?void 0:a.name)===r.name)?"string":t;var n,o,r,a})(e));const l=(void 0,e=>undefined===e);const i=e=>!(e=>null==e)(e),c=Object.hasOwnProperty,d=e=>"\ufeff"===e;var u=tinymce.util.Tools.resolve("tinymce.dom.TextSeeker");const f=e=>/^[(\[{ \u00a0]$/.test(e),g=(e,t,n)=>{for(let o=t-1;o>=0;o--){const t=e.charAt(o);if(!d(t)&&n(t))return o}return-1},m=(e,t)=>{var o;const a=e.schema.getVoidElements(),s=n(e),{dom:i,selection:d}=e;if(null!==i.getParent(d.getNode(),"a[href]"))return null;const m=d.getRng(),k=u(i,(e=>{return i.isBlock(e)||(t=a,n=e.nodeName.toLowerCase(),c.call(t,n))||"false"===i.getContentEditable(e);var t,n})),{container:p,offset:y}=((e,t)=>{let n=e,o=t;for(;1===n.nodeType&&n.childNodes[o];)n=n.childNodes[o],o=3===n.nodeType?n.data.length:n.childNodes.length;return{container:n,offset:o}})(m.endContainer,m.endOffset),h=null!==(o=i.getParent(p,i.isBlock))&&void 0!==o?o:i.getRoot(),w=k.backwards(p,y+t,((e,t)=>{const n=e.data,o=g(n,t,(r=f,e=>!r(e)));var r,a;return-1===o||(a=n[o],/[?!,.;:]/.test(a))?o:o+1}),h);if(!w)return null;let v=w.container;const _=k.backwards(w.container,w.offset,((e,t)=>{v=e;const n=g(e.data,t,f);return-1===n?n:n+1}),h),A=i.createRng();_?A.setStart(_.container,_.offset):A.setStart(v,0),A.setEnd(w.container,w.offset);const C=A.toString().replace(/\uFEFF/g,"").match(s);if(C){let t=C[0];return $="www.",(b=t).length>=$.length&&b.substr(0,0+$.length)===$?t=r(e)+"://"+t:((e,t,n=0,o)=>{const r=e.indexOf(t,n);return-1!==r&&(!!l(o)||r+t.length<=o)})(t,"@")&&!(e=>/^([A-Za-z][A-Za-z\d.+-]*:\/\/)|mailto:/.test(e))(t)&&(t="mailto:"+t),{rng:A,url:t}}var b,$;return null},k=(e,t)=>{const{dom:n,selection:r}=e,{rng:l,url:i}=t,c=r.getBookmark();r.setRng(l);const d="createlink",u={command:d,ui:!1,value:i};if(!e.dispatch("BeforeExecCommand",u).isDefaultPrevented()){e.getDoc().execCommand(d,!1,i),e.dispatch("ExecCommand",u);const t=o(e);if(s(t)){const o=r.getNode();n.setAttrib(o,"target",t),"_blank"!==t||a(e)||n.setAttrib(o,"rel","noopener")}}r.moveToBookmark(c),e.nodeChanged()},p=e=>{const t=m(e,-1);i(t)&&k(e,t)},y=p;e.add("autolink",(e=>{(e=>{const t=e.options.register;t("autolink_pattern",{processor:"regexp",default:new RegExp("^"+/(?:[A-Za-z][A-Za-z\d.+-]{0,14}:\/\/(?:[-.~*+=!&;:'%@?^${}(),\w]+@)?|www\.|[-;:&=+$,.\w]+@)[A-Za-z\d-]+(?:\.[A-Za-z\d-]+)*(?::\d+)?(?:\/(?:[-.~*+=!;:'%@$(),\/\w]*[-~*+=%@$()\/\w])?)?(?:\?(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?(?:#(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?/g.source+"$","i")}),t("link_default_target",{processor:"string"}),t("link_default_protocol",{processor:"string",default:"https"})})(e),(e=>{e.on("keydown",(t=>{13!==t.keyCode||t.isDefaultPrevented()||(e=>{const t=m(e,0);i(t)&&k(e,t)})(e)})),e.on("keyup",(t=>{32===t.keyCode?p(e):(48===t.keyCode&&t.shiftKey||221===t.keyCode)&&y(e)}))})(e)}))}(); \ No newline at end of file diff --git a/static/js/tinymce/plugins/autoresize/plugin.min.js b/static/js/tinymce/plugins/autoresize/plugin.min.js new file mode 100644 index 0000000..43b3005 --- /dev/null +++ b/static/js/tinymce/plugins/autoresize/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.2.0 (2022-09-08) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.Env");const o=e=>t=>t.options.get(e),n=o("min_height"),s=o("max_height"),i=o("autoresize_overflow_padding"),r=o("autoresize_bottom_margin"),l=(e,t)=>{const o=e.getBody();o&&(o.style.overflowY=t?"":"hidden",t||(o.scrollTop=0))},a=(e,t,o,n)=>{var s;const i=parseInt(null!==(s=e.getStyle(t,o,n))&&void 0!==s?s:"",10);return isNaN(i)?0:i},g=(e,o,i)=>{var c;const u=e.dom,d=e.getDoc();if(!d)return;if((e=>e.plugins.fullscreen&&e.plugins.fullscreen.isFullscreen())(e))return void l(e,!0);const f=d.documentElement,m=r(e),p=null!==(c=n(e))&&void 0!==c?c:e.getElement().offsetHeight;let h=p;const v=a(u,f,"margin-top",!0),y=a(u,f,"margin-bottom",!0);let C=f.offsetHeight+v+y+m;C<0&&(C=0);const S=e.getContainer().offsetHeight-e.getContentAreaContainer().offsetHeight;C+S>p&&(h=C+S);const z=s(e);if(z&&h>z?(h=z,l(e,!0)):l(e,!1),h!==o.get()){const n=h-o.get();if(u.setStyle(e.getContainer(),"height",h+"px"),o.set(h),(e=>{e.dispatch("ResizeEditor")})(e),t.browser.isSafari()&&(t.os.isMacOS()||t.os.isiOS())){const t=e.getWin();t.scrollTo(t.pageXOffset,t.pageYOffset)}e.hasFocus()&&(e=>{if("setcontent"===(null==e?void 0:e.type.toLowerCase())){const t=e;return!0===t.selection||!0===t.paste}return!1})(i)&&e.selection.scrollIntoView(),(t.browser.isSafari()||t.browser.isChromium())&&n<0&&g(e,o,i)}};e.add("autoresize",(e=>{if((e=>{const t=e.options.register;t("autoresize_overflow_padding",{processor:"number",default:1}),t("autoresize_bottom_margin",{processor:"number",default:50})})(e),e.options.isSet("resize")||e.options.set("resize",!1),!e.inline){const t=(e=>{let t=0;return{get:()=>t,set:e=>{t=e}}})();((e,t)=>{e.addCommand("mceAutoResize",(()=>{g(e,t)}))})(e,t),((e,t)=>{e.on("init",(()=>{const t=i(e),o=e.dom;o.setStyles(e.getDoc().documentElement,{height:"auto"}),o.setStyles(e.getBody(),{paddingLeft:t,paddingRight:t,"min-height":0})})),e.on("NodeChange SetContent keyup FullscreenStateChanged ResizeContent",(o=>{g(e,t,o)}))})(e,t)}}))}(); \ No newline at end of file diff --git a/static/js/tinymce/plugins/autosave/plugin.min.js b/static/js/tinymce/plugins/autosave/plugin.min.js new file mode 100644 index 0000000..19a6f16 --- /dev/null +++ b/static/js/tinymce/plugins/autosave/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.2.0 (2022-09-08) + */ +!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=("string",t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(r=o=t,(a=String).prototype.isPrototypeOf(r)||(null===(s=o.constructor)||void 0===s?void 0:s.name)===a.name)?"string":e;var r,o,a,s})(t));const r=(void 0,t=>undefined===t);var o=tinymce.util.Tools.resolve("tinymce.util.Delay"),a=tinymce.util.Tools.resolve("tinymce.util.LocalStorage"),s=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=t=>{const e=/^(\d+)([ms]?)$/.exec(t);return(e&&e[2]?{s:1e3,m:6e4}[e[2]]:1)*parseInt(t,10)},i=t=>e=>e.options.get(t),u=i("autosave_ask_before_unload"),l=i("autosave_restore_when_empty"),c=i("autosave_interval"),d=i("autosave_retention"),m=t=>{const e=document.location;return t.options.get("autosave_prefix").replace(/{path}/g,e.pathname).replace(/{query}/g,e.search).replace(/{hash}/g,e.hash).replace(/{id}/g,t.id)},v=(t,e)=>{if(r(e))return t.dom.isEmpty(t.getBody());{const r=s.trim(e);if(""===r)return!0;{const e=(new DOMParser).parseFromString(r,"text/html");return t.dom.isEmpty(e)}}},f=t=>{var e;const r=parseInt(null!==(e=a.getItem(m(t)+"time"))&&void 0!==e?e:"0",10)||0;return!((new Date).getTime()-r>d(t)&&(p(t,!1),1))},p=(t,e)=>{const r=m(t);a.removeItem(r+"draft"),a.removeItem(r+"time"),!1!==e&&(t=>{t.dispatch("RemoveDraft")})(t)},g=t=>{const e=m(t);!v(t)&&t.isDirty()&&(a.setItem(e+"draft",t.getContent({format:"raw",no_events:!0})),a.setItem(e+"time",(new Date).getTime().toString()),(t=>{t.dispatch("StoreDraft")})(t))},y=t=>{var e;const r=m(t);f(t)&&(t.setContent(null!==(e=a.getItem(r+"draft"))&&void 0!==e?e:"",{format:"raw"}),(t=>{t.dispatch("RestoreDraft")})(t))};var D=tinymce.util.Tools.resolve("tinymce.EditorManager");const h=t=>e=>{e.setEnabled(f(t));const r=()=>e.setEnabled(f(t));return t.on("StoreDraft RestoreDraft RemoveDraft",r),()=>t.off("StoreDraft RestoreDraft RemoveDraft",r)};t.add("autosave",(t=>((t=>{const r=t.options.register,o=t=>{const r=e(t);return r?{value:n(t),valid:r}:{valid:!1,message:"Must be a string."}};r("autosave_ask_before_unload",{processor:"boolean",default:!0}),r("autosave_prefix",{processor:"string",default:"tinymce-autosave-{path}{query}{hash}-{id}-"}),r("autosave_restore_when_empty",{processor:"boolean",default:!1}),r("autosave_interval",{processor:o,default:"30s"}),r("autosave_retention",{processor:o,default:"20m"})})(t),(t=>{t.editorManager.on("BeforeUnload",(t=>{let e;s.each(D.get(),(t=>{t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&u(t)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))})),e&&(t.preventDefault(),t.returnValue=e)}))})(t),(t=>{(t=>{const e=c(t);o.setEditorInterval(t,(()=>{g(t)}),e)})(t);const e=()=>{(t=>{t.undoManager.transact((()=>{y(t),p(t)})),t.focus()})(t)};t.ui.registry.addButton("restoredraft",{tooltip:"Restore last draft",icon:"restore-draft",onAction:e,onSetup:h(t)}),t.ui.registry.addMenuItem("restoredraft",{text:"Restore last draft",icon:"restore-draft",onAction:e,onSetup:h(t)})})(t),t.on("init",(()=>{l(t)&&t.dom.isEmpty(t.getBody())&&y(t)})),(t=>({hasDraft:()=>f(t),storeDraft:()=>g(t),restoreDraft:()=>y(t),removeDraft:e=>p(t,e),isEmpty:e=>v(t,e)}))(t))))}(); \ No newline at end of file diff --git a/static/js/tinymce/plugins/charmap/plugin.min.js b/static/js/tinymce/plugins/charmap/plugin.min.js new file mode 100644 index 0000000..d2dac7f --- /dev/null +++ b/static/js/tinymce/plugins/charmap/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.2.0 (2022-09-08) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=(e,t)=>{const r=((e,t)=>e.dispatch("insertCustomChar",{chr:t}))(e,t).chr;e.execCommand("mceInsertContent",!1,r)},r=e=>t=>e===t,a=("array",e=>"array"===(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(r=a=e,(n=String).prototype.isPrototypeOf(r)||(null===(i=a.constructor)||void 0===i?void 0:i.name)===n.name)?"string":t;var r,a,n,i})(e));const n=r(null),i=r(void 0),o=e=>"function"==typeof e,s=(!1,()=>false);class l{constructor(e,t){this.tag=e,this.value=t}static some(e){return new l(!0,e)}static none(){return l.singletonNone}fold(e,t){return this.tag?t(this.value):e()}isSome(){return this.tag}isNone(){return!this.tag}map(e){return this.tag?l.some(e(this.value)):l.none()}bind(e){return this.tag?e(this.value):l.none()}exists(e){return this.tag&&e(this.value)}forall(e){return!this.tag||e(this.value)}filter(e){return!this.tag||e(this.value)?this:l.none()}getOr(e){return this.tag?this.value:e}or(e){return this.tag?this:e}getOrThunk(e){return this.tag?this.value:e()}orThunk(e){return this.tag?this:e()}getOrDie(e){if(this.tag)return this.value;throw new Error(null!=e?e:"Called getOrDie on None")}static from(e){return null==e?l.none():l.some(e)}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(e){this.tag&&e(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}l.singletonNone=new l(!1);const c=Array.prototype.push,u=(e,t)=>{const r=e.length,a=new Array(r);for(let n=0;nt=>t.options.get(e),m=h("charmap"),p=h("charmap_append"),d=g.isArray,f="User Defined",y=e=>{return d(e)?(t=e,g.grep(t,(e=>d(e)&&2===e.length))):"function"==typeof e?e():[];var t},w=e=>{const t=((e,t)=>{const r=m(e);r&&(t=[{name:f,characters:y(r)}]);const a=p(e);if(a){const e=g.grep(t,(e=>e.name===f));return e.length?(e[0].characters=[...e[0].characters,...y(a)],t):t.concat({name:f,characters:y(a)})}return t})(e,[{name:"Currency",characters:[[36,"dollar sign"],[162,"cent sign"],[8364,"euro sign"],[163,"pound sign"],[165,"yen sign"],[164,"currency sign"],[8352,"euro-currency sign"],[8353,"colon sign"],[8354,"cruzeiro sign"],[8355,"french franc sign"],[8356,"lira sign"],[8357,"mill sign"],[8358,"naira sign"],[8359,"peseta sign"],[8360,"rupee sign"],[8361,"won sign"],[8362,"new sheqel sign"],[8363,"dong sign"],[8365,"kip sign"],[8366,"tugrik sign"],[8367,"drachma sign"],[8368,"german penny symbol"],[8369,"peso sign"],[8370,"guarani sign"],[8371,"austral sign"],[8372,"hryvnia sign"],[8373,"cedi sign"],[8374,"livre tournois sign"],[8375,"spesmilo sign"],[8376,"tenge sign"],[8377,"indian rupee sign"],[8378,"turkish lira sign"],[8379,"nordic mark sign"],[8380,"manat sign"],[8381,"ruble sign"],[20870,"yen character"],[20803,"yuan character"],[22291,"yuan character, in hong kong and taiwan"],[22278,"yen/yuan character variant one"]]},{name:"Text",characters:[[169,"copyright sign"],[174,"registered sign"],[8482,"trade mark sign"],[8240,"per mille sign"],[181,"micro sign"],[183,"middle dot"],[8226,"bullet"],[8230,"three dot leader"],[8242,"minutes / feet"],[8243,"seconds / inches"],[167,"section sign"],[182,"paragraph sign"],[223,"sharp s / ess-zed"]]},{name:"Quotations",characters:[[8249,"single left-pointing angle quotation mark"],[8250,"single right-pointing angle quotation mark"],[171,"left pointing guillemet"],[187,"right pointing guillemet"],[8216,"left single quotation mark"],[8217,"right single quotation mark"],[8220,"left double quotation mark"],[8221,"right double quotation mark"],[8218,"single low-9 quotation mark"],[8222,"double low-9 quotation mark"],[60,"less-than sign"],[62,"greater-than sign"],[8804,"less-than or equal to"],[8805,"greater-than or equal to"],[8211,"en dash"],[8212,"em dash"],[175,"macron"],[8254,"overline"],[164,"currency sign"],[166,"broken bar"],[168,"diaeresis"],[161,"inverted exclamation mark"],[191,"turned question mark"],[710,"circumflex accent"],[732,"small tilde"],[176,"degree sign"],[8722,"minus sign"],[177,"plus-minus sign"],[247,"division sign"],[8260,"fraction slash"],[215,"multiplication sign"],[185,"superscript one"],[178,"superscript two"],[179,"superscript three"],[188,"fraction one quarter"],[189,"fraction one half"],[190,"fraction three quarters"]]},{name:"Mathematical",characters:[[402,"function / florin"],[8747,"integral"],[8721,"n-ary sumation"],[8734,"infinity"],[8730,"square root"],[8764,"similar to"],[8773,"approximately equal to"],[8776,"almost equal to"],[8800,"not equal to"],[8801,"identical to"],[8712,"element of"],[8713,"not an element of"],[8715,"contains as member"],[8719,"n-ary product"],[8743,"logical and"],[8744,"logical or"],[172,"not sign"],[8745,"intersection"],[8746,"union"],[8706,"partial differential"],[8704,"for all"],[8707,"there exists"],[8709,"diameter"],[8711,"backward difference"],[8727,"asterisk operator"],[8733,"proportional to"],[8736,"angle"]]},{name:"Extended Latin",characters:[[192,"A - grave"],[193,"A - acute"],[194,"A - circumflex"],[195,"A - tilde"],[196,"A - diaeresis"],[197,"A - ring above"],[256,"A - macron"],[198,"ligature AE"],[199,"C - cedilla"],[200,"E - grave"],[201,"E - acute"],[202,"E - circumflex"],[203,"E - diaeresis"],[274,"E - macron"],[204,"I - grave"],[205,"I - acute"],[206,"I - circumflex"],[207,"I - diaeresis"],[298,"I - macron"],[208,"ETH"],[209,"N - tilde"],[210,"O - grave"],[211,"O - acute"],[212,"O - circumflex"],[213,"O - tilde"],[214,"O - diaeresis"],[216,"O - slash"],[332,"O - macron"],[338,"ligature OE"],[352,"S - caron"],[217,"U - grave"],[218,"U - acute"],[219,"U - circumflex"],[220,"U - diaeresis"],[362,"U - macron"],[221,"Y - acute"],[376,"Y - diaeresis"],[562,"Y - macron"],[222,"THORN"],[224,"a - grave"],[225,"a - acute"],[226,"a - circumflex"],[227,"a - tilde"],[228,"a - diaeresis"],[229,"a - ring above"],[257,"a - macron"],[230,"ligature ae"],[231,"c - cedilla"],[232,"e - grave"],[233,"e - acute"],[234,"e - circumflex"],[235,"e - diaeresis"],[275,"e - macron"],[236,"i - grave"],[237,"i - acute"],[238,"i - circumflex"],[239,"i - diaeresis"],[299,"i - macron"],[240,"eth"],[241,"n - tilde"],[242,"o - grave"],[243,"o - acute"],[244,"o - circumflex"],[245,"o - tilde"],[246,"o - diaeresis"],[248,"o slash"],[333,"o macron"],[339,"ligature oe"],[353,"s - caron"],[249,"u - grave"],[250,"u - acute"],[251,"u - circumflex"],[252,"u - diaeresis"],[363,"u - macron"],[253,"y - acute"],[254,"thorn"],[255,"y - diaeresis"],[563,"y - macron"],[913,"Alpha"],[914,"Beta"],[915,"Gamma"],[916,"Delta"],[917,"Epsilon"],[918,"Zeta"],[919,"Eta"],[920,"Theta"],[921,"Iota"],[922,"Kappa"],[923,"Lambda"],[924,"Mu"],[925,"Nu"],[926,"Xi"],[927,"Omicron"],[928,"Pi"],[929,"Rho"],[931,"Sigma"],[932,"Tau"],[933,"Upsilon"],[934,"Phi"],[935,"Chi"],[936,"Psi"],[937,"Omega"],[945,"alpha"],[946,"beta"],[947,"gamma"],[948,"delta"],[949,"epsilon"],[950,"zeta"],[951,"eta"],[952,"theta"],[953,"iota"],[954,"kappa"],[955,"lambda"],[956,"mu"],[957,"nu"],[958,"xi"],[959,"omicron"],[960,"pi"],[961,"rho"],[962,"final sigma"],[963,"sigma"],[964,"tau"],[965,"upsilon"],[966,"phi"],[967,"chi"],[968,"psi"],[969,"omega"]]},{name:"Symbols",characters:[[8501,"alef symbol"],[982,"pi symbol"],[8476,"real part symbol"],[978,"upsilon - hook symbol"],[8472,"Weierstrass p"],[8465,"imaginary part"]]},{name:"Arrows",characters:[[8592,"leftwards arrow"],[8593,"upwards arrow"],[8594,"rightwards arrow"],[8595,"downwards arrow"],[8596,"left right arrow"],[8629,"carriage return"],[8656,"leftwards double arrow"],[8657,"upwards double arrow"],[8658,"rightwards double arrow"],[8659,"downwards double arrow"],[8660,"left right double arrow"],[8756,"therefore"],[8834,"subset of"],[8835,"superset of"],[8836,"not a subset of"],[8838,"subset of or equal to"],[8839,"superset of or equal to"],[8853,"circled plus"],[8855,"circled times"],[8869,"perpendicular"],[8901,"dot operator"],[8968,"left ceiling"],[8969,"right ceiling"],[8970,"left floor"],[8971,"right floor"],[9001,"left-pointing angle bracket"],[9002,"right-pointing angle bracket"],[9674,"lozenge"],[9824,"black spade suit"],[9827,"black club suit"],[9829,"black heart suit"],[9830,"black diamond suit"],[8194,"en space"],[8195,"em space"],[8201,"thin space"],[8204,"zero width non-joiner"],[8205,"zero width joiner"],[8206,"left-to-right mark"],[8207,"right-to-left mark"]]}]);return t.length>1?[{name:"All",characters:(r=t,n=e=>e.characters,(e=>{const t=[];for(let r=0,n=e.length;r{let t=e;return{get:()=>t,set:e=>{t=e}}},b=(e,t,r=0,a)=>{const n=e.indexOf(t,r);return-1!==n&&(!!i(a)||n+t.length<=a)},k=String.fromCodePoint,C=(e,t)=>{const r=[],a=t.toLowerCase();return((e,t)=>{for(let t=0,i=e.length;t!!b(k(e).toLowerCase(),r)||b(t.toLowerCase(),r)||b(t.toLowerCase().replace(/\s+/g,""),r))((n=e[t])[0],n[1],a)&&r.push(n);var n})(e.characters),u(r,(e=>({text:e[1],value:k(e[0]),icon:k(e[0])})))},x="pattern",A=(e,r)=>{const a=()=>[{label:"Search",type:"input",name:x},{type:"collection",name:"results"}],i=1===r.length?v(f):v("All"),o=((e,t)=>{let r=null;const a=()=>{n(r)||(clearTimeout(r),r=null)};return{cancel:a,throttle:(...t)=>{a(),r=setTimeout((()=>{r=null,e.apply(null,t)}),40)}}})((e=>{const t=e.getData().pattern;((e,t)=>{var a,n;(a=r,n=e=>e.name===i.get(),((e,t,r)=>{for(let a=0,n=e.length;a{const a=C(r,t);e.setData({results:a})}))})(e,t)})),c={title:"Special Character",size:"normal",body:1===r.length?{type:"panel",items:a()}:{type:"tabpanel",tabs:u(r,(e=>({title:e.name,name:e.name,items:a()})))},buttons:[{type:"cancel",name:"close",text:"Close",primary:!0}],initialData:{pattern:"",results:C(r[0],"")},onAction:(r,a)=>{"results"===a.name&&(t(e,a.value),r.close())},onTabChange:(e,t)=>{i.set(t.newTabName),o.throttle(e)},onChange:(e,t)=>{t.name===x&&o.throttle(e)}};e.windowManager.open(c).focus(x)};e.add("charmap",(e=>{(e=>{const t=e.options.register,r=e=>o(e)||a(e);t("charmap",{processor:r}),t("charmap_append",{processor:r})})(e);const r=w(e);return((e,t)=>{e.addCommand("mceShowCharmap",(()=>{A(e,t)}))})(e,r),(e=>{const t=()=>e.execCommand("mceShowCharmap");e.ui.registry.addButton("charmap",{icon:"insert-character",tooltip:"Special character",onAction:t}),e.ui.registry.addMenuItem("charmap",{icon:"insert-character",text:"Special character...",onAction:t})})(e),((e,t)=>{e.ui.registry.addAutocompleter("charmap",{trigger:":",columns:"auto",minChars:2,fetch:(e,r)=>new Promise(((r,a)=>{r(C(t,e))})),onAction:(t,r,a)=>{e.selection.setRng(r),e.insertContent(a),t.hide()}})})(e,r[0]),(e=>({getCharMap:()=>w(e),insertChar:r=>{t(e,r)}}))(e)}))}(); \ No newline at end of file diff --git a/static/js/tinymce/plugins/code/plugin.min.js b/static/js/tinymce/plugins/code/plugin.min.js new file mode 100644 index 0000000..aadf390 --- /dev/null +++ b/static/js/tinymce/plugins/code/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.2.0 (2022-09-08) + */ +!function(){"use strict";tinymce.util.Tools.resolve("tinymce.PluginManager").add("code",(e=>((e=>{e.addCommand("mceCodeEditor",(()=>{(e=>{const o=(e=>e.getContent({source_view:!0}))(e);e.windowManager.open({title:"Source Code",size:"large",body:{type:"panel",items:[{type:"textarea",name:"code"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{code:o},onSubmit:o=>{((e,o)=>{e.focus(),e.undoManager.transact((()=>{e.setContent(o)})),e.selection.setCursorLocation(),e.nodeChanged()})(e,o.getData().code),o.close()}})})(e)}))})(e),(e=>{const o=()=>e.execCommand("mceCodeEditor");e.ui.registry.addButton("code",{icon:"sourcecode",tooltip:"Source code",onAction:o}),e.ui.registry.addMenuItem("code",{icon:"sourcecode",text:"Source code",onAction:o})})(e),{})))}(); \ No newline at end of file diff --git a/static/js/tinymce/plugins/codesample/plugin.min.js b/static/js/tinymce/plugins/codesample/plugin.min.js new file mode 100644 index 0000000..c0999db --- /dev/null +++ b/static/js/tinymce/plugins/codesample/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.2.0 (2022-09-08) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>!(e=>null==e)(e);class n{constructor(e,t){this.tag=e,this.value=t}static some(e){return new n(!0,e)}static none(){return n.singletonNone}fold(e,t){return this.tag?t(this.value):e()}isSome(){return this.tag}isNone(){return!this.tag}map(e){return this.tag?n.some(e(this.value)):n.none()}bind(e){return this.tag?e(this.value):n.none()}exists(e){return this.tag&&e(this.value)}forall(e){return!this.tag||e(this.value)}filter(e){return!this.tag||e(this.value)?this:n.none()}getOr(e){return this.tag?this.value:e}or(e){return this.tag?this:e}getOrThunk(e){return this.tag?this.value:e()}orThunk(e){return this.tag?this:e()}getOrDie(e){if(this.tag)return this.value;throw new Error(null!=e?e:"Called getOrDie on None")}static from(e){return t(e)?n.some(e):n.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(e){this.tag&&e(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}n.singletonNone=new n(!1);var a=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils");const s="undefined"!=typeof window?window:Function("return this;")(),r=function(e,t,n){const a=window.Prism;window.Prism={manual:!0};var s=function(e){var t=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,n=0,a={},s={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(t){return t instanceof r?new r(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);x+=_.value.length,_=_.next){var F=_.value;if(t.length>e.length)return;if(!(F instanceof r)){var A,S=1;if(y){if(!(A=i(v,x,e,m))||A.index>=e.length)break;var $=A.index,z=A.index+A[0].length,E=x;for(E+=_.value.length;$>=E;)E+=(_=_.next).value.length;if(x=E-=_.value.length,_.value instanceof r)continue;for(var C=_;C!==t.tail&&(Ed.reach&&(d.reach=O);var P=_.prev;if(B&&(P=u(t,P,B),x+=B.length),c(t,P,S),_=u(t,P,new r(g,f?s.tokenize(j,f):j,w,j)),T&&u(t,_,T),S>1){var N={cause:g+","+b,reach:O};o(e,t,n,_.prev,x,N),d&&N.reach>d.reach&&(d.reach=N.reach)}}}}}}function l(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function u(e,t,n){var a=t.next,s={value:n,prev:t,next:a};return t.next=s,a.prev=s,e.length++,s}function c(e,t,n){for(var a=t.next,s=0;s"+r.content+""},!e.document)return e.addEventListener?(s.disableWorkerMessageHandler||e.addEventListener("message",(function(t){var n=JSON.parse(t.data),a=n.language,r=n.code,i=n.immediateClose;e.postMessage(s.highlight(r,s.languages[a],a)),i&&e.close()}),!1),s):s;var d=s.util.currentScript();function g(){s.manual||s.highlightAll()}if(d&&(s.filename=d.src,d.hasAttribute("data-manual")&&(s.manual=!0)),!s.manual){var p=document.readyState;"loading"===p||"interactive"===p&&d&&d.defer?document.addEventListener("DOMContentLoaded",g):window.requestAnimationFrame?window.requestAnimationFrame(g):window.setTimeout(g,16)}return s}("undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{});return s.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,a,s,r){if(n.language===a){var i=n.tokenStack=[];n.code=n.code.replace(s,(function(e){if("function"==typeof r&&!r(e))return e;for(var s,o=i.length;-1!==n.code.indexOf(s=t(a,o));)++o;return i[o]=e,s})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,a){if(n.language===a&&n.tokenStack){n.grammar=e.languages[a];var s=0,r=Object.keys(n.tokenStack);!function i(o){for(var l=0;l=r.length);l++){var u=o[l];if("string"==typeof u||u.content&&"string"==typeof u.content){var c=r[s],d=n.tokenStack[c],g="string"==typeof u?u:u.content,p=t(a,c),b=g.indexOf(p);if(b>-1){++s;var h=g.substring(0,b),f=new e.Token(a,e.tokenize(d,n.grammar),"language-"+a,d),m=g.substring(b+p.length),y=[];h&&y.push.apply(y,i([h])),y.push(f),m&&y.push.apply(y,i([m])),"string"==typeof u?o.splice.apply(o,[l,1].concat(y)):u.content=y}}else u.content&&i(u.content)}return o}(n.tokens)}}}})}(s),s.languages.c=s.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),s.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),s.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},s.languages.c.string],char:s.languages.c.char,comment:s.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:s.languages.c}}}}),s.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete s.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(s),function(e){function t(e,t){return e.replace(/<<(\d+)>>/g,(function(e,n){return"(?:"+t[+n]+")"}))}function n(e,n,a){return RegExp(t(e,n),a||"")}function a(e,t){for(var n=0;n>/g,(function(){return"(?:"+e+")"}));return e.replace(/<>/g,"[^\\s\\S]")}var s="bool byte char decimal double dynamic float int long object sbyte short string uint ulong ushort var void",r="class enum interface record struct",i="add alias and ascending async await by descending from(?=\\s*(?:\\w|$)) get global group into init(?=\\s*;) join let nameof not notnull on or orderby partial remove select set unmanaged value when where with(?=\\s*{)",o="abstract as base break case catch checked const continue default delegate do else event explicit extern finally fixed for foreach goto if implicit in internal is lock namespace new null operator out override params private protected public readonly ref return sealed sizeof stackalloc static switch this throw try typeof unchecked unsafe using virtual volatile while yield";function l(e){return"\\b(?:"+e.trim().replace(/ /g,"|")+")\\b"}var u=l(r),c=RegExp(l(s+" "+r+" "+i+" "+o)),d=l(r+" "+i+" "+o),g=l(s+" "+r+" "+o),p=a(/<(?:[^<>;=+\-*/%&|^]|<>)*>/.source,2),b=a(/\((?:[^()]|<>)*\)/.source,2),h=/@?\b[A-Za-z_]\w*\b/.source,f=t(/<<0>>(?:\s*<<1>>)?/.source,[h,p]),m=t(/(?!<<0>>)<<1>>(?:\s*\.\s*<<1>>)*/.source,[d,f]),y=/\[\s*(?:,\s*)*\]/.source,w=t(/<<0>>(?:\s*(?:\?\s*)?<<1>>)*(?:\s*\?)?/.source,[m,y]),k=t(/[^,()<>[\];=+\-*/%&|^]|<<0>>|<<1>>|<<2>>/.source,[p,b,y]),v=t(/\(<<0>>+(?:,<<0>>+)+\)/.source,[k]),_=t(/(?:<<0>>|<<1>>)(?:\s*(?:\?\s*)?<<2>>)*(?:\s*\?)?/.source,[v,m,y]),x={keyword:c,punctuation:/[<>()?,.:[\]]/},F=/'(?:[^\r\n'\\]|\\.|\\[Uux][\da-fA-F]{1,8})'/.source,A=/"(?:\\.|[^\\"\r\n])*"/.source,S=/@"(?:""|\\[\s\S]|[^\\"])*"(?!")/.source;e.languages.csharp=e.languages.extend("clike",{string:[{pattern:n(/(^|[^$\\])<<0>>/.source,[S]),lookbehind:!0,greedy:!0},{pattern:n(/(^|[^@$\\])<<0>>/.source,[A]),lookbehind:!0,greedy:!0}],"class-name":[{pattern:n(/(\busing\s+static\s+)<<0>>(?=\s*;)/.source,[m]),lookbehind:!0,inside:x},{pattern:n(/(\busing\s+<<0>>\s*=\s*)<<1>>(?=\s*;)/.source,[h,_]),lookbehind:!0,inside:x},{pattern:n(/(\busing\s+)<<0>>(?=\s*=)/.source,[h]),lookbehind:!0},{pattern:n(/(\b<<0>>\s+)<<1>>/.source,[u,f]),lookbehind:!0,inside:x},{pattern:n(/(\bcatch\s*\(\s*)<<0>>/.source,[m]),lookbehind:!0,inside:x},{pattern:n(/(\bwhere\s+)<<0>>/.source,[h]),lookbehind:!0},{pattern:n(/(\b(?:is(?:\s+not)?|as)\s+)<<0>>/.source,[w]),lookbehind:!0,inside:x},{pattern:n(/\b<<0>>(?=\s+(?!<<1>>|with\s*\{)<<2>>(?:\s*[=,;:{)\]]|\s+(?:in|when)\b))/.source,[_,g,h]),inside:x}],keyword:c,number:/(?:\b0(?:x[\da-f_]*[\da-f]|b[01_]*[01])|(?:\B\.\d+(?:_+\d+)*|\b\d+(?:_+\d+)*(?:\.\d+(?:_+\d+)*)?)(?:e[-+]?\d+(?:_+\d+)*)?)(?:[dflmu]|lu|ul)?\b/i,operator:/>>=?|<<=?|[-=]>|([-+&|])\1|~|\?\?=?|[-+*/%&|^!=<>]=?/,punctuation:/\?\.?|::|[{}[\];(),.:]/}),e.languages.insertBefore("csharp","number",{range:{pattern:/\.\./,alias:"operator"}}),e.languages.insertBefore("csharp","punctuation",{"named-parameter":{pattern:n(/([(,]\s*)<<0>>(?=\s*:)/.source,[h]),lookbehind:!0,alias:"punctuation"}}),e.languages.insertBefore("csharp","class-name",{namespace:{pattern:n(/(\b(?:namespace|using)\s+)<<0>>(?:\s*\.\s*<<0>>)*(?=\s*[;{])/.source,[h]),lookbehind:!0,inside:{punctuation:/\./}},"type-expression":{pattern:n(/(\b(?:default|sizeof|typeof)\s*\(\s*(?!\s))(?:[^()\s]|\s(?!\s)|<<0>>)*(?=\s*\))/.source,[b]),lookbehind:!0,alias:"class-name",inside:x},"return-type":{pattern:n(/<<0>>(?=\s+(?:<<1>>\s*(?:=>|[({]|\.\s*this\s*\[)|this\s*\[))/.source,[_,m]),inside:x,alias:"class-name"},"constructor-invocation":{pattern:n(/(\bnew\s+)<<0>>(?=\s*[[({])/.source,[_]),lookbehind:!0,inside:x,alias:"class-name"},"generic-method":{pattern:n(/<<0>>\s*<<1>>(?=\s*\()/.source,[h,p]),inside:{function:n(/^<<0>>/.source,[h]),generic:{pattern:RegExp(p),alias:"class-name",inside:x}}},"type-list":{pattern:n(/\b((?:<<0>>\s+<<1>>|record\s+<<1>>\s*<<5>>|where\s+<<2>>)\s*:\s*)(?:<<3>>|<<4>>|<<1>>\s*<<5>>|<<6>>)(?:\s*,\s*(?:<<3>>|<<4>>|<<6>>))*(?=\s*(?:where|[{;]|=>|$))/.source,[u,f,h,_,c.source,b,/\bnew\s*\(\s*\)/.source]),lookbehind:!0,inside:{"record-arguments":{pattern:n(/(^(?!new\s*\()<<0>>\s*)<<1>>/.source,[f,b]),lookbehind:!0,greedy:!0,inside:e.languages.csharp},keyword:c,"class-name":{pattern:RegExp(_),greedy:!0,inside:x},punctuation:/[,()]/}},preprocessor:{pattern:/(^[\t ]*)#.*/m,lookbehind:!0,alias:"property",inside:{directive:{pattern:/(#)\b(?:define|elif|else|endif|endregion|error|if|line|nullable|pragma|region|undef|warning)\b/,lookbehind:!0,alias:"keyword"}}}});var $=A+"|"+F,z=t(/\/(?![*/])|\/\/[^\r\n]*[\r\n]|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>/.source,[$]),E=a(t(/[^"'/()]|<<0>>|\(<>*\)/.source,[z]),2),C=/\b(?:assembly|event|field|method|module|param|property|return|type)\b/.source,j=t(/<<0>>(?:\s*\(<<1>>*\))?/.source,[m,E]);e.languages.insertBefore("csharp","class-name",{attribute:{pattern:n(/((?:^|[^\s\w>)?])\s*\[\s*)(?:<<0>>\s*:\s*)?<<1>>(?:\s*,\s*<<1>>)*(?=\s*\])/.source,[C,j]),lookbehind:!0,greedy:!0,inside:{target:{pattern:n(/^<<0>>(?=\s*:)/.source,[C]),alias:"keyword"},"attribute-arguments":{pattern:n(/\(<<0>>*\)/.source,[E]),inside:e.languages.csharp},"class-name":{pattern:RegExp(m),inside:{punctuation:/\./}},punctuation:/[:,]/}}});var B=/:[^}\r\n]+/.source,T=a(t(/[^"'/()]|<<0>>|\(<>*\)/.source,[z]),2),O=t(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[T,B]),P=a(t(/[^"'/()]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>|\(<>*\)/.source,[$]),2),N=t(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[P,B]);function R(t,a){return{interpolation:{pattern:n(/((?:^|[^{])(?:\{\{)*)<<0>>/.source,[t]),lookbehind:!0,inside:{"format-string":{pattern:n(/(^\{(?:(?![}:])<<0>>)*)<<1>>(?=\}$)/.source,[a,B]),lookbehind:!0,inside:{punctuation:/^:/}},punctuation:/^\{|\}$/,expression:{pattern:/[\s\S]+/,alias:"language-csharp",inside:e.languages.csharp}}},string:/[\s\S]+/}}e.languages.insertBefore("csharp","string",{"interpolation-string":[{pattern:n(/(^|[^\\])(?:\$@|@\$)"(?:""|\\[\s\S]|\{\{|<<0>>|[^\\{"])*"/.source,[O]),lookbehind:!0,greedy:!0,inside:R(O,T)},{pattern:n(/(^|[^@\\])\$"(?:\\.|\{\{|<<0>>|[^\\"{])*"/.source,[N]),lookbehind:!0,greedy:!0,inside:R(N,P)}],char:{pattern:RegExp(F),greedy:!0}}),e.languages.dotnet=e.languages.cs=e.languages.csharp}(s),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(s),function(e){var t=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,n=/(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source,a={pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[a,{pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z]\w*(?=\s+\w+\s*[;,=()]|\s*(?:\[[\s,]*\]\s*)?::\s*new\b)/.source),lookbehind:!0,inside:a.inside},{pattern:RegExp(/(\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\s+)/.source+n+/[A-Z]\w*\b/.source),lookbehind:!0,inside:a.inside}],keyword:t,function:[e.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0}}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":a,keyword:t,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp(/(\bimport\s+)/.source+n+/(?:[A-Z]\w*|\*)(?=\s*;)/.source),lookbehind:!0,inside:{namespace:a.inside.namespace,punctuation:/\./,operator:/\*/,"class-name":/\w+/}},{pattern:RegExp(/(\bimport\s+static\s+)/.source+n+/(?:\w+|\*)(?=\s*;)/.source),lookbehind:!0,alias:"static",inside:{namespace:a.inside.namespace,static:/\b\w+$/,punctuation:/\./,operator:/\*/,"class-name":/\w+/}}],namespace:{pattern:RegExp(/(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!)[a-z]\w*(?:\.[a-z]\w*)*\.?/.source.replace(//g,(function(){return t.source}))),lookbehind:!0,inside:{punctuation:/\./}}})}(s),s.languages.javascript=s.languages.extend("clike",{"class-name":[s.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),s.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,s.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:s.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:s.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:s.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:s.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:s.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),s.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:s.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),s.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),s.languages.markup&&(s.languages.markup.tag.addInlined("script","javascript"),s.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),s.languages.js=s.languages.javascript,s.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},s.languages.markup.tag.inside["attr-value"].inside.entity=s.languages.markup.entity,s.languages.markup.doctype.inside["internal-subset"].inside=s.languages.markup,s.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(s.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:s.languages[t]},n.cdata=/^$/i;var a={"included-cdata":{pattern://i,inside:n}};a["language-"+t]={pattern:/[\s\S]+/,inside:s.languages[t]};var r={};r[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:a},s.languages.insertBefore("markup","cdata",r)}}),Object.defineProperty(s.languages.markup.tag,"addAttribute",{value:function(e,t){s.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:s.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),s.languages.html=s.languages.markup,s.languages.mathml=s.languages.markup,s.languages.svg=s.languages.markup,s.languages.xml=s.languages.extend("markup",{}),s.languages.ssml=s.languages.xml,s.languages.atom=s.languages.xml,s.languages.rss=s.languages.xml,function(e){var t=/\/\*[\s\S]*?\*\/|\/\/.*|#(?!\[).*/,n=[{pattern:/\b(?:false|true)\b/i,alias:"boolean"},{pattern:/(::\s*)\b[a-z_]\w*\b(?!\s*\()/i,greedy:!0,lookbehind:!0},{pattern:/(\b(?:case|const)\s+)\b[a-z_]\w*(?=\s*[;=])/i,greedy:!0,lookbehind:!0},/\b(?:null)\b/i,/\b[A-Z_][A-Z0-9_]*\b(?!\s*\()/],a=/\b0b[01]+(?:_[01]+)*\b|\b0o[0-7]+(?:_[0-7]+)*\b|\b0x[\da-f]+(?:_[\da-f]+)*\b|(?:\b\d+(?:_\d+)*\.?(?:\d+(?:_\d+)*)?|\B\.\d+)(?:e[+-]?\d+)?/i,s=/|\?\?=?|\.{3}|\??->|[!=]=?=?|::|\*\*=?|--|\+\+|&&|\|\||<<|>>|[?~]|[/^|%*&<>.+-]=?/,r=/[{}\[\](),:;]/;e.languages.php={delimiter:{pattern:/\?>$|^<\?(?:php(?=\s)|=)?/i,alias:"important"},comment:t,variable:/\$+(?:\w+\b|(?=\{))/,package:{pattern:/(namespace\s+|use\s+(?:function\s+)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,lookbehind:!0,inside:{punctuation:/\\/}},"class-name-definition":{pattern:/(\b(?:class|enum|interface|trait)\s+)\b[a-z_]\w*(?!\\)\b/i,lookbehind:!0,alias:"class-name"},"function-definition":{pattern:/(\bfunction\s+)[a-z_]\w*(?=\s*\()/i,lookbehind:!0,alias:"function"},keyword:[{pattern:/(\(\s*)\b(?:array|bool|boolean|float|int|integer|object|string)\b(?=\s*\))/i,alias:"type-casting",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|object|self|static|string)\b(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|never|object|self|static|string|void)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/\b(?:array(?!\s*\()|bool|float|int|iterable|mixed|object|string|void)\b/i,alias:"type-declaration",greedy:!0},{pattern:/(\|\s*)(?:false|null)\b|\b(?:false|null)(?=\s*\|)/i,alias:"type-declaration",greedy:!0,lookbehind:!0},{pattern:/\b(?:parent|self|static)(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(\byield\s+)from\b/i,lookbehind:!0},/\bclass\b/i,{pattern:/((?:^|[^\s>:]|(?:^|[^-])>|(?:^|[^:]):)\s*)\b(?:abstract|and|array|as|break|callable|case|catch|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|enum|eval|exit|extends|final|finally|fn|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|match|namespace|never|new|or|parent|print|private|protected|public|readonly|require|require_once|return|self|static|switch|throw|trait|try|unset|use|var|while|xor|yield|__halt_compiler)\b/i,lookbehind:!0}],"argument-name":{pattern:/([(,]\s*)\b[a-z_]\w*(?=\s*:(?!:))/i,lookbehind:!0},"class-name":[{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self|\s+static))\s+|\bcatch\s*\()\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/(\|\s*)\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/\b[a-z_]\w*(?!\\)\b(?=\s*\|)/i,greedy:!0},{pattern:/(\|\s*)(?:\\?\b[a-z_]\w*)+\b/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(?:\\?\b[a-z_]\w*)+\b(?=\s*\|)/i,alias:"class-name-fully-qualified",greedy:!0,inside:{punctuation:/\\/}},{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self\b|\s+static\b))\s+|\bcatch\s*\()(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*\$)/i,alias:"type-declaration",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-declaration"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*::)/i,alias:["class-name-fully-qualified","static-context"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/([(,?]\s*)[a-z_]\w*(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-hint"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b[a-z_]\w*(?!\\)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:["class-name-fully-qualified","return-type"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:n,function:{pattern:/(^|[^\\\w])\\?[a-z_](?:[\w\\]*\w)?(?=\s*\()/i,lookbehind:!0,inside:{punctuation:/\\/}},property:{pattern:/(->\s*)\w+/,lookbehind:!0},number:a,operator:s,punctuation:r};var i={pattern:/\{\$(?:\{(?:\{[^{}]+\}|[^{}]+)\}|[^{}])+\}|(^|[^\\{])\$+(?:\w+(?:\[[^\r\n\[\]]+\]|->\w+)?)/,lookbehind:!0,inside:e.languages.php},o=[{pattern:/<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/,alias:"nowdoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<'[^']+'|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<'?|[';]$/}}}},{pattern:/<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<"?|[";]$/}},interpolation:i}},{pattern:/`(?:\\[\s\S]|[^\\`])*`/,alias:"backtick-quoted-string",greedy:!0},{pattern:/'(?:\\[\s\S]|[^\\'])*'/,alias:"single-quoted-string",greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,alias:"double-quoted-string",greedy:!0,inside:{interpolation:i}}];e.languages.insertBefore("php","variable",{string:o,attribute:{pattern:/#\[(?:[^"'\/#]|\/(?![*/])|\/\/.*$|#(?!\[).*$|\/\*(?:[^*]|\*(?!\/))*\*\/|"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*')+\](?=\s*[a-z$#])/im,greedy:!0,inside:{"attribute-content":{pattern:/^(#\[)[\s\S]+(?=\]$)/,lookbehind:!0,inside:{comment:t,string:o,"attribute-class-name":[{pattern:/([^:]|^)\b[a-z_]\w*(?!\\)\b/i,alias:"class-name",greedy:!0,lookbehind:!0},{pattern:/([^:]|^)(?:\\?\b[a-z_]\w*)+/i,alias:["class-name","class-name-fully-qualified"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:n,number:a,operator:s,punctuation:r}},delimiter:{pattern:/^#\[|\]$/,alias:"punctuation"}}}}),e.hooks.add("before-tokenize",(function(t){/<\?/.test(t.code)&&e.languages["markup-templating"].buildPlaceholders(t,"php",/<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#(?!\[))(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|#\[|\/\*(?:[^*]|\*(?!\/))*(?:\*\/|$))*?(?:\?>|$)/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"php")}))}(s),s.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},s.languages.python["string-interpolation"].inside.interpolation.inside.rest=s.languages.python,s.languages.py=s.languages.python,function(e){e.languages.ruby=e.languages.extend("clike",{comment:{pattern:/#.*|^=begin\s[\s\S]*?^=end/m,greedy:!0},"class-name":{pattern:/(\b(?:class|module)\s+|\bcatch\s+\()[\w.\\]+|\b[A-Z_]\w*(?=\s*\.\s*new\b)/,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:BEGIN|END|alias|and|begin|break|case|class|def|define_method|defined|do|each|else|elsif|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|private|protected|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/,operator:/\.{2,3}|&\.|===||[!=]?~|(?:&&|\|\||<<|>>|\*\*|[+\-*/%<>!^&|=])=?|[?:]/,punctuation:/[(){}[\].,;]/}),e.languages.insertBefore("ruby","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}});var t={pattern:/((?:^|[^\\])(?:\\{2})*)#\{(?:[^{}]|\{[^{}]*\})*\}/,lookbehind:!0,inside:{content:{pattern:/^(#\{)[\s\S]+(?=\}$)/,lookbehind:!0,inside:e.languages.ruby},delimiter:{pattern:/^#\{|\}$/,alias:"punctuation"}}};delete e.languages.ruby.function;var n="(?:"+[/([^a-zA-Z0-9\s{(\[<=])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,/\((?:[^()\\]|\\[\s\S]|\((?:[^()\\]|\\[\s\S])*\))*\)/.source,/\{(?:[^{}\\]|\\[\s\S]|\{(?:[^{}\\]|\\[\s\S])*\})*\}/.source,/\[(?:[^\[\]\\]|\\[\s\S]|\[(?:[^\[\]\\]|\\[\s\S])*\])*\]/.source,/<(?:[^<>\\]|\\[\s\S]|<(?:[^<>\\]|\\[\s\S])*>)*>/.source].join("|")+")",a=/(?:"(?:\\.|[^"\\\r\n])*"|(?:\b[a-zA-Z_]\w*|[^\s\0-\x7F]+)[?!]?|\$.)/.source;e.languages.insertBefore("ruby","keyword",{"regex-literal":[{pattern:RegExp(/%r/.source+n+/[egimnosux]{0,6}/.source),greedy:!0,inside:{interpolation:t,regex:/[\s\S]+/}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,lookbehind:!0,greedy:!0,inside:{interpolation:t,regex:/[\s\S]+/}}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:[{pattern:RegExp(/(^|[^:]):/.source+a),lookbehind:!0,greedy:!0},{pattern:RegExp(/([\r\n{(,][ \t]*)/.source+a+/(?=:(?!:))/.source),lookbehind:!0,greedy:!0}],"method-definition":{pattern:/(\bdef\s+)\w+(?:\s*\.\s*\w+)?/,lookbehind:!0,inside:{function:/\b\w+$/,keyword:/^self\b/,"class-name":/^\w+/,punctuation:/\./}}}),e.languages.insertBefore("ruby","string",{"string-literal":[{pattern:RegExp(/%[qQiIwWs]?/.source+n),greedy:!0,inside:{interpolation:t,string:/[\s\S]+/}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:t,string:/[\s\S]+/}},{pattern:/<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?[a-z_]\w*|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?/}},interpolation:t,string:/[\s\S]+/}},{pattern:/<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?'[a-z_]\w*'|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?'|'$/}},string:/[\s\S]+/}}],"command-literal":[{pattern:RegExp(/%x/.source+n),greedy:!0,inside:{interpolation:t,command:{pattern:/[\s\S]+/,alias:"string"}}},{pattern:/`(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|[^\\`#\r\n])*`/,greedy:!0,inside:{interpolation:t,command:{pattern:/[\s\S]+/,alias:"string"}}}]}),delete e.languages.ruby.string,e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Fixnum|Float|Hash|IO|Integer|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|Stat|String|Struct|Symbol|TMS|Thread|ThreadGroup|Time|TrueClass)\b/,constant:/\b[A-Z][A-Z0-9_]*(?:[?!]|\b)/}),e.languages.rb=e.languages.ruby}(s),window.Prism=a,s}(),i=e=>t=>t.options.get(e),o=i("codesample_languages"),l=i("codesample_global_prismjs"),u=e=>s.Prism&&l(e)?s.Prism:r,c=e=>t(e)&&"PRE"===e.nodeName&&-1!==e.className.indexOf("language-"),d=e=>{const t=e.selection?e.selection.getNode():null;return c(t)?n.some(t):n.none()},g=e=>{const t=(e=>o(e)||[{text:"HTML/XML",value:"markup"},{text:"JavaScript",value:"javascript"},{text:"CSS",value:"css"},{text:"PHP",value:"php"},{text:"Ruby",value:"ruby"},{text:"Python",value:"python"},{text:"Java",value:"java"},{text:"C",value:"c"},{text:"C#",value:"csharp"},{text:"C++",value:"cpp"}])(e),s=(r=t,((e,t)=>0""),(e=>e.value));var r;const i=((e,t)=>d(e).fold((()=>t),(e=>{const n=e.className.match(/language-(\w+)/);return n?n[1]:t})))(e,s),l=(e=>d(e).bind((e=>n.from(e.textContent))).getOr(""))(e);e.windowManager.open({title:"Insert/Edit Code Sample",size:"large",body:{type:"panel",items:[{type:"selectbox",name:"language",label:"Language",items:t},{type:"textarea",name:"code",label:"Code view"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{language:i,code:l},onSubmit:t=>{const n=t.getData();((e,t,n)=>{const s=e.dom;e.undoManager.transact((()=>{const r=d(e);return n=a.DOM.encode(n),r.fold((()=>{e.insertContent('
'+n+"
");const a=s.select("#__new")[0];s.setAttrib(a,"id",null),e.selection.select(a)}),(a=>{s.setAttrib(a,"class","language-"+t),a.innerHTML=n,u(e).highlightElement(a),e.selection.select(a)}))}))})(e,n.language,n.code),t.close()}})},p=(b=/^\s+|\s+$/g,e=>e.replace(b,""));var b,h=tinymce.util.Tools.resolve("tinymce.util.Tools");e.add("codesample",(e=>{(e=>{const t=e.options.register;t("codesample_languages",{processor:"object[]"}),t("codesample_global_prismjs",{processor:"boolean",default:!1})})(e),(e=>{e.on("PreProcess",(t=>{const n=e.dom,a=n.select("pre[contenteditable=false]",t.node);h.each(h.grep(a,c),(e=>{const t=e.textContent;let a;for(n.setAttrib(e,"class",p(n.getAttrib(e,"class"))),n.setAttrib(e,"contentEditable",null),n.setAttrib(e,"data-mce-highlighted",null);a=e.firstChild;)e.removeChild(a);n.add(e,"code").textContent=t}))})),e.on("SetContent",(()=>{const t=e.dom,n=h.grep(t.select("pre"),(e=>c(e)&&"true"!==t.getAttrib(e,"data-mce-highlighted")));n.length&&e.undoManager.transact((()=>{h.each(n,(n=>{var a;h.each(t.select("br",n),(n=>{t.replace(e.getDoc().createTextNode("\n"),n)})),n.innerHTML=t.encode(null!==(a=n.textContent)&&void 0!==a?a:""),u(e).highlightElement(n),t.setAttrib(n,"data-mce-highlighted",!0),n.className=p(n.className)}))}))})),e.on("PreInit",(()=>{e.parser.addNodeFilter("pre",(e=>{var t;for(let n=0,a=e.length;n{const t=()=>e.execCommand("codesample");e.ui.registry.addToggleButton("codesample",{icon:"code-sample",tooltip:"Insert/edit code sample",onAction:t,onSetup:t=>{const n=()=>{t.setActive((e=>{const t=e.selection.getStart();return e.dom.is(t,'pre[class*="language-"]')})(e))};return e.on("NodeChange",n),()=>e.off("NodeChange",n)}}),e.ui.registry.addMenuItem("codesample",{text:"Code sample...",icon:"code-sample",onAction:t})})(e),(e=>{e.addCommand("codesample",(()=>{const t=e.selection.getNode();e.selection.isCollapsed()||c(t)?g(e):e.formatter.toggle("code")}))})(e),e.on("dblclick",(t=>{c(t.target)&&g(e)}))}))}(); \ No newline at end of file diff --git a/static/js/tinymce/plugins/directionality/plugin.min.js b/static/js/tinymce/plugins/directionality/plugin.min.js new file mode 100644 index 0000000..4f2d3b1 --- /dev/null +++ b/static/js/tinymce/plugins/directionality/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.2.0 (2022-09-08) + */ +!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=t=>e=>typeof e===t,o=t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(o=r=t,(n=String).prototype.isPrototypeOf(o)||(null===(i=r.constructor)||void 0===i?void 0:i.name)===n.name)?"string":e;var o,r,n,i})(t),r=e("boolean"),n=t=>!(t=>null==t)(t),i=e("function"),s=e("number"),l=(!1,()=>false);class a{constructor(t,e){this.tag=t,this.value=e}static some(t){return new a(!0,t)}static none(){return a.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?a.some(t(this.value)):a.none()}bind(t){return this.tag?t(this.value):a.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:a.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return n(t)?a.some(t):a.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}a.singletonNone=new a(!1);const u=(t,e)=>{for(let o=0,r=t.length;o{if(null==t)throw new Error("Node cannot be null or undefined");return{dom:t}},d=c,h=(t,e)=>{const o=t.dom;if(1!==o.nodeType)return!1;{const t=o;if(void 0!==t.matches)return t.matches(e);if(void 0!==t.msMatchesSelector)return t.msMatchesSelector(e);if(void 0!==t.webkitMatchesSelector)return t.webkitMatchesSelector(e);if(void 0!==t.mozMatchesSelector)return t.mozMatchesSelector(e);throw new Error("Browser lacks native selectors")}};"undefined"!=typeof window?window:Function("return this;")();const m=t=>e=>(t=>t.dom.nodeType)(e)===t,g=m(1),f=m(3),v=m(9),p=m(11),y=(t,e)=>{t.dom.removeAttribute(e)},w=i(Element.prototype.attachShadow)&&i(Node.prototype.getRootNode)?t=>d(t.dom.getRootNode()):t=>v(t)?t:d(t.dom.ownerDocument),N=t=>d(t.dom.host),b=t=>{const e=f(t)?t.dom.parentNode:t.dom;if(null==e||null===e.ownerDocument)return!1;const o=e.ownerDocument;return(t=>{const e=w(t);return p(o=e)&&n(o.dom.host)?a.some(e):a.none();var o})(d(e)).fold((()=>o.body.contains(e)),(r=b,i=N,t=>r(i(t))));var r,i},S=t=>"rtl"===((t,e)=>{const o=t.dom,r=window.getComputedStyle(o).getPropertyValue(e);return""!==r||b(t)?r:((t,e)=>(t=>void 0!==t.style&&i(t.style.getPropertyValue))(t)?t.style.getPropertyValue(e):"")(o,e)})(t,"direction")?"rtl":"ltr",A=(t,e)=>((t,o)=>((t,e)=>{const o=[];for(let r=0,n=t.length;r{const o=t.length,r=new Array(o);for(let n=0;nh(t,e))))(t),T=("li",t=>g(t)&&"li"===t.dom.nodeName.toLowerCase());const C=(t,e)=>{const n=t.selection.getSelectedBlocks();n.length>0&&(u(n,(t=>{const n=d(t),c=T(n),m=((t,e)=>{return(e?(o=t,r="ol,ul",((t,e,o)=>{let n=t.dom;const s=i(o)?o:l;for(;n.parentNode;){n=n.parentNode;const t=d(n);if(h(t,r))return a.some(t);if(s(t))break}return a.none()})(o,0,n)):a.some(t)).getOr(t);var o,r,n})(n,c);var f;(f=m,(t=>a.from(t.dom.parentNode).map(d))(f).filter(g)).each((t=>{if(S(t)!==e?((t,e,n)=>{((t,e,n)=>{if(!(o(n)||r(n)||s(n)))throw console.error("Invalid call to Attribute.set. Key ",e,":: Value ",n,":: Element ",t),new Error("Attribute value was not simple");t.setAttribute(e,n+"")})(t.dom,e,n)})(m,"dir",e):S(m)!==e&&y(m,"dir"),c){const t=A(m,"li[dir]");u(t,(t=>y(t,"dir")))}}))})),t.nodeChanged())},D=(t,e)=>o=>{const r=t=>{const r=d(t.element);o.setActive(S(r)===e)};return t.on("NodeChange",r),()=>t.off("NodeChange",r)};t.add("directionality",(t=>{(t=>{t.addCommand("mceDirectionLTR",(()=>{C(t,"ltr")})),t.addCommand("mceDirectionRTL",(()=>{C(t,"rtl")}))})(t),(t=>{t.ui.registry.addToggleButton("ltr",{tooltip:"Left to right",icon:"ltr",onAction:()=>t.execCommand("mceDirectionLTR"),onSetup:D(t,"ltr")}),t.ui.registry.addToggleButton("rtl",{tooltip:"Right to left",icon:"rtl",onAction:()=>t.execCommand("mceDirectionRTL"),onSetup:D(t,"rtl")})})(t)}))}(); \ No newline at end of file diff --git a/static/js/tinymce/plugins/emoticons/js/emojiimages.js b/static/js/tinymce/plugins/emoticons/js/emojiimages.js new file mode 100644 index 0000000..6fcec71 --- /dev/null +++ b/static/js/tinymce/plugins/emoticons/js/emojiimages.js @@ -0,0 +1 @@ +window.tinymce.Resource.add("tinymce.plugins.emoticons",{100:{keywords:["score","perfect","numbers","century","exam","quiz","test","pass","hundred"],char:'💯',fitzpatrick_scale:false,category:"symbols"},1234:{keywords:["numbers","blue-square"],char:'🔢',fitzpatrick_scale:false,category:"symbols"},grinning:{keywords:["face","smile","happy","joy",":D","grin"],char:'😀',fitzpatrick_scale:false,category:"people"},grimacing:{keywords:["face","grimace","teeth"],char:'😬',fitzpatrick_scale:false,category:"people"},grin:{keywords:["face","happy","smile","joy","kawaii"],char:'😁',fitzpatrick_scale:false,category:"people"},joy:{keywords:["face","cry","tears","weep","happy","happytears","haha"],char:'😂',fitzpatrick_scale:false,category:"people"},rofl:{keywords:["face","rolling","floor","laughing","lol","haha"],char:'🤣',fitzpatrick_scale:false,category:"people"},partying:{keywords:["face","celebration","woohoo"],char:'🥳',fitzpatrick_scale:false,category:"people"},smiley:{keywords:["face","happy","joy","haha",":D",":)","smile","funny"],char:'😃',fitzpatrick_scale:false,category:"people"},smile:{keywords:["face","happy","joy","funny","haha","laugh","like",":D",":)"],char:'😄',fitzpatrick_scale:false,category:"people"},sweat_smile:{keywords:["face","hot","happy","laugh","sweat","smile","relief"],char:'😅',fitzpatrick_scale:false,category:"people"},laughing:{keywords:["happy","joy","lol","satisfied","haha","face","glad","XD","laugh"],char:'😆',fitzpatrick_scale:false,category:"people"},innocent:{keywords:["face","angel","heaven","halo"],char:'😇',fitzpatrick_scale:false,category:"people"},wink:{keywords:["face","happy","mischievous","secret",";)","smile","eye"],char:'😉',fitzpatrick_scale:false,category:"people"},blush:{keywords:["face","smile","happy","flushed","crush","embarrassed","shy","joy"],char:'😊',fitzpatrick_scale:false,category:"people"},slightly_smiling_face:{keywords:["face","smile"],char:'🙂',fitzpatrick_scale:false,category:"people"},upside_down_face:{keywords:["face","flipped","silly","smile"],char:'🙃',fitzpatrick_scale:false,category:"people"},relaxed:{keywords:["face","blush","massage","happiness"],char:'☺️',fitzpatrick_scale:false,category:"people"},yum:{keywords:["happy","joy","tongue","smile","face","silly","yummy","nom","delicious","savouring"],char:'😋',fitzpatrick_scale:false,category:"people"},relieved:{keywords:["face","relaxed","phew","massage","happiness"],char:'😌',fitzpatrick_scale:false,category:"people"},heart_eyes:{keywords:["face","love","like","affection","valentines","infatuation","crush","heart"],char:'😍',fitzpatrick_scale:false,category:"people"},smiling_face_with_three_hearts:{keywords:["face","love","like","affection","valentines","infatuation","crush","hearts","adore"],char:'🥰',fitzpatrick_scale:false,category:"people"},kissing_heart:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:'😘',fitzpatrick_scale:false,category:"people"},kissing:{keywords:["love","like","face","3","valentines","infatuation","kiss"],char:'😗',fitzpatrick_scale:false,category:"people"},kissing_smiling_eyes:{keywords:["face","affection","valentines","infatuation","kiss"],char:'😙',fitzpatrick_scale:false,category:"people"},kissing_closed_eyes:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:'😚',fitzpatrick_scale:false,category:"people"},stuck_out_tongue_winking_eye:{keywords:["face","prank","childish","playful","mischievous","smile","wink","tongue"],char:'😜',fitzpatrick_scale:false,category:"people"},zany:{keywords:["face","goofy","crazy"],char:'🤪',fitzpatrick_scale:false,category:"people"},raised_eyebrow:{keywords:["face","distrust","scepticism","disapproval","disbelief","surprise"],char:'🤨',fitzpatrick_scale:false,category:"people"},monocle:{keywords:["face","stuffy","wealthy"],char:'🧐',fitzpatrick_scale:false,category:"people"},stuck_out_tongue_closed_eyes:{keywords:["face","prank","playful","mischievous","smile","tongue"],char:'😝',fitzpatrick_scale:false,category:"people"},stuck_out_tongue:{keywords:["face","prank","childish","playful","mischievous","smile","tongue"],char:'😛',fitzpatrick_scale:false,category:"people"},money_mouth_face:{keywords:["face","rich","dollar","money"],char:'🤑',fitzpatrick_scale:false,category:"people"},nerd_face:{keywords:["face","nerdy","geek","dork"],char:'🤓',fitzpatrick_scale:false,category:"people"},sunglasses:{keywords:["face","cool","smile","summer","beach","sunglass"],char:'😎',fitzpatrick_scale:false,category:"people"},star_struck:{keywords:["face","smile","starry","eyes","grinning"],char:'🤩',fitzpatrick_scale:false,category:"people"},clown_face:{keywords:["face"],char:'🤡',fitzpatrick_scale:false,category:"people"},cowboy_hat_face:{keywords:["face","cowgirl","hat"],char:'🤠',fitzpatrick_scale:false,category:"people"},hugs:{keywords:["face","smile","hug"],char:'🤗',fitzpatrick_scale:false,category:"people"},smirk:{keywords:["face","smile","mean","prank","smug","sarcasm"],char:'😏',fitzpatrick_scale:false,category:"people"},no_mouth:{keywords:["face","hellokitty"],char:'😶',fitzpatrick_scale:false,category:"people"},neutral_face:{keywords:["indifference","meh",":|","neutral"],char:'😐',fitzpatrick_scale:false,category:"people"},expressionless:{keywords:["face","indifferent","-_-","meh","deadpan"],char:'😑',fitzpatrick_scale:false,category:"people"},unamused:{keywords:["indifference","bored","straight face","serious","sarcasm","unimpressed","skeptical","dubious","side_eye"],char:'😒',fitzpatrick_scale:false,category:"people"},roll_eyes:{keywords:["face","eyeroll","frustrated"],char:'🙄',fitzpatrick_scale:false,category:"people"},thinking:{keywords:["face","hmmm","think","consider"],char:'🤔',fitzpatrick_scale:false,category:"people"},lying_face:{keywords:["face","lie","pinocchio"],char:'🤥',fitzpatrick_scale:false,category:"people"},hand_over_mouth:{keywords:["face","whoops","shock","surprise"],char:'🤭',fitzpatrick_scale:false,category:"people"},shushing:{keywords:["face","quiet","shhh"],char:'🤫',fitzpatrick_scale:false,category:"people"},symbols_over_mouth:{keywords:["face","swearing","cursing","cussing","profanity","expletive"],char:'🤬',fitzpatrick_scale:false,category:"people"},exploding_head:{keywords:["face","shocked","mind","blown"],char:'🤯',fitzpatrick_scale:false,category:"people"},flushed:{keywords:["face","blush","shy","flattered"],char:'😳',fitzpatrick_scale:false,category:"people"},disappointed:{keywords:["face","sad","upset","depressed",":("],char:'😞',fitzpatrick_scale:false,category:"people"},worried:{keywords:["face","concern","nervous",":("],char:'😟',fitzpatrick_scale:false,category:"people"},angry:{keywords:["mad","face","annoyed","frustrated"],char:'😠',fitzpatrick_scale:false,category:"people"},rage:{keywords:["angry","mad","hate","despise"],char:'😡',fitzpatrick_scale:false,category:"people"},pensive:{keywords:["face","sad","depressed","upset"],char:'😔',fitzpatrick_scale:false,category:"people"},confused:{keywords:["face","indifference","huh","weird","hmmm",":/"],char:'😕',fitzpatrick_scale:false,category:"people"},slightly_frowning_face:{keywords:["face","frowning","disappointed","sad","upset"],char:'🙁',fitzpatrick_scale:false,category:"people"},frowning_face:{keywords:["face","sad","upset","frown"],char:'☹',fitzpatrick_scale:false,category:"people"},persevere:{keywords:["face","sick","no","upset","oops"],char:'😣',fitzpatrick_scale:false,category:"people"},confounded:{keywords:["face","confused","sick","unwell","oops",":S"],char:'😖',fitzpatrick_scale:false,category:"people"},tired_face:{keywords:["sick","whine","upset","frustrated"],char:'😫',fitzpatrick_scale:false,category:"people"},weary:{keywords:["face","tired","sleepy","sad","frustrated","upset"],char:'😩',fitzpatrick_scale:false,category:"people"},pleading:{keywords:["face","begging","mercy"],char:'🥺',fitzpatrick_scale:false,category:"people"},triumph:{keywords:["face","gas","phew","proud","pride"],char:'😤',fitzpatrick_scale:false,category:"people"},open_mouth:{keywords:["face","surprise","impressed","wow","whoa",":O"],char:'😮',fitzpatrick_scale:false,category:"people"},scream:{keywords:["face","munch","scared","omg"],char:'😱',fitzpatrick_scale:false,category:"people"},fearful:{keywords:["face","scared","terrified","nervous","oops","huh"],char:'😨',fitzpatrick_scale:false,category:"people"},cold_sweat:{keywords:["face","nervous","sweat"],char:'😰',fitzpatrick_scale:false,category:"people"},hushed:{keywords:["face","woo","shh"],char:'😯',fitzpatrick_scale:false,category:"people"},frowning:{keywords:["face","aw","what"],char:'😦',fitzpatrick_scale:false,category:"people"},anguished:{keywords:["face","stunned","nervous"],char:'😧',fitzpatrick_scale:false,category:"people"},cry:{keywords:["face","tears","sad","depressed","upset",":'("],char:'😢',fitzpatrick_scale:false,category:"people"},disappointed_relieved:{keywords:["face","phew","sweat","nervous"],char:'😥',fitzpatrick_scale:false,category:"people"},drooling_face:{keywords:["face"],char:'🤤',fitzpatrick_scale:false,category:"people"},sleepy:{keywords:["face","tired","rest","nap"],char:'😪',fitzpatrick_scale:false,category:"people"},sweat:{keywords:["face","hot","sad","tired","exercise"],char:'😓',fitzpatrick_scale:false,category:"people"},hot:{keywords:["face","feverish","heat","red","sweating"],char:'🥵',fitzpatrick_scale:false,category:"people"},cold:{keywords:["face","blue","freezing","frozen","frostbite","icicles"],char:'🥶',fitzpatrick_scale:false,category:"people"},sob:{keywords:["face","cry","tears","sad","upset","depressed"],char:'😭',fitzpatrick_scale:false,category:"people"},dizzy_face:{keywords:["spent","unconscious","xox","dizzy"],char:'😵',fitzpatrick_scale:false,category:"people"},astonished:{keywords:["face","xox","surprised","poisoned"],char:'😲',fitzpatrick_scale:false,category:"people"},zipper_mouth_face:{keywords:["face","sealed","zipper","secret"],char:'🤐',fitzpatrick_scale:false,category:"people"},nauseated_face:{keywords:["face","vomit","gross","green","sick","throw up","ill"],char:'🤢',fitzpatrick_scale:false,category:"people"},sneezing_face:{keywords:["face","gesundheit","sneeze","sick","allergy"],char:'🤧',fitzpatrick_scale:false,category:"people"},vomiting:{keywords:["face","sick"],char:'🤮',fitzpatrick_scale:false,category:"people"},mask:{keywords:["face","sick","ill","disease"],char:'😷',fitzpatrick_scale:false,category:"people"},face_with_thermometer:{keywords:["sick","temperature","thermometer","cold","fever"],char:'🤒',fitzpatrick_scale:false,category:"people"},face_with_head_bandage:{keywords:["injured","clumsy","bandage","hurt"],char:'🤕',fitzpatrick_scale:false,category:"people"},woozy:{keywords:["face","dizzy","intoxicated","tipsy","wavy"],char:'🥴',fitzpatrick_scale:false,category:"people"},sleeping:{keywords:["face","tired","sleepy","night","zzz"],char:'😴',fitzpatrick_scale:false,category:"people"},zzz:{keywords:["sleepy","tired","dream"],char:'💤',fitzpatrick_scale:false,category:"people"},poop:{keywords:["hankey","shitface","fail","turd","shit"],char:'💩',fitzpatrick_scale:false,category:"people"},smiling_imp:{keywords:["devil","horns"],char:'😈',fitzpatrick_scale:false,category:"people"},imp:{keywords:["devil","angry","horns"],char:'👿',fitzpatrick_scale:false,category:"people"},japanese_ogre:{keywords:["monster","red","mask","halloween","scary","creepy","devil","demon","japanese","ogre"],char:'👹',fitzpatrick_scale:false,category:"people"},japanese_goblin:{keywords:["red","evil","mask","monster","scary","creepy","japanese","goblin"],char:'👺',fitzpatrick_scale:false,category:"people"},skull:{keywords:["dead","skeleton","creepy","death"],char:'💀',fitzpatrick_scale:false,category:"people"},ghost:{keywords:["halloween","spooky","scary"],char:'👻',fitzpatrick_scale:false,category:"people"},alien:{keywords:["UFO","paul","weird","outer_space"],char:'👽',fitzpatrick_scale:false,category:"people"},robot:{keywords:["computer","machine","bot"],char:'🤖',fitzpatrick_scale:false,category:"people"},smiley_cat:{keywords:["animal","cats","happy","smile"],char:'😺',fitzpatrick_scale:false,category:"people"},smile_cat:{keywords:["animal","cats","smile"],char:'😸',fitzpatrick_scale:false,category:"people"},joy_cat:{keywords:["animal","cats","haha","happy","tears"],char:'😹',fitzpatrick_scale:false,category:"people"},heart_eyes_cat:{keywords:["animal","love","like","affection","cats","valentines","heart"],char:'😻',fitzpatrick_scale:false,category:"people"},smirk_cat:{keywords:["animal","cats","smirk"],char:'😼',fitzpatrick_scale:false,category:"people"},kissing_cat:{keywords:["animal","cats","kiss"],char:'😽',fitzpatrick_scale:false,category:"people"},scream_cat:{keywords:["animal","cats","munch","scared","scream"],char:'🙀',fitzpatrick_scale:false,category:"people"},crying_cat_face:{keywords:["animal","tears","weep","sad","cats","upset","cry"],char:'😿',fitzpatrick_scale:false,category:"people"},pouting_cat:{keywords:["animal","cats"],char:'😾',fitzpatrick_scale:false,category:"people"},palms_up:{keywords:["hands","gesture","cupped","prayer"],char:'🤲',fitzpatrick_scale:true,category:"people"},raised_hands:{keywords:["gesture","hooray","yea","celebration","hands"],char:'🙌',fitzpatrick_scale:true,category:"people"},clap:{keywords:["hands","praise","applause","congrats","yay"],char:'👏',fitzpatrick_scale:true,category:"people"},wave:{keywords:["hands","gesture","goodbye","solong","farewell","hello","hi","palm"],char:'👋',fitzpatrick_scale:true,category:"people"},call_me_hand:{keywords:["hands","gesture"],char:'🤙',fitzpatrick_scale:true,category:"people"},"+1":{keywords:["thumbsup","yes","awesome","good","agree","accept","cool","hand","like"],char:'👍',fitzpatrick_scale:true,category:"people"},"-1":{keywords:["thumbsdown","no","dislike","hand"],char:'👎',fitzpatrick_scale:true,category:"people"},facepunch:{keywords:["angry","violence","fist","hit","attack","hand"],char:'👊',fitzpatrick_scale:true,category:"people"},fist:{keywords:["fingers","hand","grasp"],char:'✊',fitzpatrick_scale:true,category:"people"},fist_left:{keywords:["hand","fistbump"],char:'🤛',fitzpatrick_scale:true,category:"people"},fist_right:{keywords:["hand","fistbump"],char:'🤜',fitzpatrick_scale:true,category:"people"},v:{keywords:["fingers","ohyeah","hand","peace","victory","two"],char:'✌',fitzpatrick_scale:true,category:"people"},ok_hand:{keywords:["fingers","limbs","perfect","ok","okay"],char:'👌',fitzpatrick_scale:true,category:"people"},raised_hand:{keywords:["fingers","stop","highfive","palm","ban"],char:'✋',fitzpatrick_scale:true,category:"people"},raised_back_of_hand:{keywords:["fingers","raised","backhand"],char:'🤚',fitzpatrick_scale:true,category:"people"},open_hands:{keywords:["fingers","butterfly","hands","open"],char:'👐',fitzpatrick_scale:true,category:"people"},muscle:{keywords:["arm","flex","hand","summer","strong","biceps"],char:'💪',fitzpatrick_scale:true,category:"people"},pray:{keywords:["please","hope","wish","namaste","highfive"],char:'🙏',fitzpatrick_scale:true,category:"people"},foot:{keywords:["kick","stomp"],char:'🦶',fitzpatrick_scale:true,category:"people"},leg:{keywords:["kick","limb"],char:'🦵',fitzpatrick_scale:true,category:"people"},handshake:{keywords:["agreement","shake"],char:'🤝',fitzpatrick_scale:false,category:"people"},point_up:{keywords:["hand","fingers","direction","up"],char:'☝',fitzpatrick_scale:true,category:"people"},point_up_2:{keywords:["fingers","hand","direction","up"],char:'👆',fitzpatrick_scale:true,category:"people"},point_down:{keywords:["fingers","hand","direction","down"],char:'👇',fitzpatrick_scale:true,category:"people"},point_left:{keywords:["direction","fingers","hand","left"],char:'👈',fitzpatrick_scale:true,category:"people"},point_right:{keywords:["fingers","hand","direction","right"],char:'👉',fitzpatrick_scale:true,category:"people"},fu:{keywords:["hand","fingers","rude","middle","flipping"],char:'🖕',fitzpatrick_scale:true,category:"people"},raised_hand_with_fingers_splayed:{keywords:["hand","fingers","palm"],char:'🖐',fitzpatrick_scale:true,category:"people"},love_you:{keywords:["hand","fingers","gesture"],char:'🤟',fitzpatrick_scale:true,category:"people"},metal:{keywords:["hand","fingers","evil_eye","sign_of_horns","rock_on"],char:'🤘',fitzpatrick_scale:true,category:"people"},crossed_fingers:{keywords:["good","lucky"],char:'🤞',fitzpatrick_scale:true,category:"people"},vulcan_salute:{keywords:["hand","fingers","spock","star trek"],char:'🖖',fitzpatrick_scale:true,category:"people"},writing_hand:{keywords:["lower_left_ballpoint_pen","stationery","write","compose"],char:'✍',fitzpatrick_scale:true,category:"people"},selfie:{keywords:["camera","phone"],char:'🤳',fitzpatrick_scale:true,category:"people"},nail_care:{keywords:["beauty","manicure","finger","fashion","nail"],char:'💅',fitzpatrick_scale:true,category:"people"},lips:{keywords:["mouth","kiss"],char:'👄',fitzpatrick_scale:false,category:"people"},tooth:{keywords:["teeth","dentist"],char:'🦷',fitzpatrick_scale:false,category:"people"},tongue:{keywords:["mouth","playful"],char:'👅',fitzpatrick_scale:false,category:"people"},ear:{keywords:["face","hear","sound","listen"],char:'👂',fitzpatrick_scale:true,category:"people"},nose:{keywords:["smell","sniff"],char:'👃',fitzpatrick_scale:true,category:"people"},eye:{keywords:["face","look","see","watch","stare"],char:'👁',fitzpatrick_scale:false,category:"people"},eyes:{keywords:["look","watch","stalk","peek","see"],char:'👀',fitzpatrick_scale:false,category:"people"},brain:{keywords:["smart","intelligent"],char:'🧠',fitzpatrick_scale:false,category:"people"},bust_in_silhouette:{keywords:["user","person","human"],char:'👤',fitzpatrick_scale:false,category:"people"},busts_in_silhouette:{keywords:["user","person","human","group","team"],char:'👥',fitzpatrick_scale:false,category:"people"},speaking_head:{keywords:["user","person","human","sing","say","talk"],char:'🗣',fitzpatrick_scale:false,category:"people"},baby:{keywords:["child","boy","girl","toddler"],char:'👶',fitzpatrick_scale:true,category:"people"},child:{keywords:["gender-neutral","young"],char:'🧒',fitzpatrick_scale:true,category:"people"},boy:{keywords:["man","male","guy","teenager"],char:'👦',fitzpatrick_scale:true,category:"people"},girl:{keywords:["female","woman","teenager"],char:'👧',fitzpatrick_scale:true,category:"people"},adult:{keywords:["gender-neutral","person"],char:'🧑',fitzpatrick_scale:true,category:"people"},man:{keywords:["mustache","father","dad","guy","classy","sir","moustache"],char:'👨',fitzpatrick_scale:true,category:"people"},woman:{keywords:["female","girls","lady"],char:'👩',fitzpatrick_scale:true,category:"people"},blonde_woman:{keywords:["woman","female","girl","blonde","person"],char:'👱‍♀️',fitzpatrick_scale:true,category:"people"},blonde_man:{keywords:["man","male","boy","blonde","guy","person"],char:'👱',fitzpatrick_scale:true,category:"people"},bearded_person:{keywords:["person","bewhiskered"],char:'🧔',fitzpatrick_scale:true,category:"people"},older_adult:{keywords:["human","elder","senior","gender-neutral"],char:'🧓',fitzpatrick_scale:true,category:"people"},older_man:{keywords:["human","male","men","old","elder","senior"],char:'👴',fitzpatrick_scale:true,category:"people"},older_woman:{keywords:["human","female","women","lady","old","elder","senior"],char:'👵',fitzpatrick_scale:true,category:"people"},man_with_gua_pi_mao:{keywords:["male","boy","chinese"],char:'👲',fitzpatrick_scale:true,category:"people"},woman_with_headscarf:{keywords:["female","hijab","mantilla","tichel"],char:'🧕',fitzpatrick_scale:true,category:"people"},woman_with_turban:{keywords:["female","indian","hinduism","arabs","woman"],char:'👳‍♀️',fitzpatrick_scale:true,category:"people"},man_with_turban:{keywords:["male","indian","hinduism","arabs"],char:'👳',fitzpatrick_scale:true,category:"people"},policewoman:{keywords:["woman","police","law","legal","enforcement","arrest","911","female"],char:'👮‍♀️',fitzpatrick_scale:true,category:"people"},policeman:{keywords:["man","police","law","legal","enforcement","arrest","911"],char:'👮',fitzpatrick_scale:true,category:"people"},construction_worker_woman:{keywords:["female","human","wip","build","construction","worker","labor","woman"],char:'👷‍♀️',fitzpatrick_scale:true,category:"people"},construction_worker_man:{keywords:["male","human","wip","guy","build","construction","worker","labor"],char:'👷',fitzpatrick_scale:true,category:"people"},guardswoman:{keywords:["uk","gb","british","female","royal","woman"],char:'💂‍♀️',fitzpatrick_scale:true,category:"people"},guardsman:{keywords:["uk","gb","british","male","guy","royal"],char:'💂',fitzpatrick_scale:true,category:"people"},female_detective:{keywords:["human","spy","detective","female","woman"],char:'🕵️‍♀️',fitzpatrick_scale:true,category:"people"},male_detective:{keywords:["human","spy","detective"],char:'🕵',fitzpatrick_scale:true,category:"people"},woman_health_worker:{keywords:["doctor","nurse","therapist","healthcare","woman","human"],char:'👩‍⚕️',fitzpatrick_scale:true,category:"people"},man_health_worker:{keywords:["doctor","nurse","therapist","healthcare","man","human"],char:'👨‍⚕️',fitzpatrick_scale:true,category:"people"},woman_farmer:{keywords:["rancher","gardener","woman","human"],char:'👩‍🌾',fitzpatrick_scale:true,category:"people"},man_farmer:{keywords:["rancher","gardener","man","human"],char:'👨‍🌾',fitzpatrick_scale:true,category:"people"},woman_cook:{keywords:["chef","woman","human"],char:'👩‍🍳',fitzpatrick_scale:true,category:"people"},man_cook:{keywords:["chef","man","human"],char:'👨‍🍳',fitzpatrick_scale:true,category:"people"},woman_student:{keywords:["graduate","woman","human"],char:'👩‍🎓',fitzpatrick_scale:true,category:"people"},man_student:{keywords:["graduate","man","human"],char:'👨‍🎓',fitzpatrick_scale:true,category:"people"},woman_singer:{keywords:["rockstar","entertainer","woman","human"],char:'👩‍🎤',fitzpatrick_scale:true,category:"people"},man_singer:{keywords:["rockstar","entertainer","man","human"],char:'👨‍🎤',fitzpatrick_scale:true,category:"people"},woman_teacher:{keywords:["instructor","professor","woman","human"],char:'👩‍🏫',fitzpatrick_scale:true,category:"people"},man_teacher:{keywords:["instructor","professor","man","human"],char:'👨‍🏫',fitzpatrick_scale:true,category:"people"},woman_factory_worker:{keywords:["assembly","industrial","woman","human"],char:'👩‍🏭',fitzpatrick_scale:true,category:"people"},man_factory_worker:{keywords:["assembly","industrial","man","human"],char:'👨‍🏭',fitzpatrick_scale:true,category:"people"},woman_technologist:{keywords:["coder","developer","engineer","programmer","software","woman","human","laptop","computer"],char:'👩‍💻',fitzpatrick_scale:true,category:"people"},man_technologist:{keywords:["coder","developer","engineer","programmer","software","man","human","laptop","computer"],char:'👨‍💻',fitzpatrick_scale:true,category:"people"},woman_office_worker:{keywords:["business","manager","woman","human"],char:'👩‍💼',fitzpatrick_scale:true,category:"people"},man_office_worker:{keywords:["business","manager","man","human"],char:'👨‍💼',fitzpatrick_scale:true,category:"people"},woman_mechanic:{keywords:["plumber","woman","human","wrench"],char:'👩‍🔧',fitzpatrick_scale:true,category:"people"},man_mechanic:{keywords:["plumber","man","human","wrench"],char:'👨‍🔧',fitzpatrick_scale:true,category:"people"},woman_scientist:{keywords:["biologist","chemist","engineer","physicist","woman","human"],char:'👩‍🔬',fitzpatrick_scale:true,category:"people"},man_scientist:{keywords:["biologist","chemist","engineer","physicist","man","human"],char:'👨‍🔬',fitzpatrick_scale:true,category:"people"},woman_artist:{keywords:["painter","woman","human"],char:'👩‍🎨',fitzpatrick_scale:true,category:"people"},man_artist:{keywords:["painter","man","human"],char:'👨‍🎨',fitzpatrick_scale:true,category:"people"},woman_firefighter:{keywords:["fireman","woman","human"],char:'👩‍🚒',fitzpatrick_scale:true,category:"people"},man_firefighter:{keywords:["fireman","man","human"],char:'👨‍🚒',fitzpatrick_scale:true,category:"people"},woman_pilot:{keywords:["aviator","plane","woman","human"],char:'👩‍✈️',fitzpatrick_scale:true,category:"people"},man_pilot:{keywords:["aviator","plane","man","human"],char:'👨‍✈️',fitzpatrick_scale:true,category:"people"},woman_astronaut:{keywords:["space","rocket","woman","human"],char:'👩‍🚀',fitzpatrick_scale:true,category:"people"},man_astronaut:{keywords:["space","rocket","man","human"],char:'👨‍🚀',fitzpatrick_scale:true,category:"people"},woman_judge:{keywords:["justice","court","woman","human"],char:'👩‍⚖️',fitzpatrick_scale:true,category:"people"},man_judge:{keywords:["justice","court","man","human"],char:'👨‍⚖️',fitzpatrick_scale:true,category:"people"},woman_superhero:{keywords:["woman","female","good","heroine","superpowers"],char:'🦸‍♀️',fitzpatrick_scale:true,category:"people"},man_superhero:{keywords:["man","male","good","hero","superpowers"],char:'🦸‍♂️',fitzpatrick_scale:true,category:"people"},woman_supervillain:{keywords:["woman","female","evil","bad","criminal","heroine","superpowers"],char:'🦹‍♀️',fitzpatrick_scale:true,category:"people"},man_supervillain:{keywords:["man","male","evil","bad","criminal","hero","superpowers"],char:'🦹‍♂️',fitzpatrick_scale:true,category:"people"},mrs_claus:{keywords:["woman","female","xmas","mother christmas"],char:'🤶',fitzpatrick_scale:true,category:"people"},santa:{keywords:["festival","man","male","xmas","father christmas"],char:'🎅',fitzpatrick_scale:true,category:"people"},sorceress:{keywords:["woman","female","mage","witch"],char:'🧙‍♀️',fitzpatrick_scale:true,category:"people"},wizard:{keywords:["man","male","mage","sorcerer"],char:'🧙‍♂️',fitzpatrick_scale:true,category:"people"},woman_elf:{keywords:["woman","female"],char:'🧝‍♀️',fitzpatrick_scale:true,category:"people"},man_elf:{keywords:["man","male"],char:'🧝‍♂️',fitzpatrick_scale:true,category:"people"},woman_vampire:{keywords:["woman","female"],char:'🧛‍♀️',fitzpatrick_scale:true,category:"people"},man_vampire:{keywords:["man","male","dracula"],char:'🧛‍♂️',fitzpatrick_scale:true,category:"people"},woman_zombie:{keywords:["woman","female","undead","walking dead"],char:'🧟‍♀️',fitzpatrick_scale:false,category:"people"},man_zombie:{keywords:["man","male","dracula","undead","walking dead"],char:'🧟‍♂️',fitzpatrick_scale:false,category:"people"},woman_genie:{keywords:["woman","female"],char:'🧞‍♀️',fitzpatrick_scale:false,category:"people"},man_genie:{keywords:["man","male"],char:'🧞‍♂️',fitzpatrick_scale:false,category:"people"},mermaid:{keywords:["woman","female","merwoman","ariel"],char:'🧜‍♀️',fitzpatrick_scale:true,category:"people"},merman:{keywords:["man","male","triton"],char:'🧜‍♂️',fitzpatrick_scale:true,category:"people"},woman_fairy:{keywords:["woman","female"],char:'🧚‍♀️',fitzpatrick_scale:true,category:"people"},man_fairy:{keywords:["man","male"],char:'🧚‍♂️',fitzpatrick_scale:true,category:"people"},angel:{keywords:["heaven","wings","halo"],char:'👼',fitzpatrick_scale:true,category:"people"},pregnant_woman:{keywords:["baby"],char:'🤰',fitzpatrick_scale:true,category:"people"},breastfeeding:{keywords:["nursing","baby"],char:'🤱',fitzpatrick_scale:true,category:"people"},princess:{keywords:["girl","woman","female","blond","crown","royal","queen"],char:'👸',fitzpatrick_scale:true,category:"people"},prince:{keywords:["boy","man","male","crown","royal","king"],char:'🤴',fitzpatrick_scale:true,category:"people"},bride_with_veil:{keywords:["couple","marriage","wedding","woman","bride"],char:'👰',fitzpatrick_scale:true,category:"people"},man_in_tuxedo:{keywords:["couple","marriage","wedding","groom"],char:'🤵',fitzpatrick_scale:true,category:"people"},running_woman:{keywords:["woman","walking","exercise","race","running","female"],char:'🏃‍♀️',fitzpatrick_scale:true,category:"people"},running_man:{keywords:["man","walking","exercise","race","running"],char:'🏃',fitzpatrick_scale:true,category:"people"},walking_woman:{keywords:["human","feet","steps","woman","female"],char:'🚶‍♀️',fitzpatrick_scale:true,category:"people"},walking_man:{keywords:["human","feet","steps"],char:'🚶',fitzpatrick_scale:true,category:"people"},dancer:{keywords:["female","girl","woman","fun"],char:'💃',fitzpatrick_scale:true,category:"people"},man_dancing:{keywords:["male","boy","fun","dancer"],char:'🕺',fitzpatrick_scale:true,category:"people"},dancing_women:{keywords:["female","bunny","women","girls"],char:'👯',fitzpatrick_scale:false,category:"people"},dancing_men:{keywords:["male","bunny","men","boys"],char:'👯‍♂️',fitzpatrick_scale:false,category:"people"},couple:{keywords:["pair","people","human","love","date","dating","like","affection","valentines","marriage"],char:'👫',fitzpatrick_scale:false,category:"people"},two_men_holding_hands:{keywords:["pair","couple","love","like","bromance","friendship","people","human"],char:'👬',fitzpatrick_scale:false,category:"people"},two_women_holding_hands:{keywords:["pair","friendship","couple","love","like","female","people","human"],char:'👭',fitzpatrick_scale:false,category:"people"},bowing_woman:{keywords:["woman","female","girl"],char:'🙇‍♀️',fitzpatrick_scale:true,category:"people"},bowing_man:{keywords:["man","male","boy"],char:'🙇',fitzpatrick_scale:true,category:"people"},man_facepalming:{keywords:["man","male","boy","disbelief"],char:'🤦‍♂️',fitzpatrick_scale:true,category:"people"},woman_facepalming:{keywords:["woman","female","girl","disbelief"],char:'🤦‍♀️',fitzpatrick_scale:true,category:"people"},woman_shrugging:{keywords:["woman","female","girl","confused","indifferent","doubt"],char:'🤷',fitzpatrick_scale:true,category:"people"},man_shrugging:{keywords:["man","male","boy","confused","indifferent","doubt"],char:'🤷‍♂️',fitzpatrick_scale:true,category:"people"},tipping_hand_woman:{keywords:["female","girl","woman","human","information"],char:'💁',fitzpatrick_scale:true,category:"people"},tipping_hand_man:{keywords:["male","boy","man","human","information"],char:'💁‍♂️',fitzpatrick_scale:true,category:"people"},no_good_woman:{keywords:["female","girl","woman","nope"],char:'🙅',fitzpatrick_scale:true,category:"people"},no_good_man:{keywords:["male","boy","man","nope"],char:'🙅‍♂️',fitzpatrick_scale:true,category:"people"},ok_woman:{keywords:["women","girl","female","pink","human","woman"],char:'🙆',fitzpatrick_scale:true,category:"people"},ok_man:{keywords:["men","boy","male","blue","human","man"],char:'🙆‍♂️',fitzpatrick_scale:true,category:"people"},raising_hand_woman:{keywords:["female","girl","woman"],char:'🙋',fitzpatrick_scale:true,category:"people"},raising_hand_man:{keywords:["male","boy","man"],char:'🙋‍♂️',fitzpatrick_scale:true,category:"people"},pouting_woman:{keywords:["female","girl","woman"],char:'🙎',fitzpatrick_scale:true,category:"people"},pouting_man:{keywords:["male","boy","man"],char:'🙎‍♂️',fitzpatrick_scale:true,category:"people"},frowning_woman:{keywords:["female","girl","woman","sad","depressed","discouraged","unhappy"],char:'🙍',fitzpatrick_scale:true,category:"people"},frowning_man:{keywords:["male","boy","man","sad","depressed","discouraged","unhappy"],char:'🙍‍♂️',fitzpatrick_scale:true,category:"people"},haircut_woman:{keywords:["female","girl","woman"],char:'💇',fitzpatrick_scale:true,category:"people"},haircut_man:{keywords:["male","boy","man"],char:'💇‍♂️',fitzpatrick_scale:true,category:"people"},massage_woman:{keywords:["female","girl","woman","head"],char:'💆',fitzpatrick_scale:true,category:"people"},massage_man:{keywords:["male","boy","man","head"],char:'💆‍♂️',fitzpatrick_scale:true,category:"people"},woman_in_steamy_room:{keywords:["female","woman","spa","steamroom","sauna"],char:'🧖‍♀️',fitzpatrick_scale:true,category:"people"},man_in_steamy_room:{keywords:["male","man","spa","steamroom","sauna"],char:'🧖‍♂️',fitzpatrick_scale:true,category:"people"},couple_with_heart_woman_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:'💑',fitzpatrick_scale:false,category:"people"},couple_with_heart_woman_woman:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:'👩‍❤️‍👩',fitzpatrick_scale:false,category:"people"},couple_with_heart_man_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:'👨‍❤️‍👨',fitzpatrick_scale:false,category:"people"},couplekiss_man_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:'💏',fitzpatrick_scale:false,category:"people"},couplekiss_woman_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:'👩‍❤️‍💋‍👩',fitzpatrick_scale:false,category:"people"},couplekiss_man_man:{keywords:["pair","valentines","love","like","dating","marriage"],char:'👨‍❤️‍💋‍👨',fitzpatrick_scale:false,category:"people"},family_man_woman_boy:{keywords:["home","parents","child","mom","dad","father","mother","people","human"],char:'👪',fitzpatrick_scale:false,category:"people"},family_man_woman_girl:{keywords:["home","parents","people","human","child"],char:'👨‍👩‍👧',fitzpatrick_scale:false,category:"people"},family_man_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:'👨‍👩‍👧‍👦',fitzpatrick_scale:false,category:"people"},family_man_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:'👨‍👩‍👦‍👦',fitzpatrick_scale:false,category:"people"},family_man_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:'👨‍👩‍👧‍👧',fitzpatrick_scale:false,category:"people"},family_woman_woman_boy:{keywords:["home","parents","people","human","children"],char:'👩‍👩‍👦',fitzpatrick_scale:false,category:"people"},family_woman_woman_girl:{keywords:["home","parents","people","human","children"],char:'👩‍👩‍👧',fitzpatrick_scale:false,category:"people"},family_woman_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:'👩‍👩‍👧‍👦',fitzpatrick_scale:false,category:"people"},family_woman_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:'👩‍👩‍👦‍👦',fitzpatrick_scale:false,category:"people"},family_woman_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:'👩‍👩‍👧‍👧',fitzpatrick_scale:false,category:"people"},family_man_man_boy:{keywords:["home","parents","people","human","children"],char:'👨‍👨‍👦',fitzpatrick_scale:false,category:"people"},family_man_man_girl:{keywords:["home","parents","people","human","children"],char:'👨‍👨‍👧',fitzpatrick_scale:false,category:"people"},family_man_man_girl_boy:{keywords:["home","parents","people","human","children"],char:'👨‍👨‍👧‍👦',fitzpatrick_scale:false,category:"people"},family_man_man_boy_boy:{keywords:["home","parents","people","human","children"],char:'👨‍👨‍👦‍👦',fitzpatrick_scale:false,category:"people"},family_man_man_girl_girl:{keywords:["home","parents","people","human","children"],char:'👨‍👨‍👧‍👧',fitzpatrick_scale:false,category:"people"},family_woman_boy:{keywords:["home","parent","people","human","child"],char:'👩‍👦',fitzpatrick_scale:false,category:"people"},family_woman_girl:{keywords:["home","parent","people","human","child"],char:'👩‍👧',fitzpatrick_scale:false,category:"people"},family_woman_girl_boy:{keywords:["home","parent","people","human","children"],char:'👩‍👧‍👦',fitzpatrick_scale:false,category:"people"},family_woman_boy_boy:{keywords:["home","parent","people","human","children"],char:'👩‍👦‍👦',fitzpatrick_scale:false,category:"people"},family_woman_girl_girl:{keywords:["home","parent","people","human","children"],char:'👩‍👧‍👧',fitzpatrick_scale:false,category:"people"},family_man_boy:{keywords:["home","parent","people","human","child"],char:'👨‍👦',fitzpatrick_scale:false,category:"people"},family_man_girl:{keywords:["home","parent","people","human","child"],char:'👨‍👧',fitzpatrick_scale:false,category:"people"},family_man_girl_boy:{keywords:["home","parent","people","human","children"],char:'👨‍👧‍👦',fitzpatrick_scale:false,category:"people"},family_man_boy_boy:{keywords:["home","parent","people","human","children"],char:'👨‍👦‍👦',fitzpatrick_scale:false,category:"people"},family_man_girl_girl:{keywords:["home","parent","people","human","children"],char:'👨‍👧‍👧',fitzpatrick_scale:false,category:"people"},yarn:{keywords:["ball","crochet","knit"],char:'🧶',fitzpatrick_scale:false,category:"people"},thread:{keywords:["needle","sewing","spool","string"],char:'🧵',fitzpatrick_scale:false,category:"people"},coat:{keywords:["jacket"],char:'🧥',fitzpatrick_scale:false,category:"people"},labcoat:{keywords:["doctor","experiment","scientist","chemist"],char:'🥼',fitzpatrick_scale:false,category:"people"},womans_clothes:{keywords:["fashion","shopping_bags","female"],char:'👚',fitzpatrick_scale:false,category:"people"},tshirt:{keywords:["fashion","cloth","casual","shirt","tee"],char:'👕',fitzpatrick_scale:false,category:"people"},jeans:{keywords:["fashion","shopping"],char:'👖',fitzpatrick_scale:false,category:"people"},necktie:{keywords:["shirt","suitup","formal","fashion","cloth","business"],char:'👔',fitzpatrick_scale:false,category:"people"},dress:{keywords:["clothes","fashion","shopping"],char:'👗',fitzpatrick_scale:false,category:"people"},bikini:{keywords:["swimming","female","woman","girl","fashion","beach","summer"],char:'👙',fitzpatrick_scale:false,category:"people"},kimono:{keywords:["dress","fashion","women","female","japanese"],char:'👘',fitzpatrick_scale:false,category:"people"},lipstick:{keywords:["female","girl","fashion","woman"],char:'💄',fitzpatrick_scale:false,category:"people"},kiss:{keywords:["face","lips","love","like","affection","valentines"],char:'💋',fitzpatrick_scale:false,category:"people"},footprints:{keywords:["feet","tracking","walking","beach"],char:'👣',fitzpatrick_scale:false,category:"people"},flat_shoe:{keywords:["ballet","slip-on","slipper"],char:'🥿',fitzpatrick_scale:false,category:"people"},high_heel:{keywords:["fashion","shoes","female","pumps","stiletto"],char:'👠',fitzpatrick_scale:false,category:"people"},sandal:{keywords:["shoes","fashion","flip flops"],char:'👡',fitzpatrick_scale:false,category:"people"},boot:{keywords:["shoes","fashion"],char:'👢',fitzpatrick_scale:false,category:"people"},mans_shoe:{keywords:["fashion","male"],char:'👞',fitzpatrick_scale:false,category:"people"},athletic_shoe:{keywords:["shoes","sports","sneakers"],char:'👟',fitzpatrick_scale:false,category:"people"},hiking_boot:{keywords:["backpacking","camping","hiking"],char:'🥾',fitzpatrick_scale:false,category:"people"},socks:{keywords:["stockings","clothes"],char:'🧦',fitzpatrick_scale:false,category:"people"},gloves:{keywords:["hands","winter","clothes"],char:'🧤',fitzpatrick_scale:false,category:"people"},scarf:{keywords:["neck","winter","clothes"],char:'🧣',fitzpatrick_scale:false,category:"people"},womans_hat:{keywords:["fashion","accessories","female","lady","spring"],char:'👒',fitzpatrick_scale:false,category:"people"},tophat:{keywords:["magic","gentleman","classy","circus"],char:'🎩',fitzpatrick_scale:false,category:"people"},billed_hat:{keywords:["cap","baseball"],char:'🧢',fitzpatrick_scale:false,category:"people"},rescue_worker_helmet:{keywords:["construction","build"],char:'⛑',fitzpatrick_scale:false,category:"people"},mortar_board:{keywords:["school","college","degree","university","graduation","cap","hat","legal","learn","education"],char:'🎓',fitzpatrick_scale:false,category:"people"},crown:{keywords:["king","kod","leader","royalty","lord"],char:'👑',fitzpatrick_scale:false,category:"people"},school_satchel:{keywords:["student","education","bag","backpack"],char:'🎒',fitzpatrick_scale:false,category:"people"},luggage:{keywords:["packing","travel"],char:'🧳',fitzpatrick_scale:false,category:"people"},pouch:{keywords:["bag","accessories","shopping"],char:'👝',fitzpatrick_scale:false,category:"people"},purse:{keywords:["fashion","accessories","money","sales","shopping"],char:'👛',fitzpatrick_scale:false,category:"people"},handbag:{keywords:["fashion","accessory","accessories","shopping"],char:'👜',fitzpatrick_scale:false,category:"people"},briefcase:{keywords:["business","documents","work","law","legal","job","career"],char:'💼',fitzpatrick_scale:false,category:"people"},eyeglasses:{keywords:["fashion","accessories","eyesight","nerdy","dork","geek"],char:'👓',fitzpatrick_scale:false,category:"people"},dark_sunglasses:{keywords:["face","cool","accessories"],char:'🕶',fitzpatrick_scale:false,category:"people"},goggles:{keywords:["eyes","protection","safety"],char:'🥽',fitzpatrick_scale:false,category:"people"},ring:{keywords:["wedding","propose","marriage","valentines","diamond","fashion","jewelry","gem","engagement"],char:'💍',fitzpatrick_scale:false,category:"people"},closed_umbrella:{keywords:["weather","rain","drizzle"],char:'🌂',fitzpatrick_scale:false,category:"people"},dog:{keywords:["animal","friend","nature","woof","puppy","pet","faithful"],char:'🐶',fitzpatrick_scale:false,category:"animals_and_nature"},cat:{keywords:["animal","meow","nature","pet","kitten"],char:'🐱',fitzpatrick_scale:false,category:"animals_and_nature"},mouse:{keywords:["animal","nature","cheese_wedge","rodent"],char:'🐭',fitzpatrick_scale:false,category:"animals_and_nature"},hamster:{keywords:["animal","nature"],char:'🐹',fitzpatrick_scale:false,category:"animals_and_nature"},rabbit:{keywords:["animal","nature","pet","spring","magic","bunny"],char:'🐰',fitzpatrick_scale:false,category:"animals_and_nature"},fox_face:{keywords:["animal","nature","face"],char:'🦊',fitzpatrick_scale:false,category:"animals_and_nature"},bear:{keywords:["animal","nature","wild"],char:'🐻',fitzpatrick_scale:false,category:"animals_and_nature"},panda_face:{keywords:["animal","nature","panda"],char:'🐼',fitzpatrick_scale:false,category:"animals_and_nature"},koala:{keywords:["animal","nature"],char:'🐨',fitzpatrick_scale:false,category:"animals_and_nature"},tiger:{keywords:["animal","cat","danger","wild","nature","roar"],char:'🐯',fitzpatrick_scale:false,category:"animals_and_nature"},lion:{keywords:["animal","nature"],char:'🦁',fitzpatrick_scale:false,category:"animals_and_nature"},cow:{keywords:["beef","ox","animal","nature","moo","milk"],char:'🐮',fitzpatrick_scale:false,category:"animals_and_nature"},pig:{keywords:["animal","oink","nature"],char:'🐷',fitzpatrick_scale:false,category:"animals_and_nature"},pig_nose:{keywords:["animal","oink"],char:'🐽',fitzpatrick_scale:false,category:"animals_and_nature"},frog:{keywords:["animal","nature","croak","toad"],char:'🐸',fitzpatrick_scale:false,category:"animals_and_nature"},squid:{keywords:["animal","nature","ocean","sea"],char:'🦑',fitzpatrick_scale:false,category:"animals_and_nature"},octopus:{keywords:["animal","creature","ocean","sea","nature","beach"],char:'🐙',fitzpatrick_scale:false,category:"animals_and_nature"},shrimp:{keywords:["animal","ocean","nature","seafood"],char:'🦐',fitzpatrick_scale:false,category:"animals_and_nature"},monkey_face:{keywords:["animal","nature","circus"],char:'🐵',fitzpatrick_scale:false,category:"animals_and_nature"},gorilla:{keywords:["animal","nature","circus"],char:'🦍',fitzpatrick_scale:false,category:"animals_and_nature"},see_no_evil:{keywords:["monkey","animal","nature","haha"],char:'🙈',fitzpatrick_scale:false,category:"animals_and_nature"},hear_no_evil:{keywords:["animal","monkey","nature"],char:'🙉',fitzpatrick_scale:false,category:"animals_and_nature"},speak_no_evil:{keywords:["monkey","animal","nature","omg"],char:'🙊',fitzpatrick_scale:false,category:"animals_and_nature"},monkey:{keywords:["animal","nature","banana","circus"],char:'🐒',fitzpatrick_scale:false,category:"animals_and_nature"},chicken:{keywords:["animal","cluck","nature","bird"],char:'🐔',fitzpatrick_scale:false,category:"animals_and_nature"},penguin:{keywords:["animal","nature"],char:'🐧',fitzpatrick_scale:false,category:"animals_and_nature"},bird:{keywords:["animal","nature","fly","tweet","spring"],char:'🐦',fitzpatrick_scale:false,category:"animals_and_nature"},baby_chick:{keywords:["animal","chicken","bird"],char:'🐤',fitzpatrick_scale:false,category:"animals_and_nature"},hatching_chick:{keywords:["animal","chicken","egg","born","baby","bird"],char:'🐣',fitzpatrick_scale:false,category:"animals_and_nature"},hatched_chick:{keywords:["animal","chicken","baby","bird"],char:'🐥',fitzpatrick_scale:false,category:"animals_and_nature"},duck:{keywords:["animal","nature","bird","mallard"],char:'🦆',fitzpatrick_scale:false,category:"animals_and_nature"},eagle:{keywords:["animal","nature","bird"],char:'🦅',fitzpatrick_scale:false,category:"animals_and_nature"},owl:{keywords:["animal","nature","bird","hoot"],char:'🦉',fitzpatrick_scale:false,category:"animals_and_nature"},bat:{keywords:["animal","nature","blind","vampire"],char:'🦇',fitzpatrick_scale:false,category:"animals_and_nature"},wolf:{keywords:["animal","nature","wild"],char:'🐺',fitzpatrick_scale:false,category:"animals_and_nature"},boar:{keywords:["animal","nature"],char:'🐗',fitzpatrick_scale:false,category:"animals_and_nature"},horse:{keywords:["animal","brown","nature"],char:'🐴',fitzpatrick_scale:false,category:"animals_and_nature"},unicorn:{keywords:["animal","nature","mystical"],char:'🦄',fitzpatrick_scale:false,category:"animals_and_nature"},honeybee:{keywords:["animal","insect","nature","bug","spring","honey"],char:'🐝',fitzpatrick_scale:false,category:"animals_and_nature"},bug:{keywords:["animal","insect","nature","worm"],char:'🐛',fitzpatrick_scale:false,category:"animals_and_nature"},butterfly:{keywords:["animal","insect","nature","caterpillar"],char:'🦋',fitzpatrick_scale:false,category:"animals_and_nature"},snail:{keywords:["slow","animal","shell"],char:'🐌',fitzpatrick_scale:false,category:"animals_and_nature"},beetle:{keywords:["animal","insect","nature","ladybug"],char:'🐞',fitzpatrick_scale:false,category:"animals_and_nature"},ant:{keywords:["animal","insect","nature","bug"],char:'🐜',fitzpatrick_scale:false,category:"animals_and_nature"},grasshopper:{keywords:["animal","cricket","chirp"],char:'🦗',fitzpatrick_scale:false,category:"animals_and_nature"},spider:{keywords:["animal","arachnid"],char:'🕷',fitzpatrick_scale:false,category:"animals_and_nature"},scorpion:{keywords:["animal","arachnid"],char:'🦂',fitzpatrick_scale:false,category:"animals_and_nature"},crab:{keywords:["animal","crustacean"],char:'🦀',fitzpatrick_scale:false,category:"animals_and_nature"},snake:{keywords:["animal","evil","nature","hiss","python"],char:'🐍',fitzpatrick_scale:false,category:"animals_and_nature"},lizard:{keywords:["animal","nature","reptile"],char:'🦎',fitzpatrick_scale:false,category:"animals_and_nature"},"t-rex":{keywords:["animal","nature","dinosaur","tyrannosaurus","extinct"],char:'🦖',fitzpatrick_scale:false,category:"animals_and_nature"},sauropod:{keywords:["animal","nature","dinosaur","brachiosaurus","brontosaurus","diplodocus","extinct"],char:'🦕',fitzpatrick_scale:false,category:"animals_and_nature"},turtle:{keywords:["animal","slow","nature","tortoise"],char:'🐢',fitzpatrick_scale:false,category:"animals_and_nature"},tropical_fish:{keywords:["animal","swim","ocean","beach","nemo"],char:'🐠',fitzpatrick_scale:false,category:"animals_and_nature"},fish:{keywords:["animal","food","nature"],char:'🐟',fitzpatrick_scale:false,category:"animals_and_nature"},blowfish:{keywords:["animal","nature","food","sea","ocean"],char:'🐡',fitzpatrick_scale:false,category:"animals_and_nature"},dolphin:{keywords:["animal","nature","fish","sea","ocean","flipper","fins","beach"],char:'🐬',fitzpatrick_scale:false,category:"animals_and_nature"},shark:{keywords:["animal","nature","fish","sea","ocean","jaws","fins","beach"],char:'🦈',fitzpatrick_scale:false,category:"animals_and_nature"},whale:{keywords:["animal","nature","sea","ocean"],char:'🐳',fitzpatrick_scale:false,category:"animals_and_nature"},whale2:{keywords:["animal","nature","sea","ocean"],char:'🐋',fitzpatrick_scale:false,category:"animals_and_nature"},crocodile:{keywords:["animal","nature","reptile","lizard","alligator"],char:'🐊',fitzpatrick_scale:false,category:"animals_and_nature"},leopard:{keywords:["animal","nature"],char:'🐆',fitzpatrick_scale:false,category:"animals_and_nature"},zebra:{keywords:["animal","nature","stripes","safari"],char:'🦓',fitzpatrick_scale:false,category:"animals_and_nature"},tiger2:{keywords:["animal","nature","roar"],char:'🐅',fitzpatrick_scale:false,category:"animals_and_nature"},water_buffalo:{keywords:["animal","nature","ox","cow"],char:'🐃',fitzpatrick_scale:false,category:"animals_and_nature"},ox:{keywords:["animal","cow","beef"],char:'🐂',fitzpatrick_scale:false,category:"animals_and_nature"},cow2:{keywords:["beef","ox","animal","nature","moo","milk"],char:'🐄',fitzpatrick_scale:false,category:"animals_and_nature"},deer:{keywords:["animal","nature","horns","venison"],char:'🦌',fitzpatrick_scale:false,category:"animals_and_nature"},dromedary_camel:{keywords:["animal","hot","desert","hump"],char:'🐪',fitzpatrick_scale:false,category:"animals_and_nature"},camel:{keywords:["animal","nature","hot","desert","hump"],char:'🐫',fitzpatrick_scale:false,category:"animals_and_nature"},giraffe:{keywords:["animal","nature","spots","safari"],char:'🦒',fitzpatrick_scale:false,category:"animals_and_nature"},elephant:{keywords:["animal","nature","nose","th","circus"],char:'🐘',fitzpatrick_scale:false,category:"animals_and_nature"},rhinoceros:{keywords:["animal","nature","horn"],char:'🦏',fitzpatrick_scale:false,category:"animals_and_nature"},goat:{keywords:["animal","nature"],char:'🐐',fitzpatrick_scale:false,category:"animals_and_nature"},ram:{keywords:["animal","sheep","nature"],char:'🐏',fitzpatrick_scale:false,category:"animals_and_nature"},sheep:{keywords:["animal","nature","wool","shipit"],char:'🐑',fitzpatrick_scale:false,category:"animals_and_nature"},racehorse:{keywords:["animal","gamble","luck"],char:'🐎',fitzpatrick_scale:false,category:"animals_and_nature"},pig2:{keywords:["animal","nature"],char:'🐖',fitzpatrick_scale:false,category:"animals_and_nature"},rat:{keywords:["animal","mouse","rodent"],char:'🐀',fitzpatrick_scale:false,category:"animals_and_nature"},mouse2:{keywords:["animal","nature","rodent"],char:'🐁',fitzpatrick_scale:false,category:"animals_and_nature"},rooster:{keywords:["animal","nature","chicken"],char:'🐓',fitzpatrick_scale:false,category:"animals_and_nature"},turkey:{keywords:["animal","bird"],char:'🦃',fitzpatrick_scale:false,category:"animals_and_nature"},dove:{keywords:["animal","bird"],char:'🕊',fitzpatrick_scale:false,category:"animals_and_nature"},dog2:{keywords:["animal","nature","friend","doge","pet","faithful"],char:'🐕',fitzpatrick_scale:false,category:"animals_and_nature"},poodle:{keywords:["dog","animal","101","nature","pet"],char:'🐩',fitzpatrick_scale:false,category:"animals_and_nature"},cat2:{keywords:["animal","meow","pet","cats"],char:'🐈',fitzpatrick_scale:false,category:"animals_and_nature"},rabbit2:{keywords:["animal","nature","pet","magic","spring"],char:'🐇',fitzpatrick_scale:false,category:"animals_and_nature"},chipmunk:{keywords:["animal","nature","rodent","squirrel"],char:'🐿',fitzpatrick_scale:false,category:"animals_and_nature"},hedgehog:{keywords:["animal","nature","spiny"],char:'🦔',fitzpatrick_scale:false,category:"animals_and_nature"},raccoon:{keywords:["animal","nature"],char:'🦝',fitzpatrick_scale:false,category:"animals_and_nature"},llama:{keywords:["animal","nature","alpaca"],char:'🦙',fitzpatrick_scale:false,category:"animals_and_nature"},hippopotamus:{keywords:["animal","nature"],char:'🦛',fitzpatrick_scale:false,category:"animals_and_nature"},kangaroo:{keywords:["animal","nature","australia","joey","hop","marsupial"],char:'🦘',fitzpatrick_scale:false,category:"animals_and_nature"},badger:{keywords:["animal","nature","honey"],char:'🦡',fitzpatrick_scale:false,category:"animals_and_nature"},swan:{keywords:["animal","nature","bird"],char:'🦢',fitzpatrick_scale:false,category:"animals_and_nature"},peacock:{keywords:["animal","nature","peahen","bird"],char:'🦚',fitzpatrick_scale:false,category:"animals_and_nature"},parrot:{keywords:["animal","nature","bird","pirate","talk"],char:'🦜',fitzpatrick_scale:false,category:"animals_and_nature"},lobster:{keywords:["animal","nature","bisque","claws","seafood"],char:'🦞',fitzpatrick_scale:false,category:"animals_and_nature"},mosquito:{keywords:["animal","nature","insect","malaria"],char:'🦟',fitzpatrick_scale:false,category:"animals_and_nature"},paw_prints:{keywords:["animal","tracking","footprints","dog","cat","pet","feet"],char:'🐾',fitzpatrick_scale:false,category:"animals_and_nature"},dragon:{keywords:["animal","myth","nature","chinese","green"],char:'🐉',fitzpatrick_scale:false,category:"animals_and_nature"},dragon_face:{keywords:["animal","myth","nature","chinese","green"],char:'🐲',fitzpatrick_scale:false,category:"animals_and_nature"},cactus:{keywords:["vegetable","plant","nature"],char:'🌵',fitzpatrick_scale:false,category:"animals_and_nature"},christmas_tree:{keywords:["festival","vacation","december","xmas","celebration"],char:'🎄',fitzpatrick_scale:false,category:"animals_and_nature"},evergreen_tree:{keywords:["plant","nature"],char:'🌲',fitzpatrick_scale:false,category:"animals_and_nature"},deciduous_tree:{keywords:["plant","nature"],char:'🌳',fitzpatrick_scale:false,category:"animals_and_nature"},palm_tree:{keywords:["plant","vegetable","nature","summer","beach","mojito","tropical"],char:'🌴',fitzpatrick_scale:false,category:"animals_and_nature"},seedling:{keywords:["plant","nature","grass","lawn","spring"],char:'🌱',fitzpatrick_scale:false,category:"animals_and_nature"},herb:{keywords:["vegetable","plant","medicine","weed","grass","lawn"],char:'🌿',fitzpatrick_scale:false,category:"animals_and_nature"},shamrock:{keywords:["vegetable","plant","nature","irish","clover"],char:'☘',fitzpatrick_scale:false,category:"animals_and_nature"},four_leaf_clover:{keywords:["vegetable","plant","nature","lucky","irish"],char:'🍀',fitzpatrick_scale:false,category:"animals_and_nature"},bamboo:{keywords:["plant","nature","vegetable","panda","pine_decoration"],char:'🎍',fitzpatrick_scale:false,category:"animals_and_nature"},tanabata_tree:{keywords:["plant","nature","branch","summer"],char:'🎋',fitzpatrick_scale:false,category:"animals_and_nature"},leaves:{keywords:["nature","plant","tree","vegetable","grass","lawn","spring"],char:'🍃',fitzpatrick_scale:false,category:"animals_and_nature"},fallen_leaf:{keywords:["nature","plant","vegetable","leaves"],char:'🍂',fitzpatrick_scale:false,category:"animals_and_nature"},maple_leaf:{keywords:["nature","plant","vegetable","ca","fall"],char:'🍁',fitzpatrick_scale:false,category:"animals_and_nature"},ear_of_rice:{keywords:["nature","plant"],char:'🌾',fitzpatrick_scale:false,category:"animals_and_nature"},hibiscus:{keywords:["plant","vegetable","flowers","beach"],char:'🌺',fitzpatrick_scale:false,category:"animals_and_nature"},sunflower:{keywords:["nature","plant","fall"],char:'🌻',fitzpatrick_scale:false,category:"animals_and_nature"},rose:{keywords:["flowers","valentines","love","spring"],char:'🌹',fitzpatrick_scale:false,category:"animals_and_nature"},wilted_flower:{keywords:["plant","nature","flower"],char:'🥀',fitzpatrick_scale:false,category:"animals_and_nature"},tulip:{keywords:["flowers","plant","nature","summer","spring"],char:'🌷',fitzpatrick_scale:false,category:"animals_and_nature"},blossom:{keywords:["nature","flowers","yellow"],char:'🌼',fitzpatrick_scale:false,category:"animals_and_nature"},cherry_blossom:{keywords:["nature","plant","spring","flower"],char:'🌸',fitzpatrick_scale:false,category:"animals_and_nature"},bouquet:{keywords:["flowers","nature","spring"],char:'💐',fitzpatrick_scale:false,category:"animals_and_nature"},mushroom:{keywords:["plant","vegetable"],char:'🍄',fitzpatrick_scale:false,category:"animals_and_nature"},chestnut:{keywords:["food","squirrel"],char:'🌰',fitzpatrick_scale:false,category:"animals_and_nature"},jack_o_lantern:{keywords:["halloween","light","pumpkin","creepy","fall"],char:'🎃',fitzpatrick_scale:false,category:"animals_and_nature"},shell:{keywords:["nature","sea","beach"],char:'🐚',fitzpatrick_scale:false,category:"animals_and_nature"},spider_web:{keywords:["animal","insect","arachnid","silk"],char:'🕸',fitzpatrick_scale:false,category:"animals_and_nature"},earth_americas:{keywords:["globe","world","USA","international"],char:'🌎',fitzpatrick_scale:false,category:"animals_and_nature"},earth_africa:{keywords:["globe","world","international"],char:'🌍',fitzpatrick_scale:false,category:"animals_and_nature"},earth_asia:{keywords:["globe","world","east","international"],char:'🌏',fitzpatrick_scale:false,category:"animals_and_nature"},full_moon:{keywords:["nature","yellow","twilight","planet","space","night","evening","sleep"],char:'🌕',fitzpatrick_scale:false,category:"animals_and_nature"},waning_gibbous_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep","waxing_gibbous_moon"],char:'🌖',fitzpatrick_scale:false,category:"animals_and_nature"},last_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'🌗',fitzpatrick_scale:false,category:"animals_and_nature"},waning_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'🌘',fitzpatrick_scale:false,category:"animals_and_nature"},new_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'🌑',fitzpatrick_scale:false,category:"animals_and_nature"},waxing_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'🌒',fitzpatrick_scale:false,category:"animals_and_nature"},first_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'🌓',fitzpatrick_scale:false,category:"animals_and_nature"},waxing_gibbous_moon:{keywords:["nature","night","sky","gray","twilight","planet","space","evening","sleep"],char:'🌔',fitzpatrick_scale:false,category:"animals_and_nature"},new_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'🌚',fitzpatrick_scale:false,category:"animals_and_nature"},full_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'🌝',fitzpatrick_scale:false,category:"animals_and_nature"},first_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'🌛',fitzpatrick_scale:false,category:"animals_and_nature"},last_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'🌜',fitzpatrick_scale:false,category:"animals_and_nature"},sun_with_face:{keywords:["nature","morning","sky"],char:'🌞',fitzpatrick_scale:false,category:"animals_and_nature"},crescent_moon:{keywords:["night","sleep","sky","evening","magic"],char:'🌙',fitzpatrick_scale:false,category:"animals_and_nature"},star:{keywords:["night","yellow"],char:'⭐',fitzpatrick_scale:false,category:"animals_and_nature"},star2:{keywords:["night","sparkle","awesome","good","magic"],char:'🌟',fitzpatrick_scale:false,category:"animals_and_nature"},dizzy:{keywords:["star","sparkle","shoot","magic"],char:'💫',fitzpatrick_scale:false,category:"animals_and_nature"},sparkles:{keywords:["stars","shine","shiny","cool","awesome","good","magic"],char:'✨',fitzpatrick_scale:false,category:"animals_and_nature"},comet:{keywords:["space"],char:'☄',fitzpatrick_scale:false,category:"animals_and_nature"},sunny:{keywords:["weather","nature","brightness","summer","beach","spring"],char:'☀️',fitzpatrick_scale:false,category:"animals_and_nature"},sun_behind_small_cloud:{keywords:["weather"],char:'🌤',fitzpatrick_scale:false,category:"animals_and_nature"},partly_sunny:{keywords:["weather","nature","cloudy","morning","fall","spring"],char:'⛅',fitzpatrick_scale:false,category:"animals_and_nature"},sun_behind_large_cloud:{keywords:["weather"],char:'🌥',fitzpatrick_scale:false,category:"animals_and_nature"},sun_behind_rain_cloud:{keywords:["weather"],char:'🌦',fitzpatrick_scale:false,category:"animals_and_nature"},cloud:{keywords:["weather","sky"],char:'☁️',fitzpatrick_scale:false,category:"animals_and_nature"},cloud_with_rain:{keywords:["weather"],char:'🌧',fitzpatrick_scale:false,category:"animals_and_nature"},cloud_with_lightning_and_rain:{keywords:["weather","lightning"],char:'⛈',fitzpatrick_scale:false,category:"animals_and_nature"},cloud_with_lightning:{keywords:["weather","thunder"],char:'🌩',fitzpatrick_scale:false,category:"animals_and_nature"},zap:{keywords:["thunder","weather","lightning bolt","fast"],char:'⚡',fitzpatrick_scale:false,category:"animals_and_nature"},fire:{keywords:["hot","cook","flame"],char:'🔥',fitzpatrick_scale:false,category:"animals_and_nature"},boom:{keywords:["bomb","explode","explosion","collision","blown"],char:'💥',fitzpatrick_scale:false,category:"animals_and_nature"},snowflake:{keywords:["winter","season","cold","weather","christmas","xmas"],char:'❄️',fitzpatrick_scale:false,category:"animals_and_nature"},cloud_with_snow:{keywords:["weather"],char:'🌨',fitzpatrick_scale:false,category:"animals_and_nature"},snowman:{keywords:["winter","season","cold","weather","christmas","xmas","frozen","without_snow"],char:'⛄',fitzpatrick_scale:false,category:"animals_and_nature"},snowman_with_snow:{keywords:["winter","season","cold","weather","christmas","xmas","frozen"],char:'☃',fitzpatrick_scale:false,category:"animals_and_nature"},wind_face:{keywords:["gust","air"],char:'🌬',fitzpatrick_scale:false,category:"animals_and_nature"},dash:{keywords:["wind","air","fast","shoo","fart","smoke","puff"],char:'💨',fitzpatrick_scale:false,category:"animals_and_nature"},tornado:{keywords:["weather","cyclone","twister"],char:'🌪',fitzpatrick_scale:false,category:"animals_and_nature"},fog:{keywords:["weather"],char:'🌫',fitzpatrick_scale:false,category:"animals_and_nature"},open_umbrella:{keywords:["weather","spring"],char:'☂',fitzpatrick_scale:false,category:"animals_and_nature"},umbrella:{keywords:["rainy","weather","spring"],char:'☔',fitzpatrick_scale:false,category:"animals_and_nature"},droplet:{keywords:["water","drip","faucet","spring"],char:'💧',fitzpatrick_scale:false,category:"animals_and_nature"},sweat_drops:{keywords:["water","drip","oops"],char:'💦',fitzpatrick_scale:false,category:"animals_and_nature"},ocean:{keywords:["sea","water","wave","nature","tsunami","disaster"],char:'🌊',fitzpatrick_scale:false,category:"animals_and_nature"},green_apple:{keywords:["fruit","nature"],char:'🍏',fitzpatrick_scale:false,category:"food_and_drink"},apple:{keywords:["fruit","mac","school"],char:'🍎',fitzpatrick_scale:false,category:"food_and_drink"},pear:{keywords:["fruit","nature","food"],char:'🍐',fitzpatrick_scale:false,category:"food_and_drink"},tangerine:{keywords:["food","fruit","nature","orange"],char:'🍊',fitzpatrick_scale:false,category:"food_and_drink"},lemon:{keywords:["fruit","nature"],char:'🍋',fitzpatrick_scale:false,category:"food_and_drink"},banana:{keywords:["fruit","food","monkey"],char:'🍌',fitzpatrick_scale:false,category:"food_and_drink"},watermelon:{keywords:["fruit","food","picnic","summer"],char:'🍉',fitzpatrick_scale:false,category:"food_and_drink"},grapes:{keywords:["fruit","food","wine"],char:'🍇',fitzpatrick_scale:false,category:"food_and_drink"},strawberry:{keywords:["fruit","food","nature"],char:'🍓',fitzpatrick_scale:false,category:"food_and_drink"},melon:{keywords:["fruit","nature","food"],char:'🍈',fitzpatrick_scale:false,category:"food_and_drink"},cherries:{keywords:["food","fruit"],char:'🍒',fitzpatrick_scale:false,category:"food_and_drink"},peach:{keywords:["fruit","nature","food"],char:'🍑',fitzpatrick_scale:false,category:"food_and_drink"},pineapple:{keywords:["fruit","nature","food"],char:'🍍',fitzpatrick_scale:false,category:"food_and_drink"},coconut:{keywords:["fruit","nature","food","palm"],char:'🥥',fitzpatrick_scale:false,category:"food_and_drink"},kiwi_fruit:{keywords:["fruit","food"],char:'🥝',fitzpatrick_scale:false,category:"food_and_drink"},mango:{keywords:["fruit","food","tropical"],char:'🥭',fitzpatrick_scale:false,category:"food_and_drink"},avocado:{keywords:["fruit","food"],char:'🥑',fitzpatrick_scale:false,category:"food_and_drink"},broccoli:{keywords:["fruit","food","vegetable"],char:'🥦',fitzpatrick_scale:false,category:"food_and_drink"},tomato:{keywords:["fruit","vegetable","nature","food"],char:'🍅',fitzpatrick_scale:false,category:"food_and_drink"},eggplant:{keywords:["vegetable","nature","food","aubergine"],char:'🍆',fitzpatrick_scale:false,category:"food_and_drink"},cucumber:{keywords:["fruit","food","pickle"],char:'🥒',fitzpatrick_scale:false,category:"food_and_drink"},carrot:{keywords:["vegetable","food","orange"],char:'🥕',fitzpatrick_scale:false,category:"food_and_drink"},hot_pepper:{keywords:["food","spicy","chilli","chili"],char:'🌶',fitzpatrick_scale:false,category:"food_and_drink"},potato:{keywords:["food","tuber","vegatable","starch"],char:'🥔',fitzpatrick_scale:false,category:"food_and_drink"},corn:{keywords:["food","vegetable","plant"],char:'🌽',fitzpatrick_scale:false,category:"food_and_drink"},leafy_greens:{keywords:["food","vegetable","plant","bok choy","cabbage","kale","lettuce"],char:'🥬',fitzpatrick_scale:false,category:"food_and_drink"},sweet_potato:{keywords:["food","nature"],char:'🍠',fitzpatrick_scale:false,category:"food_and_drink"},peanuts:{keywords:["food","nut"],char:'🥜',fitzpatrick_scale:false,category:"food_and_drink"},honey_pot:{keywords:["bees","sweet","kitchen"],char:'🍯',fitzpatrick_scale:false,category:"food_and_drink"},croissant:{keywords:["food","bread","french"],char:'🥐',fitzpatrick_scale:false,category:"food_and_drink"},bread:{keywords:["food","wheat","breakfast","toast"],char:'🍞',fitzpatrick_scale:false,category:"food_and_drink"},baguette_bread:{keywords:["food","bread","french"],char:'🥖',fitzpatrick_scale:false,category:"food_and_drink"},bagel:{keywords:["food","bread","bakery","schmear"],char:'🥯',fitzpatrick_scale:false,category:"food_and_drink"},pretzel:{keywords:["food","bread","twisted"],char:'🥨',fitzpatrick_scale:false,category:"food_and_drink"},cheese:{keywords:["food","chadder"],char:'🧀',fitzpatrick_scale:false,category:"food_and_drink"},egg:{keywords:["food","chicken","breakfast"],char:'🥚',fitzpatrick_scale:false,category:"food_and_drink"},bacon:{keywords:["food","breakfast","pork","pig","meat"],char:'🥓',fitzpatrick_scale:false,category:"food_and_drink"},steak:{keywords:["food","cow","meat","cut","chop","lambchop","porkchop"],char:'🥩',fitzpatrick_scale:false,category:"food_and_drink"},pancakes:{keywords:["food","breakfast","flapjacks","hotcakes"],char:'🥞',fitzpatrick_scale:false,category:"food_and_drink"},poultry_leg:{keywords:["food","meat","drumstick","bird","chicken","turkey"],char:'🍗',fitzpatrick_scale:false,category:"food_and_drink"},meat_on_bone:{keywords:["good","food","drumstick"],char:'🍖',fitzpatrick_scale:false,category:"food_and_drink"},bone:{keywords:["skeleton"],char:'🦴',fitzpatrick_scale:false,category:"food_and_drink"},fried_shrimp:{keywords:["food","animal","appetizer","summer"],char:'🍤',fitzpatrick_scale:false,category:"food_and_drink"},fried_egg:{keywords:["food","breakfast","kitchen","egg"],char:'🍳',fitzpatrick_scale:false,category:"food_and_drink"},hamburger:{keywords:["meat","fast food","beef","cheeseburger","mcdonalds","burger king"],char:'🍔',fitzpatrick_scale:false,category:"food_and_drink"},fries:{keywords:["chips","snack","fast food"],char:'🍟',fitzpatrick_scale:false,category:"food_and_drink"},stuffed_flatbread:{keywords:["food","flatbread","stuffed","gyro"],char:'🥙',fitzpatrick_scale:false,category:"food_and_drink"},hotdog:{keywords:["food","frankfurter"],char:'🌭',fitzpatrick_scale:false,category:"food_and_drink"},pizza:{keywords:["food","party"],char:'🍕',fitzpatrick_scale:false,category:"food_and_drink"},sandwich:{keywords:["food","lunch","bread"],char:'🥪',fitzpatrick_scale:false,category:"food_and_drink"},canned_food:{keywords:["food","soup"],char:'🥫',fitzpatrick_scale:false,category:"food_and_drink"},spaghetti:{keywords:["food","italian","noodle"],char:'🍝',fitzpatrick_scale:false,category:"food_and_drink"},taco:{keywords:["food","mexican"],char:'🌮',fitzpatrick_scale:false,category:"food_and_drink"},burrito:{keywords:["food","mexican"],char:'🌯',fitzpatrick_scale:false,category:"food_and_drink"},green_salad:{keywords:["food","healthy","lettuce"],char:'🥗',fitzpatrick_scale:false,category:"food_and_drink"},shallow_pan_of_food:{keywords:["food","cooking","casserole","paella"],char:'🥘',fitzpatrick_scale:false,category:"food_and_drink"},ramen:{keywords:["food","japanese","noodle","chopsticks"],char:'🍜',fitzpatrick_scale:false,category:"food_and_drink"},stew:{keywords:["food","meat","soup"],char:'🍲',fitzpatrick_scale:false,category:"food_and_drink"},fish_cake:{keywords:["food","japan","sea","beach","narutomaki","pink","swirl","kamaboko","surimi","ramen"],char:'🍥',fitzpatrick_scale:false,category:"food_and_drink"},fortune_cookie:{keywords:["food","prophecy"],char:'🥠',fitzpatrick_scale:false,category:"food_and_drink"},sushi:{keywords:["food","fish","japanese","rice"],char:'🍣',fitzpatrick_scale:false,category:"food_and_drink"},bento:{keywords:["food","japanese","box"],char:'🍱',fitzpatrick_scale:false,category:"food_and_drink"},curry:{keywords:["food","spicy","hot","indian"],char:'🍛',fitzpatrick_scale:false,category:"food_and_drink"},rice_ball:{keywords:["food","japanese"],char:'🍙',fitzpatrick_scale:false,category:"food_and_drink"},rice:{keywords:["food","china","asian"],char:'🍚',fitzpatrick_scale:false,category:"food_and_drink"},rice_cracker:{keywords:["food","japanese"],char:'🍘',fitzpatrick_scale:false,category:"food_and_drink"},oden:{keywords:["food","japanese"],char:'🍢',fitzpatrick_scale:false,category:"food_and_drink"},dango:{keywords:["food","dessert","sweet","japanese","barbecue","meat"],char:'🍡',fitzpatrick_scale:false,category:"food_and_drink"},shaved_ice:{keywords:["hot","dessert","summer"],char:'🍧',fitzpatrick_scale:false,category:"food_and_drink"},ice_cream:{keywords:["food","hot","dessert"],char:'🍨',fitzpatrick_scale:false,category:"food_and_drink"},icecream:{keywords:["food","hot","dessert","summer"],char:'🍦',fitzpatrick_scale:false,category:"food_and_drink"},pie:{keywords:["food","dessert","pastry"],char:'🥧',fitzpatrick_scale:false,category:"food_and_drink"},cake:{keywords:["food","dessert"],char:'🍰',fitzpatrick_scale:false,category:"food_and_drink"},cupcake:{keywords:["food","dessert","bakery","sweet"],char:'🧁',fitzpatrick_scale:false,category:"food_and_drink"},moon_cake:{keywords:["food","autumn"],char:'🥮',fitzpatrick_scale:false,category:"food_and_drink"},birthday:{keywords:["food","dessert","cake"],char:'🎂',fitzpatrick_scale:false,category:"food_and_drink"},custard:{keywords:["dessert","food"],char:'🍮',fitzpatrick_scale:false,category:"food_and_drink"},candy:{keywords:["snack","dessert","sweet","lolly"],char:'🍬',fitzpatrick_scale:false,category:"food_and_drink"},lollipop:{keywords:["food","snack","candy","sweet"],char:'🍭',fitzpatrick_scale:false,category:"food_and_drink"},chocolate_bar:{keywords:["food","snack","dessert","sweet"],char:'🍫',fitzpatrick_scale:false,category:"food_and_drink"},popcorn:{keywords:["food","movie theater","films","snack"],char:'🍿',fitzpatrick_scale:false,category:"food_and_drink"},dumpling:{keywords:["food","empanada","pierogi","potsticker"],char:'🥟',fitzpatrick_scale:false,category:"food_and_drink"},doughnut:{keywords:["food","dessert","snack","sweet","donut"],char:'🍩',fitzpatrick_scale:false,category:"food_and_drink"},cookie:{keywords:["food","snack","oreo","chocolate","sweet","dessert"],char:'🍪',fitzpatrick_scale:false,category:"food_and_drink"},milk_glass:{keywords:["beverage","drink","cow"],char:'🥛',fitzpatrick_scale:false,category:"food_and_drink"},beer:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:'🍺',fitzpatrick_scale:false,category:"food_and_drink"},beers:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:'🍻',fitzpatrick_scale:false,category:"food_and_drink"},clinking_glasses:{keywords:["beverage","drink","party","alcohol","celebrate","cheers","wine","champagne","toast"],char:'🥂',fitzpatrick_scale:false,category:"food_and_drink"},wine_glass:{keywords:["drink","beverage","drunk","alcohol","booze"],char:'🍷',fitzpatrick_scale:false,category:"food_and_drink"},tumbler_glass:{keywords:["drink","beverage","drunk","alcohol","liquor","booze","bourbon","scotch","whisky","glass","shot"],char:'🥃',fitzpatrick_scale:false,category:"food_and_drink"},cocktail:{keywords:["drink","drunk","alcohol","beverage","booze","mojito"],char:'🍸',fitzpatrick_scale:false,category:"food_and_drink"},tropical_drink:{keywords:["beverage","cocktail","summer","beach","alcohol","booze","mojito"],char:'🍹',fitzpatrick_scale:false,category:"food_and_drink"},champagne:{keywords:["drink","wine","bottle","celebration"],char:'🍾',fitzpatrick_scale:false,category:"food_and_drink"},sake:{keywords:["wine","drink","drunk","beverage","japanese","alcohol","booze"],char:'🍶',fitzpatrick_scale:false,category:"food_and_drink"},tea:{keywords:["drink","bowl","breakfast","green","british"],char:'🍵',fitzpatrick_scale:false,category:"food_and_drink"},cup_with_straw:{keywords:["drink","soda"],char:'🥤',fitzpatrick_scale:false,category:"food_and_drink"},coffee:{keywords:["beverage","caffeine","latte","espresso"],char:'☕',fitzpatrick_scale:false,category:"food_and_drink"},baby_bottle:{keywords:["food","container","milk"],char:'🍼',fitzpatrick_scale:false,category:"food_and_drink"},salt:{keywords:["condiment","shaker"],char:'🧂',fitzpatrick_scale:false,category:"food_and_drink"},spoon:{keywords:["cutlery","kitchen","tableware"],char:'🥄',fitzpatrick_scale:false,category:"food_and_drink"},fork_and_knife:{keywords:["cutlery","kitchen"],char:'🍴',fitzpatrick_scale:false,category:"food_and_drink"},plate_with_cutlery:{keywords:["food","eat","meal","lunch","dinner","restaurant"],char:'🍽',fitzpatrick_scale:false,category:"food_and_drink"},bowl_with_spoon:{keywords:["food","breakfast","cereal","oatmeal","porridge"],char:'🥣',fitzpatrick_scale:false,category:"food_and_drink"},takeout_box:{keywords:["food","leftovers"],char:'🥡',fitzpatrick_scale:false,category:"food_and_drink"},chopsticks:{keywords:["food"],char:'🥢',fitzpatrick_scale:false,category:"food_and_drink"},soccer:{keywords:["sports","football"],char:'⚽',fitzpatrick_scale:false,category:"activity"},basketball:{keywords:["sports","balls","NBA"],char:'🏀',fitzpatrick_scale:false,category:"activity"},football:{keywords:["sports","balls","NFL"],char:'🏈',fitzpatrick_scale:false,category:"activity"},baseball:{keywords:["sports","balls"],char:'⚾',fitzpatrick_scale:false,category:"activity"},softball:{keywords:["sports","balls"],char:'🥎',fitzpatrick_scale:false,category:"activity"},tennis:{keywords:["sports","balls","green"],char:'🎾',fitzpatrick_scale:false,category:"activity"},volleyball:{keywords:["sports","balls"],char:'🏐',fitzpatrick_scale:false,category:"activity"},rugby_football:{keywords:["sports","team"],char:'🏉',fitzpatrick_scale:false,category:"activity"},flying_disc:{keywords:["sports","frisbee","ultimate"],char:'🥏',fitzpatrick_scale:false,category:"activity"},"8ball":{keywords:["pool","hobby","game","luck","magic"],char:'🎱',fitzpatrick_scale:false,category:"activity"},golf:{keywords:["sports","business","flag","hole","summer"],char:'⛳',fitzpatrick_scale:false,category:"activity"},golfing_woman:{keywords:["sports","business","woman","female"],char:'🏌️‍♀️',fitzpatrick_scale:false,category:"activity"},golfing_man:{keywords:["sports","business"],char:'🏌',fitzpatrick_scale:true,category:"activity"},ping_pong:{keywords:["sports","pingpong"],char:'🏓',fitzpatrick_scale:false,category:"activity"},badminton:{keywords:["sports"],char:'🏸',fitzpatrick_scale:false,category:"activity"},goal_net:{keywords:["sports"],char:'🥅',fitzpatrick_scale:false,category:"activity"},ice_hockey:{keywords:["sports"],char:'🏒',fitzpatrick_scale:false,category:"activity"},field_hockey:{keywords:["sports"],char:'🏑',fitzpatrick_scale:false,category:"activity"},lacrosse:{keywords:["sports","ball","stick"],char:'🥍',fitzpatrick_scale:false,category:"activity"},cricket:{keywords:["sports"],char:'🏏',fitzpatrick_scale:false,category:"activity"},ski:{keywords:["sports","winter","cold","snow"],char:'🎿',fitzpatrick_scale:false,category:"activity"},skier:{keywords:["sports","winter","snow"],char:'⛷',fitzpatrick_scale:false,category:"activity"},snowboarder:{keywords:["sports","winter"],char:'🏂',fitzpatrick_scale:true,category:"activity"},person_fencing:{keywords:["sports","fencing","sword"],char:'🤺',fitzpatrick_scale:false,category:"activity"},women_wrestling:{keywords:["sports","wrestlers"],char:'🤼‍♀️',fitzpatrick_scale:false,category:"activity"},men_wrestling:{keywords:["sports","wrestlers"],char:'🤼‍♂️',fitzpatrick_scale:false,category:"activity"},woman_cartwheeling:{keywords:["gymnastics"],char:'🤸‍♀️',fitzpatrick_scale:true,category:"activity"},man_cartwheeling:{keywords:["gymnastics"],char:'🤸‍♂️',fitzpatrick_scale:true,category:"activity"},woman_playing_handball:{keywords:["sports"],char:'🤾‍♀️',fitzpatrick_scale:true,category:"activity"},man_playing_handball:{keywords:["sports"],char:'🤾‍♂️',fitzpatrick_scale:true,category:"activity"},ice_skate:{keywords:["sports"],char:'⛸',fitzpatrick_scale:false,category:"activity"},curling_stone:{keywords:["sports"],char:'🥌',fitzpatrick_scale:false,category:"activity"},skateboard:{keywords:["board"],char:'🛹',fitzpatrick_scale:false,category:"activity"},sled:{keywords:["sleigh","luge","toboggan"],char:'🛷',fitzpatrick_scale:false,category:"activity"},bow_and_arrow:{keywords:["sports"],char:'🏹',fitzpatrick_scale:false,category:"activity"},fishing_pole_and_fish:{keywords:["food","hobby","summer"],char:'🎣',fitzpatrick_scale:false,category:"activity"},boxing_glove:{keywords:["sports","fighting"],char:'🥊',fitzpatrick_scale:false,category:"activity"},martial_arts_uniform:{keywords:["judo","karate","taekwondo"],char:'🥋',fitzpatrick_scale:false,category:"activity"},rowing_woman:{keywords:["sports","hobby","water","ship","woman","female"],char:'🚣‍♀️',fitzpatrick_scale:true,category:"activity"},rowing_man:{keywords:["sports","hobby","water","ship"],char:'🚣',fitzpatrick_scale:true,category:"activity"},climbing_woman:{keywords:["sports","hobby","woman","female","rock"],char:'🧗‍♀️',fitzpatrick_scale:true,category:"activity"},climbing_man:{keywords:["sports","hobby","man","male","rock"],char:'🧗‍♂️',fitzpatrick_scale:true,category:"activity"},swimming_woman:{keywords:["sports","exercise","human","athlete","water","summer","woman","female"],char:'🏊‍♀️',fitzpatrick_scale:true,category:"activity"},swimming_man:{keywords:["sports","exercise","human","athlete","water","summer"],char:'🏊',fitzpatrick_scale:true,category:"activity"},woman_playing_water_polo:{keywords:["sports","pool"],char:'🤽‍♀️',fitzpatrick_scale:true,category:"activity"},man_playing_water_polo:{keywords:["sports","pool"],char:'🤽‍♂️',fitzpatrick_scale:true,category:"activity"},woman_in_lotus_position:{keywords:["woman","female","meditation","yoga","serenity","zen","mindfulness"],char:'🧘‍♀️',fitzpatrick_scale:true,category:"activity"},man_in_lotus_position:{keywords:["man","male","meditation","yoga","serenity","zen","mindfulness"],char:'🧘‍♂️',fitzpatrick_scale:true,category:"activity"},surfing_woman:{keywords:["sports","ocean","sea","summer","beach","woman","female"],char:'🏄‍♀️',fitzpatrick_scale:true,category:"activity"},surfing_man:{keywords:["sports","ocean","sea","summer","beach"],char:'🏄',fitzpatrick_scale:true,category:"activity"},bath:{keywords:["clean","shower","bathroom"],char:'🛀',fitzpatrick_scale:true,category:"activity"},basketball_woman:{keywords:["sports","human","woman","female"],char:'⛹️‍♀️',fitzpatrick_scale:true,category:"activity"},basketball_man:{keywords:["sports","human"],char:'⛹',fitzpatrick_scale:true,category:"activity"},weight_lifting_woman:{keywords:["sports","training","exercise","woman","female"],char:'🏋️‍♀️',fitzpatrick_scale:true,category:"activity"},weight_lifting_man:{keywords:["sports","training","exercise"],char:'🏋',fitzpatrick_scale:true,category:"activity"},biking_woman:{keywords:["sports","bike","exercise","hipster","woman","female"],char:'🚴‍♀️',fitzpatrick_scale:true,category:"activity"},biking_man:{keywords:["sports","bike","exercise","hipster"],char:'🚴',fitzpatrick_scale:true,category:"activity"},mountain_biking_woman:{keywords:["transportation","sports","human","race","bike","woman","female"],char:'🚵‍♀️',fitzpatrick_scale:true,category:"activity"},mountain_biking_man:{keywords:["transportation","sports","human","race","bike"],char:'🚵',fitzpatrick_scale:true,category:"activity"},horse_racing:{keywords:["animal","betting","competition","gambling","luck"],char:'🏇',fitzpatrick_scale:true,category:"activity"},business_suit_levitating:{keywords:["suit","business","levitate","hover","jump"],char:'🕴',fitzpatrick_scale:true,category:"activity"},trophy:{keywords:["win","award","contest","place","ftw","ceremony"],char:'🏆',fitzpatrick_scale:false,category:"activity"},running_shirt_with_sash:{keywords:["play","pageant"],char:'🎽',fitzpatrick_scale:false,category:"activity"},medal_sports:{keywords:["award","winning"],char:'🏅',fitzpatrick_scale:false,category:"activity"},medal_military:{keywords:["award","winning","army"],char:'🎖',fitzpatrick_scale:false,category:"activity"},"1st_place_medal":{keywords:["award","winning","first"],char:'🥇',fitzpatrick_scale:false,category:"activity"},"2nd_place_medal":{keywords:["award","second"],char:'🥈',fitzpatrick_scale:false,category:"activity"},"3rd_place_medal":{keywords:["award","third"],char:'🥉',fitzpatrick_scale:false,category:"activity"},reminder_ribbon:{keywords:["sports","cause","support","awareness"],char:'🎗',fitzpatrick_scale:false,category:"activity"},rosette:{keywords:["flower","decoration","military"],char:'🏵',fitzpatrick_scale:false,category:"activity"},ticket:{keywords:["event","concert","pass"],char:'🎫',fitzpatrick_scale:false,category:"activity"},tickets:{keywords:["sports","concert","entrance"],char:'🎟',fitzpatrick_scale:false,category:"activity"},performing_arts:{keywords:["acting","theater","drama"],char:'🎭',fitzpatrick_scale:false,category:"activity"},art:{keywords:["design","paint","draw","colors"],char:'🎨',fitzpatrick_scale:false,category:"activity"},circus_tent:{keywords:["festival","carnival","party"],char:'🎪',fitzpatrick_scale:false,category:"activity"},woman_juggling:{keywords:["juggle","balance","skill","multitask"],char:'🤹‍♀️',fitzpatrick_scale:true,category:"activity"},man_juggling:{keywords:["juggle","balance","skill","multitask"],char:'🤹‍♂️',fitzpatrick_scale:true,category:"activity"},microphone:{keywords:["sound","music","PA","sing","talkshow"],char:'🎤',fitzpatrick_scale:false,category:"activity"},headphones:{keywords:["music","score","gadgets"],char:'🎧',fitzpatrick_scale:false,category:"activity"},musical_score:{keywords:["treble","clef","compose"],char:'🎼',fitzpatrick_scale:false,category:"activity"},musical_keyboard:{keywords:["piano","instrument","compose"],char:'🎹',fitzpatrick_scale:false,category:"activity"},drum:{keywords:["music","instrument","drumsticks","snare"],char:'🥁',fitzpatrick_scale:false,category:"activity"},saxophone:{keywords:["music","instrument","jazz","blues"],char:'🎷',fitzpatrick_scale:false,category:"activity"},trumpet:{keywords:["music","brass"],char:'🎺',fitzpatrick_scale:false,category:"activity"},guitar:{keywords:["music","instrument"],char:'🎸',fitzpatrick_scale:false,category:"activity"},violin:{keywords:["music","instrument","orchestra","symphony"],char:'🎻',fitzpatrick_scale:false,category:"activity"},clapper:{keywords:["movie","film","record"],char:'🎬',fitzpatrick_scale:false,category:"activity"},video_game:{keywords:["play","console","PS4","controller"],char:'🎮',fitzpatrick_scale:false,category:"activity"},space_invader:{keywords:["game","arcade","play"],char:'👾',fitzpatrick_scale:false,category:"activity"},dart:{keywords:["game","play","bar","target","bullseye"],char:'🎯',fitzpatrick_scale:false,category:"activity"},game_die:{keywords:["dice","random","tabletop","play","luck"],char:'🎲',fitzpatrick_scale:false,category:"activity"},chess_pawn:{keywords:["expendable"],char:"♟",fitzpatrick_scale:false,category:"activity"},slot_machine:{keywords:["bet","gamble","vegas","fruit machine","luck","casino"],char:'🎰',fitzpatrick_scale:false,category:"activity"},jigsaw:{keywords:["interlocking","puzzle","piece"],char:'🧩',fitzpatrick_scale:false,category:"activity"},bowling:{keywords:["sports","fun","play"],char:'🎳',fitzpatrick_scale:false,category:"activity"},red_car:{keywords:["red","transportation","vehicle"],char:'🚗',fitzpatrick_scale:false,category:"travel_and_places"},taxi:{keywords:["uber","vehicle","cars","transportation"],char:'🚕',fitzpatrick_scale:false,category:"travel_and_places"},blue_car:{keywords:["transportation","vehicle"],char:'🚙',fitzpatrick_scale:false,category:"travel_and_places"},bus:{keywords:["car","vehicle","transportation"],char:'🚌',fitzpatrick_scale:false,category:"travel_and_places"},trolleybus:{keywords:["bart","transportation","vehicle"],char:'🚎',fitzpatrick_scale:false,category:"travel_and_places"},racing_car:{keywords:["sports","race","fast","formula","f1"],char:'🏎',fitzpatrick_scale:false,category:"travel_and_places"},police_car:{keywords:["vehicle","cars","transportation","law","legal","enforcement"],char:'🚓',fitzpatrick_scale:false,category:"travel_and_places"},ambulance:{keywords:["health","911","hospital"],char:'🚑',fitzpatrick_scale:false,category:"travel_and_places"},fire_engine:{keywords:["transportation","cars","vehicle"],char:'🚒',fitzpatrick_scale:false,category:"travel_and_places"},minibus:{keywords:["vehicle","car","transportation"],char:'🚐',fitzpatrick_scale:false,category:"travel_and_places"},truck:{keywords:["cars","transportation"],char:'🚚',fitzpatrick_scale:false,category:"travel_and_places"},articulated_lorry:{keywords:["vehicle","cars","transportation","express"],char:'🚛',fitzpatrick_scale:false,category:"travel_and_places"},tractor:{keywords:["vehicle","car","farming","agriculture"],char:'🚜',fitzpatrick_scale:false,category:"travel_and_places"},kick_scooter:{keywords:["vehicle","kick","razor"],char:'🛴',fitzpatrick_scale:false,category:"travel_and_places"},motorcycle:{keywords:["race","sports","fast"],char:'🏍',fitzpatrick_scale:false,category:"travel_and_places"},bike:{keywords:["sports","bicycle","exercise","hipster"],char:'🚲',fitzpatrick_scale:false,category:"travel_and_places"},motor_scooter:{keywords:["vehicle","vespa","sasha"],char:'🛵',fitzpatrick_scale:false,category:"travel_and_places"},rotating_light:{keywords:["police","ambulance","911","emergency","alert","error","pinged","law","legal"],char:'🚨',fitzpatrick_scale:false,category:"travel_and_places"},oncoming_police_car:{keywords:["vehicle","law","legal","enforcement","911"],char:'🚔',fitzpatrick_scale:false,category:"travel_and_places"},oncoming_bus:{keywords:["vehicle","transportation"],char:'🚍',fitzpatrick_scale:false,category:"travel_and_places"},oncoming_automobile:{keywords:["car","vehicle","transportation"],char:'🚘',fitzpatrick_scale:false,category:"travel_and_places"},oncoming_taxi:{keywords:["vehicle","cars","uber"],char:'🚖',fitzpatrick_scale:false,category:"travel_and_places"},aerial_tramway:{keywords:["transportation","vehicle","ski"],char:'🚡',fitzpatrick_scale:false,category:"travel_and_places"},mountain_cableway:{keywords:["transportation","vehicle","ski"],char:'🚠',fitzpatrick_scale:false,category:"travel_and_places"},suspension_railway:{keywords:["vehicle","transportation"],char:'🚟',fitzpatrick_scale:false,category:"travel_and_places"},railway_car:{keywords:["transportation","vehicle"],char:'🚃',fitzpatrick_scale:false,category:"travel_and_places"},train:{keywords:["transportation","vehicle","carriage","public","travel"],char:'🚋',fitzpatrick_scale:false,category:"travel_and_places"},monorail:{keywords:["transportation","vehicle"],char:'🚝',fitzpatrick_scale:false,category:"travel_and_places"},bullettrain_side:{keywords:["transportation","vehicle"],char:'🚄',fitzpatrick_scale:false,category:"travel_and_places"},bullettrain_front:{keywords:["transportation","vehicle","speed","fast","public","travel"],char:'🚅',fitzpatrick_scale:false,category:"travel_and_places"},light_rail:{keywords:["transportation","vehicle"],char:'🚈',fitzpatrick_scale:false,category:"travel_and_places"},mountain_railway:{keywords:["transportation","vehicle"],char:'🚞',fitzpatrick_scale:false,category:"travel_and_places"},steam_locomotive:{keywords:["transportation","vehicle","train"],char:'🚂',fitzpatrick_scale:false,category:"travel_and_places"},train2:{keywords:["transportation","vehicle"],char:'🚆',fitzpatrick_scale:false,category:"travel_and_places"},metro:{keywords:["transportation","blue-square","mrt","underground","tube"],char:'🚇',fitzpatrick_scale:false,category:"travel_and_places"},tram:{keywords:["transportation","vehicle"],char:'🚊',fitzpatrick_scale:false,category:"travel_and_places"},station:{keywords:["transportation","vehicle","public"],char:'🚉',fitzpatrick_scale:false,category:"travel_and_places"},flying_saucer:{keywords:["transportation","vehicle","ufo"],char:'🛸',fitzpatrick_scale:false,category:"travel_and_places"},helicopter:{keywords:["transportation","vehicle","fly"],char:'🚁',fitzpatrick_scale:false,category:"travel_and_places"},small_airplane:{keywords:["flight","transportation","fly","vehicle"],char:'🛩',fitzpatrick_scale:false,category:"travel_and_places"},airplane:{keywords:["vehicle","transportation","flight","fly"],char:'✈️',fitzpatrick_scale:false,category:"travel_and_places"},flight_departure:{keywords:["airport","flight","landing"],char:'🛫',fitzpatrick_scale:false,category:"travel_and_places"},flight_arrival:{keywords:["airport","flight","boarding"],char:'🛬',fitzpatrick_scale:false,category:"travel_and_places"},sailboat:{keywords:["ship","summer","transportation","water","sailing"],char:'⛵',fitzpatrick_scale:false,category:"travel_and_places"},motor_boat:{keywords:["ship"],char:'🛥',fitzpatrick_scale:false,category:"travel_and_places"},speedboat:{keywords:["ship","transportation","vehicle","summer"],char:'🚤',fitzpatrick_scale:false,category:"travel_and_places"},ferry:{keywords:["boat","ship","yacht"],char:'⛴',fitzpatrick_scale:false,category:"travel_and_places"},passenger_ship:{keywords:["yacht","cruise","ferry"],char:'🛳',fitzpatrick_scale:false,category:"travel_and_places"},rocket:{keywords:["launch","ship","staffmode","NASA","outer space","outer_space","fly"],char:'🚀',fitzpatrick_scale:false,category:"travel_and_places"},artificial_satellite:{keywords:["communication","gps","orbit","spaceflight","NASA","ISS"],char:'🛰',fitzpatrick_scale:false,category:"travel_and_places"},seat:{keywords:["sit","airplane","transport","bus","flight","fly"],char:'💺',fitzpatrick_scale:false,category:"travel_and_places"},canoe:{keywords:["boat","paddle","water","ship"],char:'🛶',fitzpatrick_scale:false,category:"travel_and_places"},anchor:{keywords:["ship","ferry","sea","boat"],char:'⚓',fitzpatrick_scale:false,category:"travel_and_places"},construction:{keywords:["wip","progress","caution","warning"],char:'🚧',fitzpatrick_scale:false,category:"travel_and_places"},fuelpump:{keywords:["gas station","petroleum"],char:'⛽',fitzpatrick_scale:false,category:"travel_and_places"},busstop:{keywords:["transportation","wait"],char:'🚏',fitzpatrick_scale:false,category:"travel_and_places"},vertical_traffic_light:{keywords:["transportation","driving"],char:'🚦',fitzpatrick_scale:false,category:"travel_and_places"},traffic_light:{keywords:["transportation","signal"],char:'🚥',fitzpatrick_scale:false,category:"travel_and_places"},checkered_flag:{keywords:["contest","finishline","race","gokart"],char:'🏁',fitzpatrick_scale:false,category:"travel_and_places"},ship:{keywords:["transportation","titanic","deploy"],char:'🚢',fitzpatrick_scale:false,category:"travel_and_places"},ferris_wheel:{keywords:["photo","carnival","londoneye"],char:'🎡',fitzpatrick_scale:false,category:"travel_and_places"},roller_coaster:{keywords:["carnival","playground","photo","fun"],char:'🎢',fitzpatrick_scale:false,category:"travel_and_places"},carousel_horse:{keywords:["photo","carnival"],char:'🎠',fitzpatrick_scale:false,category:"travel_and_places"},building_construction:{keywords:["wip","working","progress"],char:'🏗',fitzpatrick_scale:false,category:"travel_and_places"},foggy:{keywords:["photo","mountain"],char:'🌁',fitzpatrick_scale:false,category:"travel_and_places"},tokyo_tower:{keywords:["photo","japanese"],char:'🗼',fitzpatrick_scale:false,category:"travel_and_places"},factory:{keywords:["building","industry","pollution","smoke"],char:'🏭',fitzpatrick_scale:false,category:"travel_and_places"},fountain:{keywords:["photo","summer","water","fresh"],char:'⛲',fitzpatrick_scale:false,category:"travel_and_places"},rice_scene:{keywords:["photo","japan","asia","tsukimi"],char:'🎑',fitzpatrick_scale:false,category:"travel_and_places"},mountain:{keywords:["photo","nature","environment"],char:'⛰',fitzpatrick_scale:false,category:"travel_and_places"},mountain_snow:{keywords:["photo","nature","environment","winter","cold"],char:'🏔',fitzpatrick_scale:false,category:"travel_and_places"},mount_fuji:{keywords:["photo","mountain","nature","japanese"],char:'🗻',fitzpatrick_scale:false,category:"travel_and_places"},volcano:{keywords:["photo","nature","disaster"],char:'🌋',fitzpatrick_scale:false,category:"travel_and_places"},japan:{keywords:["nation","country","japanese","asia"],char:'🗾',fitzpatrick_scale:false,category:"travel_and_places"},camping:{keywords:["photo","outdoors","tent"],char:'🏕',fitzpatrick_scale:false,category:"travel_and_places"},tent:{keywords:["photo","camping","outdoors"],char:'⛺',fitzpatrick_scale:false,category:"travel_and_places"},national_park:{keywords:["photo","environment","nature"],char:'🏞',fitzpatrick_scale:false,category:"travel_and_places"},motorway:{keywords:["road","cupertino","interstate","highway"],char:'🛣',fitzpatrick_scale:false,category:"travel_and_places"},railway_track:{keywords:["train","transportation"],char:'🛤',fitzpatrick_scale:false,category:"travel_and_places"},sunrise:{keywords:["morning","view","vacation","photo"],char:'🌅',fitzpatrick_scale:false,category:"travel_and_places"},sunrise_over_mountains:{keywords:["view","vacation","photo"],char:'🌄',fitzpatrick_scale:false,category:"travel_and_places"},desert:{keywords:["photo","warm","saharah"],char:'🏜',fitzpatrick_scale:false,category:"travel_and_places"},beach_umbrella:{keywords:["weather","summer","sunny","sand","mojito"],char:'🏖',fitzpatrick_scale:false,category:"travel_and_places"},desert_island:{keywords:["photo","tropical","mojito"],char:'🏝',fitzpatrick_scale:false,category:"travel_and_places"},city_sunrise:{keywords:["photo","good morning","dawn"],char:'🌇',fitzpatrick_scale:false,category:"travel_and_places"},city_sunset:{keywords:["photo","evening","sky","buildings"],char:'🌆',fitzpatrick_scale:false,category:"travel_and_places"},cityscape:{keywords:["photo","night life","urban"],char:'🏙',fitzpatrick_scale:false,category:"travel_and_places"},night_with_stars:{keywords:["evening","city","downtown"],char:'🌃',fitzpatrick_scale:false,category:"travel_and_places"},bridge_at_night:{keywords:["photo","sanfrancisco"],char:'🌉',fitzpatrick_scale:false,category:"travel_and_places"},milky_way:{keywords:["photo","space","stars"],char:'🌌',fitzpatrick_scale:false,category:"travel_and_places"},stars:{keywords:["night","photo"],char:'🌠',fitzpatrick_scale:false,category:"travel_and_places"},sparkler:{keywords:["stars","night","shine"],char:'🎇',fitzpatrick_scale:false,category:"travel_and_places"},fireworks:{keywords:["photo","festival","carnival","congratulations"],char:'🎆',fitzpatrick_scale:false,category:"travel_and_places"},rainbow:{keywords:["nature","happy","unicorn_face","photo","sky","spring"],char:'🌈',fitzpatrick_scale:false,category:"travel_and_places"},houses:{keywords:["buildings","photo"],char:'🏘',fitzpatrick_scale:false,category:"travel_and_places"},european_castle:{keywords:["building","royalty","history"],char:'🏰',fitzpatrick_scale:false,category:"travel_and_places"},japanese_castle:{keywords:["photo","building"],char:'🏯',fitzpatrick_scale:false,category:"travel_and_places"},stadium:{keywords:["photo","place","sports","concert","venue"],char:'🏟',fitzpatrick_scale:false,category:"travel_and_places"},statue_of_liberty:{keywords:["american","newyork"],char:'🗽',fitzpatrick_scale:false,category:"travel_and_places"},house:{keywords:["building","home"],char:'🏠',fitzpatrick_scale:false,category:"travel_and_places"},house_with_garden:{keywords:["home","plant","nature"],char:'🏡',fitzpatrick_scale:false,category:"travel_and_places"},derelict_house:{keywords:["abandon","evict","broken","building"],char:'🏚',fitzpatrick_scale:false,category:"travel_and_places"},office:{keywords:["building","bureau","work"],char:'🏢',fitzpatrick_scale:false,category:"travel_and_places"},department_store:{keywords:["building","shopping","mall"],char:'🏬',fitzpatrick_scale:false,category:"travel_and_places"},post_office:{keywords:["building","envelope","communication"],char:'🏣',fitzpatrick_scale:false,category:"travel_and_places"},european_post_office:{keywords:["building","email"],char:'🏤',fitzpatrick_scale:false,category:"travel_and_places"},hospital:{keywords:["building","health","surgery","doctor"],char:'🏥',fitzpatrick_scale:false,category:"travel_and_places"},bank:{keywords:["building","money","sales","cash","business","enterprise"],char:'🏦',fitzpatrick_scale:false,category:"travel_and_places"},hotel:{keywords:["building","accomodation","checkin"],char:'🏨',fitzpatrick_scale:false,category:"travel_and_places"},convenience_store:{keywords:["building","shopping","groceries"],char:'🏪',fitzpatrick_scale:false,category:"travel_and_places"},school:{keywords:["building","student","education","learn","teach"],char:'🏫',fitzpatrick_scale:false,category:"travel_and_places"},love_hotel:{keywords:["like","affection","dating"],char:'🏩',fitzpatrick_scale:false,category:"travel_and_places"},wedding:{keywords:["love","like","affection","couple","marriage","bride","groom"],char:'💒',fitzpatrick_scale:false,category:"travel_and_places"},classical_building:{keywords:["art","culture","history"],char:'🏛',fitzpatrick_scale:false,category:"travel_and_places"},church:{keywords:["building","religion","christ"],char:'⛪',fitzpatrick_scale:false,category:"travel_and_places"},mosque:{keywords:["islam","worship","minaret"],char:'🕌',fitzpatrick_scale:false,category:"travel_and_places"},synagogue:{keywords:["judaism","worship","temple","jewish"],char:'🕍',fitzpatrick_scale:false,category:"travel_and_places"},kaaba:{keywords:["mecca","mosque","islam"],char:'🕋',fitzpatrick_scale:false,category:"travel_and_places"},shinto_shrine:{keywords:["temple","japan","kyoto"],char:'⛩',fitzpatrick_scale:false,category:"travel_and_places"},watch:{keywords:["time","accessories"],char:'⌚',fitzpatrick_scale:false,category:"objects"},iphone:{keywords:["technology","apple","gadgets","dial"],char:'📱',fitzpatrick_scale:false,category:"objects"},calling:{keywords:["iphone","incoming"],char:'📲',fitzpatrick_scale:false,category:"objects"},computer:{keywords:["technology","laptop","screen","display","monitor"],char:'💻',fitzpatrick_scale:false,category:"objects"},keyboard:{keywords:["technology","computer","type","input","text"],char:'⌨',fitzpatrick_scale:false,category:"objects"},desktop_computer:{keywords:["technology","computing","screen"],char:'🖥',fitzpatrick_scale:false,category:"objects"},printer:{keywords:["paper","ink"],char:'🖨',fitzpatrick_scale:false,category:"objects"},computer_mouse:{keywords:["click"],char:'🖱',fitzpatrick_scale:false,category:"objects"},trackball:{keywords:["technology","trackpad"],char:'🖲',fitzpatrick_scale:false,category:"objects"},joystick:{keywords:["game","play"],char:'🕹',fitzpatrick_scale:false,category:"objects"},clamp:{keywords:["tool"],char:'🗜',fitzpatrick_scale:false,category:"objects"},minidisc:{keywords:["technology","record","data","disk","90s"],char:'💽',fitzpatrick_scale:false,category:"objects"},floppy_disk:{keywords:["oldschool","technology","save","90s","80s"],char:'💾',fitzpatrick_scale:false,category:"objects"},cd:{keywords:["technology","dvd","disk","disc","90s"],char:'💿',fitzpatrick_scale:false,category:"objects"},dvd:{keywords:["cd","disk","disc"],char:'📀',fitzpatrick_scale:false,category:"objects"},vhs:{keywords:["record","video","oldschool","90s","80s"],char:'📼',fitzpatrick_scale:false,category:"objects"},camera:{keywords:["gadgets","photography"],char:'📷',fitzpatrick_scale:false,category:"objects"},camera_flash:{keywords:["photography","gadgets"],char:'📸',fitzpatrick_scale:false,category:"objects"},video_camera:{keywords:["film","record"],char:'📹',fitzpatrick_scale:false,category:"objects"},movie_camera:{keywords:["film","record"],char:'🎥',fitzpatrick_scale:false,category:"objects"},film_projector:{keywords:["video","tape","record","movie"],char:'📽',fitzpatrick_scale:false,category:"objects"},film_strip:{keywords:["movie"],char:'🎞',fitzpatrick_scale:false,category:"objects"},telephone_receiver:{keywords:["technology","communication","dial"],char:'📞',fitzpatrick_scale:false,category:"objects"},phone:{keywords:["technology","communication","dial","telephone"],char:'☎️',fitzpatrick_scale:false,category:"objects"},pager:{keywords:["bbcall","oldschool","90s"],char:'📟',fitzpatrick_scale:false,category:"objects"},fax:{keywords:["communication","technology"],char:'📠',fitzpatrick_scale:false,category:"objects"},tv:{keywords:["technology","program","oldschool","show","television"],char:'📺',fitzpatrick_scale:false,category:"objects"},radio:{keywords:["communication","music","podcast","program"],char:'📻',fitzpatrick_scale:false,category:"objects"},studio_microphone:{keywords:["sing","recording","artist","talkshow"],char:'🎙',fitzpatrick_scale:false,category:"objects"},level_slider:{keywords:["scale"],char:'🎚',fitzpatrick_scale:false,category:"objects"},control_knobs:{keywords:["dial"],char:'🎛',fitzpatrick_scale:false,category:"objects"},compass:{keywords:["magnetic","navigation","orienteering"],char:'🧭',fitzpatrick_scale:false,category:"objects"},stopwatch:{keywords:["time","deadline"],char:'⏱',fitzpatrick_scale:false,category:"objects"},timer_clock:{keywords:["alarm"],char:'⏲',fitzpatrick_scale:false,category:"objects"},alarm_clock:{keywords:["time","wake"],char:'⏰',fitzpatrick_scale:false,category:"objects"},mantelpiece_clock:{keywords:["time"],char:'🕰',fitzpatrick_scale:false,category:"objects"},hourglass_flowing_sand:{keywords:["oldschool","time","countdown"],char:'⏳',fitzpatrick_scale:false,category:"objects"},hourglass:{keywords:["time","clock","oldschool","limit","exam","quiz","test"],char:'⌛',fitzpatrick_scale:false,category:"objects"},satellite:{keywords:["communication","future","radio","space"],char:'📡',fitzpatrick_scale:false,category:"objects"},battery:{keywords:["power","energy","sustain"],char:'🔋',fitzpatrick_scale:false,category:"objects"},electric_plug:{keywords:["charger","power"],char:'🔌',fitzpatrick_scale:false,category:"objects"},bulb:{keywords:["light","electricity","idea"],char:'💡',fitzpatrick_scale:false,category:"objects"},flashlight:{keywords:["dark","camping","sight","night"],char:'🔦',fitzpatrick_scale:false,category:"objects"},candle:{keywords:["fire","wax"],char:'🕯',fitzpatrick_scale:false,category:"objects"},fire_extinguisher:{keywords:["quench"],char:'🧯',fitzpatrick_scale:false,category:"objects"},wastebasket:{keywords:["bin","trash","rubbish","garbage","toss"],char:'🗑',fitzpatrick_scale:false,category:"objects"},oil_drum:{keywords:["barrell"],char:'🛢',fitzpatrick_scale:false,category:"objects"},money_with_wings:{keywords:["dollar","bills","payment","sale"],char:'💸',fitzpatrick_scale:false,category:"objects"},dollar:{keywords:["money","sales","bill","currency"],char:'💵',fitzpatrick_scale:false,category:"objects"},yen:{keywords:["money","sales","japanese","dollar","currency"],char:'💴',fitzpatrick_scale:false,category:"objects"},euro:{keywords:["money","sales","dollar","currency"],char:'💶',fitzpatrick_scale:false,category:"objects"},pound:{keywords:["british","sterling","money","sales","bills","uk","england","currency"],char:'💷',fitzpatrick_scale:false,category:"objects"},moneybag:{keywords:["dollar","payment","coins","sale"],char:'💰',fitzpatrick_scale:false,category:"objects"},credit_card:{keywords:["money","sales","dollar","bill","payment","shopping"],char:'💳',fitzpatrick_scale:false,category:"objects"},gem:{keywords:["blue","ruby","diamond","jewelry"],char:'💎',fitzpatrick_scale:false,category:"objects"},balance_scale:{keywords:["law","fairness","weight"],char:'⚖',fitzpatrick_scale:false,category:"objects"},toolbox:{keywords:["tools","diy","fix","maintainer","mechanic"],char:'🧰',fitzpatrick_scale:false,category:"objects"},wrench:{keywords:["tools","diy","ikea","fix","maintainer"],char:'🔧',fitzpatrick_scale:false,category:"objects"},hammer:{keywords:["tools","build","create"],char:'🔨',fitzpatrick_scale:false,category:"objects"},hammer_and_pick:{keywords:["tools","build","create"],char:'⚒',fitzpatrick_scale:false,category:"objects"},hammer_and_wrench:{keywords:["tools","build","create"],char:'🛠',fitzpatrick_scale:false,category:"objects"},pick:{keywords:["tools","dig"],char:'⛏',fitzpatrick_scale:false,category:"objects"},nut_and_bolt:{keywords:["handy","tools","fix"],char:'🔩',fitzpatrick_scale:false,category:"objects"},gear:{keywords:["cog"],char:'⚙',fitzpatrick_scale:false,category:"objects"},brick:{keywords:["bricks"],char:'🧱',fitzpatrick_scale:false,category:"objects"},chains:{keywords:["lock","arrest"],char:'⛓',fitzpatrick_scale:false,category:"objects"},magnet:{keywords:["attraction","magnetic"],char:'🧲',fitzpatrick_scale:false,category:"objects"},gun:{keywords:["violence","weapon","pistol","revolver"],char:'🔫',fitzpatrick_scale:false,category:"objects"},bomb:{keywords:["boom","explode","explosion","terrorism"],char:'💣',fitzpatrick_scale:false,category:"objects"},firecracker:{keywords:["dynamite","boom","explode","explosion","explosive"],char:'🧨',fitzpatrick_scale:false,category:"objects"},hocho:{keywords:["knife","blade","cutlery","kitchen","weapon"],char:'🔪',fitzpatrick_scale:false,category:"objects"},dagger:{keywords:["weapon"],char:'🗡',fitzpatrick_scale:false,category:"objects"},crossed_swords:{keywords:["weapon"],char:'⚔',fitzpatrick_scale:false,category:"objects"},shield:{keywords:["protection","security"],char:'🛡',fitzpatrick_scale:false,category:"objects"},smoking:{keywords:["kills","tobacco","cigarette","joint","smoke"],char:'🚬',fitzpatrick_scale:false,category:"objects"},skull_and_crossbones:{keywords:["poison","danger","deadly","scary","death","pirate","evil"],char:'☠',fitzpatrick_scale:false,category:"objects"},coffin:{keywords:["vampire","dead","die","death","rip","graveyard","cemetery","casket","funeral","box"],char:'⚰',fitzpatrick_scale:false,category:"objects"},funeral_urn:{keywords:["dead","die","death","rip","ashes"],char:'⚱',fitzpatrick_scale:false,category:"objects"},amphora:{keywords:["vase","jar"],char:'🏺',fitzpatrick_scale:false,category:"objects"},crystal_ball:{keywords:["disco","party","magic","circus","fortune_teller"],char:'🔮',fitzpatrick_scale:false,category:"objects"},prayer_beads:{keywords:["dhikr","religious"],char:'📿',fitzpatrick_scale:false,category:"objects"},nazar_amulet:{keywords:["bead","charm"],char:'🧿',fitzpatrick_scale:false,category:"objects"},barber:{keywords:["hair","salon","style"],char:'💈',fitzpatrick_scale:false,category:"objects"},alembic:{keywords:["distilling","science","experiment","chemistry"],char:'⚗',fitzpatrick_scale:false,category:"objects"},telescope:{keywords:["stars","space","zoom","science","astronomy"],char:'🔭',fitzpatrick_scale:false,category:"objects"},microscope:{keywords:["laboratory","experiment","zoomin","science","study"],char:'🔬',fitzpatrick_scale:false,category:"objects"},hole:{keywords:["embarrassing"],char:'🕳',fitzpatrick_scale:false,category:"objects"},pill:{keywords:["health","medicine","doctor","pharmacy","drug"],char:'💊',fitzpatrick_scale:false,category:"objects"},syringe:{keywords:["health","hospital","drugs","blood","medicine","needle","doctor","nurse"],char:'💉',fitzpatrick_scale:false,category:"objects"},dna:{keywords:["biologist","genetics","life"],char:'🧬',fitzpatrick_scale:false,category:"objects"},microbe:{keywords:["amoeba","bacteria","germs"],char:'🦠',fitzpatrick_scale:false,category:"objects"},petri_dish:{keywords:["bacteria","biology","culture","lab"],char:'🧫',fitzpatrick_scale:false,category:"objects"},test_tube:{keywords:["chemistry","experiment","lab","science"],char:'🧪',fitzpatrick_scale:false,category:"objects"},thermometer:{keywords:["weather","temperature","hot","cold"],char:'🌡',fitzpatrick_scale:false,category:"objects"},broom:{keywords:["cleaning","sweeping","witch"],char:'🧹',fitzpatrick_scale:false,category:"objects"},basket:{keywords:["laundry"],char:'🧺',fitzpatrick_scale:false,category:"objects"},toilet_paper:{keywords:["roll"],char:'🧻',fitzpatrick_scale:false,category:"objects"},label:{keywords:["sale","tag"],char:'🏷',fitzpatrick_scale:false,category:"objects"},bookmark:{keywords:["favorite","label","save"],char:'🔖',fitzpatrick_scale:false,category:"objects"},toilet:{keywords:["restroom","wc","washroom","bathroom","potty"],char:'🚽',fitzpatrick_scale:false,category:"objects"},shower:{keywords:["clean","water","bathroom"],char:'🚿',fitzpatrick_scale:false,category:"objects"},bathtub:{keywords:["clean","shower","bathroom"],char:'🛁',fitzpatrick_scale:false,category:"objects"},soap:{keywords:["bar","bathing","cleaning","lather"],char:'🧼',fitzpatrick_scale:false,category:"objects"},sponge:{keywords:["absorbing","cleaning","porous"],char:'🧽',fitzpatrick_scale:false,category:"objects"},lotion_bottle:{keywords:["moisturizer","sunscreen"],char:'🧴',fitzpatrick_scale:false,category:"objects"},key:{keywords:["lock","door","password"],char:'🔑',fitzpatrick_scale:false,category:"objects"},old_key:{keywords:["lock","door","password"],char:'🗝',fitzpatrick_scale:false,category:"objects"},couch_and_lamp:{keywords:["read","chill"],char:'🛋',fitzpatrick_scale:false,category:"objects"},sleeping_bed:{keywords:["bed","rest"],char:'🛌',fitzpatrick_scale:true,category:"objects"},bed:{keywords:["sleep","rest"],char:'🛏',fitzpatrick_scale:false,category:"objects"},door:{keywords:["house","entry","exit"],char:'🚪',fitzpatrick_scale:false,category:"objects"},bellhop_bell:{keywords:["service"],char:'🛎',fitzpatrick_scale:false,category:"objects"},teddy_bear:{keywords:["plush","stuffed"],char:'🧸',fitzpatrick_scale:false,category:"objects"},framed_picture:{keywords:["photography"],char:'🖼',fitzpatrick_scale:false,category:"objects"},world_map:{keywords:["location","direction"],char:'🗺',fitzpatrick_scale:false,category:"objects"},parasol_on_ground:{keywords:["weather","summer"],char:'⛱',fitzpatrick_scale:false,category:"objects"},moyai:{keywords:["rock","easter island","moai"],char:'🗿',fitzpatrick_scale:false,category:"objects"},shopping:{keywords:["mall","buy","purchase"],char:'🛍',fitzpatrick_scale:false,category:"objects"},shopping_cart:{keywords:["trolley"],char:'🛒',fitzpatrick_scale:false,category:"objects"},balloon:{keywords:["party","celebration","birthday","circus"],char:'🎈',fitzpatrick_scale:false,category:"objects"},flags:{keywords:["fish","japanese","koinobori","carp","banner"],char:'🎏',fitzpatrick_scale:false,category:"objects"},ribbon:{keywords:["decoration","pink","girl","bowtie"],char:'🎀',fitzpatrick_scale:false,category:"objects"},gift:{keywords:["present","birthday","christmas","xmas"],char:'🎁',fitzpatrick_scale:false,category:"objects"},confetti_ball:{keywords:["festival","party","birthday","circus"],char:'🎊',fitzpatrick_scale:false,category:"objects"},tada:{keywords:["party","congratulations","birthday","magic","circus","celebration"],char:'🎉',fitzpatrick_scale:false,category:"objects"},dolls:{keywords:["japanese","toy","kimono"],char:'🎎',fitzpatrick_scale:false,category:"objects"},wind_chime:{keywords:["nature","ding","spring","bell"],char:'🎐',fitzpatrick_scale:false,category:"objects"},crossed_flags:{keywords:["japanese","nation","country","border"],char:'🎌',fitzpatrick_scale:false,category:"objects"},izakaya_lantern:{keywords:["light","paper","halloween","spooky"],char:'🏮',fitzpatrick_scale:false,category:"objects"},red_envelope:{keywords:["gift"],char:'🧧',fitzpatrick_scale:false,category:"objects"},email:{keywords:["letter","postal","inbox","communication"],char:'✉️',fitzpatrick_scale:false,category:"objects"},envelope_with_arrow:{keywords:["email","communication"],char:'📩',fitzpatrick_scale:false,category:"objects"},incoming_envelope:{keywords:["email","inbox"],char:'📨',fitzpatrick_scale:false,category:"objects"},"e-mail":{keywords:["communication","inbox"],char:'📧',fitzpatrick_scale:false,category:"objects"},love_letter:{keywords:["email","like","affection","envelope","valentines"],char:'💌',fitzpatrick_scale:false,category:"objects"},postbox:{keywords:["email","letter","envelope"],char:'📮',fitzpatrick_scale:false,category:"objects"},mailbox_closed:{keywords:["email","communication","inbox"],char:'📪',fitzpatrick_scale:false,category:"objects"},mailbox:{keywords:["email","inbox","communication"],char:'📫',fitzpatrick_scale:false,category:"objects"},mailbox_with_mail:{keywords:["email","inbox","communication"],char:'📬',fitzpatrick_scale:false,category:"objects"},mailbox_with_no_mail:{keywords:["email","inbox"],char:'📭',fitzpatrick_scale:false,category:"objects"},package:{keywords:["mail","gift","cardboard","box","moving"],char:'📦',fitzpatrick_scale:false,category:"objects"},postal_horn:{keywords:["instrument","music"],char:'📯',fitzpatrick_scale:false,category:"objects"},inbox_tray:{keywords:["email","documents"],char:'📥',fitzpatrick_scale:false,category:"objects"},outbox_tray:{keywords:["inbox","email"],char:'📤',fitzpatrick_scale:false,category:"objects"},scroll:{keywords:["documents","ancient","history","paper"],char:'📜',fitzpatrick_scale:false,category:"objects"},page_with_curl:{keywords:["documents","office","paper"],char:'📃',fitzpatrick_scale:false,category:"objects"},bookmark_tabs:{keywords:["favorite","save","order","tidy"],char:'📑',fitzpatrick_scale:false,category:"objects"},receipt:{keywords:["accounting","expenses"],char:'🧾',fitzpatrick_scale:false,category:"objects"},bar_chart:{keywords:["graph","presentation","stats"],char:'📊',fitzpatrick_scale:false,category:"objects"},chart_with_upwards_trend:{keywords:["graph","presentation","stats","recovery","business","economics","money","sales","good","success"],char:'📈',fitzpatrick_scale:false,category:"objects"},chart_with_downwards_trend:{keywords:["graph","presentation","stats","recession","business","economics","money","sales","bad","failure"],char:'📉',fitzpatrick_scale:false,category:"objects"},page_facing_up:{keywords:["documents","office","paper","information"],char:'📄',fitzpatrick_scale:false,category:"objects"},date:{keywords:["calendar","schedule"],char:'📅',fitzpatrick_scale:false,category:"objects"},calendar:{keywords:["schedule","date","planning"],char:'📆',fitzpatrick_scale:false,category:"objects"},spiral_calendar:{keywords:["date","schedule","planning"],char:'🗓',fitzpatrick_scale:false,category:"objects"},card_index:{keywords:["business","stationery"],char:'📇',fitzpatrick_scale:false,category:"objects"},card_file_box:{keywords:["business","stationery"],char:'🗃',fitzpatrick_scale:false,category:"objects"},ballot_box:{keywords:["election","vote"],char:'🗳',fitzpatrick_scale:false,category:"objects"},file_cabinet:{keywords:["filing","organizing"],char:'🗄',fitzpatrick_scale:false,category:"objects"},clipboard:{keywords:["stationery","documents"],char:'📋',fitzpatrick_scale:false,category:"objects"},spiral_notepad:{keywords:["memo","stationery"],char:'🗒',fitzpatrick_scale:false,category:"objects"},file_folder:{keywords:["documents","business","office"],char:'📁',fitzpatrick_scale:false,category:"objects"},open_file_folder:{keywords:["documents","load"],char:'📂',fitzpatrick_scale:false,category:"objects"},card_index_dividers:{keywords:["organizing","business","stationery"],char:'🗂',fitzpatrick_scale:false,category:"objects"},newspaper_roll:{keywords:["press","headline"],char:'🗞',fitzpatrick_scale:false,category:"objects"},newspaper:{keywords:["press","headline"],char:'📰',fitzpatrick_scale:false,category:"objects"},notebook:{keywords:["stationery","record","notes","paper","study"],char:'📓',fitzpatrick_scale:false,category:"objects"},closed_book:{keywords:["read","library","knowledge","textbook","learn"],char:'📕',fitzpatrick_scale:false,category:"objects"},green_book:{keywords:["read","library","knowledge","study"],char:'📗',fitzpatrick_scale:false,category:"objects"},blue_book:{keywords:["read","library","knowledge","learn","study"],char:'📘',fitzpatrick_scale:false,category:"objects"},orange_book:{keywords:["read","library","knowledge","textbook","study"],char:'📙',fitzpatrick_scale:false,category:"objects"},notebook_with_decorative_cover:{keywords:["classroom","notes","record","paper","study"],char:'📔',fitzpatrick_scale:false,category:"objects"},ledger:{keywords:["notes","paper"],char:'📒',fitzpatrick_scale:false,category:"objects"},books:{keywords:["literature","library","study"],char:'📚',fitzpatrick_scale:false,category:"objects"},open_book:{keywords:["book","read","library","knowledge","literature","learn","study"],char:'📖',fitzpatrick_scale:false,category:"objects"},safety_pin:{keywords:["diaper"],char:'🧷',fitzpatrick_scale:false,category:"objects"},link:{keywords:["rings","url"],char:'🔗',fitzpatrick_scale:false,category:"objects"},paperclip:{keywords:["documents","stationery"],char:'📎',fitzpatrick_scale:false,category:"objects"},paperclips:{keywords:["documents","stationery"],char:'🖇',fitzpatrick_scale:false,category:"objects"},scissors:{keywords:["stationery","cut"],char:'✂️',fitzpatrick_scale:false,category:"objects"},triangular_ruler:{keywords:["stationery","math","architect","sketch"],char:'📐',fitzpatrick_scale:false,category:"objects"},straight_ruler:{keywords:["stationery","calculate","length","math","school","drawing","architect","sketch"],char:'📏',fitzpatrick_scale:false,category:"objects"},abacus:{keywords:["calculation"],char:'🧮',fitzpatrick_scale:false,category:"objects"},pushpin:{keywords:["stationery","mark","here"],char:'📌',fitzpatrick_scale:false,category:"objects"},round_pushpin:{keywords:["stationery","location","map","here"],char:'📍',fitzpatrick_scale:false,category:"objects"},triangular_flag_on_post:{keywords:["mark","milestone","place"],char:'🚩',fitzpatrick_scale:false,category:"objects"},white_flag:{keywords:["losing","loser","lost","surrender","give up","fail"],char:'🏳',fitzpatrick_scale:false,category:"objects"},black_flag:{keywords:["pirate"],char:'🏴',fitzpatrick_scale:false,category:"objects"},rainbow_flag:{keywords:["flag","rainbow","pride","gay","lgbt","glbt","queer","homosexual","lesbian","bisexual","transgender"],char:'🏳️‍🌈',fitzpatrick_scale:false,category:"objects"},closed_lock_with_key:{keywords:["security","privacy"],char:'🔐',fitzpatrick_scale:false,category:"objects"},lock:{keywords:["security","password","padlock"],char:'🔒',fitzpatrick_scale:false,category:"objects"},unlock:{keywords:["privacy","security"],char:'🔓',fitzpatrick_scale:false,category:"objects"},lock_with_ink_pen:{keywords:["security","secret"],char:'🔏',fitzpatrick_scale:false,category:"objects"},pen:{keywords:["stationery","writing","write"],char:'🖊',fitzpatrick_scale:false,category:"objects"},fountain_pen:{keywords:["stationery","writing","write"],char:'🖋',fitzpatrick_scale:false,category:"objects"},black_nib:{keywords:["pen","stationery","writing","write"],char:'✒️',fitzpatrick_scale:false,category:"objects"},memo:{keywords:["write","documents","stationery","pencil","paper","writing","legal","exam","quiz","test","study","compose"],char:'📝',fitzpatrick_scale:false,category:"objects"},pencil2:{keywords:["stationery","write","paper","writing","school","study"],char:'✏️',fitzpatrick_scale:false,category:"objects"},crayon:{keywords:["drawing","creativity"],char:'🖍',fitzpatrick_scale:false,category:"objects"},paintbrush:{keywords:["drawing","creativity","art"],char:'🖌',fitzpatrick_scale:false,category:"objects"},mag:{keywords:["search","zoom","find","detective"],char:'🔍',fitzpatrick_scale:false,category:"objects"},mag_right:{keywords:["search","zoom","find","detective"],char:'🔎',fitzpatrick_scale:false,category:"objects"},heart:{keywords:["love","like","valentines"],char:'❤️',fitzpatrick_scale:false,category:"symbols"},orange_heart:{keywords:["love","like","affection","valentines"],char:'🧡',fitzpatrick_scale:false,category:"symbols"},yellow_heart:{keywords:["love","like","affection","valentines"],char:'💛',fitzpatrick_scale:false,category:"symbols"},green_heart:{keywords:["love","like","affection","valentines"],char:'💚',fitzpatrick_scale:false,category:"symbols"},blue_heart:{keywords:["love","like","affection","valentines"],char:'💙',fitzpatrick_scale:false,category:"symbols"},purple_heart:{keywords:["love","like","affection","valentines"],char:'💜',fitzpatrick_scale:false,category:"symbols"},black_heart:{keywords:["evil"],char:'🖤',fitzpatrick_scale:false,category:"symbols"},broken_heart:{keywords:["sad","sorry","break","heart","heartbreak"],char:'💔',fitzpatrick_scale:false,category:"symbols"},heavy_heart_exclamation:{keywords:["decoration","love"],char:'❣',fitzpatrick_scale:false,category:"symbols"},two_hearts:{keywords:["love","like","affection","valentines","heart"],char:'💕',fitzpatrick_scale:false,category:"symbols"},revolving_hearts:{keywords:["love","like","affection","valentines"],char:'💞',fitzpatrick_scale:false,category:"symbols"},heartbeat:{keywords:["love","like","affection","valentines","pink","heart"],char:'💓',fitzpatrick_scale:false,category:"symbols"},heartpulse:{keywords:["like","love","affection","valentines","pink"],char:'💗',fitzpatrick_scale:false,category:"symbols"},sparkling_heart:{keywords:["love","like","affection","valentines"],char:'💖',fitzpatrick_scale:false,category:"symbols"},cupid:{keywords:["love","like","heart","affection","valentines"],char:'💘',fitzpatrick_scale:false,category:"symbols"},gift_heart:{keywords:["love","valentines"],char:'💝',fitzpatrick_scale:false,category:"symbols"},heart_decoration:{keywords:["purple-square","love","like"],char:'💟',fitzpatrick_scale:false,category:"symbols"},peace_symbol:{keywords:["hippie"],char:'☮',fitzpatrick_scale:false,category:"symbols"},latin_cross:{keywords:["christianity"],char:'✝',fitzpatrick_scale:false,category:"symbols"},star_and_crescent:{keywords:["islam"],char:'☪',fitzpatrick_scale:false,category:"symbols"},om:{keywords:["hinduism","buddhism","sikhism","jainism"],char:'🕉',fitzpatrick_scale:false,category:"symbols"},wheel_of_dharma:{keywords:["hinduism","buddhism","sikhism","jainism"],char:'☸',fitzpatrick_scale:false,category:"symbols"},star_of_david:{keywords:["judaism"],char:'✡',fitzpatrick_scale:false,category:"symbols"},six_pointed_star:{keywords:["purple-square","religion","jewish","hexagram"],char:'🔯',fitzpatrick_scale:false,category:"symbols"},menorah:{keywords:["hanukkah","candles","jewish"],char:'🕎',fitzpatrick_scale:false,category:"symbols"},yin_yang:{keywords:["balance"],char:'☯',fitzpatrick_scale:false,category:"symbols"},orthodox_cross:{keywords:["suppedaneum","religion"],char:'☦',fitzpatrick_scale:false,category:"symbols"},place_of_worship:{keywords:["religion","church","temple","prayer"],char:'🛐',fitzpatrick_scale:false,category:"symbols"},ophiuchus:{keywords:["sign","purple-square","constellation","astrology"],char:'⛎',fitzpatrick_scale:false,category:"symbols"},aries:{keywords:["sign","purple-square","zodiac","astrology"],char:'♈',fitzpatrick_scale:false,category:"symbols"},taurus:{keywords:["purple-square","sign","zodiac","astrology"],char:'♉',fitzpatrick_scale:false,category:"symbols"},gemini:{keywords:["sign","zodiac","purple-square","astrology"],char:'♊',fitzpatrick_scale:false,category:"symbols"},cancer:{keywords:["sign","zodiac","purple-square","astrology"],char:'♋',fitzpatrick_scale:false,category:"symbols"},leo:{keywords:["sign","purple-square","zodiac","astrology"],char:'♌',fitzpatrick_scale:false,category:"symbols"},virgo:{keywords:["sign","zodiac","purple-square","astrology"],char:'♍',fitzpatrick_scale:false,category:"symbols"},libra:{keywords:["sign","purple-square","zodiac","astrology"],char:'♎',fitzpatrick_scale:false,category:"symbols"},scorpius:{keywords:["sign","zodiac","purple-square","astrology","scorpio"],char:'♏',fitzpatrick_scale:false,category:"symbols"},sagittarius:{keywords:["sign","zodiac","purple-square","astrology"],char:'♐',fitzpatrick_scale:false,category:"symbols"},capricorn:{keywords:["sign","zodiac","purple-square","astrology"],char:'♑',fitzpatrick_scale:false,category:"symbols"},aquarius:{keywords:["sign","purple-square","zodiac","astrology"],char:'♒',fitzpatrick_scale:false,category:"symbols"},pisces:{keywords:["purple-square","sign","zodiac","astrology"],char:'♓',fitzpatrick_scale:false,category:"symbols"},id:{keywords:["purple-square","words"],char:'🆔',fitzpatrick_scale:false,category:"symbols"},atom_symbol:{keywords:["science","physics","chemistry"],char:'⚛',fitzpatrick_scale:false,category:"symbols"},u7a7a:{keywords:["kanji","japanese","chinese","empty","sky","blue-square"],char:'🈳',fitzpatrick_scale:false,category:"symbols"},u5272:{keywords:["cut","divide","chinese","kanji","pink-square"],char:'🈹',fitzpatrick_scale:false,category:"symbols"},radioactive:{keywords:["nuclear","danger"],char:'☢',fitzpatrick_scale:false,category:"symbols"},biohazard:{keywords:["danger"],char:'☣',fitzpatrick_scale:false,category:"symbols"},mobile_phone_off:{keywords:["mute","orange-square","silence","quiet"],char:'📴',fitzpatrick_scale:false,category:"symbols"},vibration_mode:{keywords:["orange-square","phone"],char:'📳',fitzpatrick_scale:false,category:"symbols"},u6709:{keywords:["orange-square","chinese","have","kanji"],char:'🈶',fitzpatrick_scale:false,category:"symbols"},u7121:{keywords:["nothing","chinese","kanji","japanese","orange-square"],char:'🈚',fitzpatrick_scale:false,category:"symbols"},u7533:{keywords:["chinese","japanese","kanji","orange-square"],char:'🈸',fitzpatrick_scale:false,category:"symbols"},u55b6:{keywords:["japanese","opening hours","orange-square"],char:'🈺',fitzpatrick_scale:false,category:"symbols"},u6708:{keywords:["chinese","month","moon","japanese","orange-square","kanji"],char:'🈷️',fitzpatrick_scale:false,category:"symbols"},eight_pointed_black_star:{keywords:["orange-square","shape","polygon"],char:'✴️',fitzpatrick_scale:false,category:"symbols"},vs:{keywords:["words","orange-square"],char:'🆚',fitzpatrick_scale:false,category:"symbols"},accept:{keywords:["ok","good","chinese","kanji","agree","yes","orange-circle"],char:'🉑',fitzpatrick_scale:false,category:"symbols"},white_flower:{keywords:["japanese","spring"],char:'💮',fitzpatrick_scale:false,category:"symbols"},ideograph_advantage:{keywords:["chinese","kanji","obtain","get","circle"],char:'🉐',fitzpatrick_scale:false,category:"symbols"},secret:{keywords:["privacy","chinese","sshh","kanji","red-circle"],char:'㊙️',fitzpatrick_scale:false,category:"symbols"},congratulations:{keywords:["chinese","kanji","japanese","red-circle"],char:'㊗️',fitzpatrick_scale:false,category:"symbols"},u5408:{keywords:["japanese","chinese","join","kanji","red-square"],char:'🈴',fitzpatrick_scale:false,category:"symbols"},u6e80:{keywords:["full","chinese","japanese","red-square","kanji"],char:'🈵',fitzpatrick_scale:false,category:"symbols"},u7981:{keywords:["kanji","japanese","chinese","forbidden","limit","restricted","red-square"],char:'🈲',fitzpatrick_scale:false,category:"symbols"},a:{keywords:["red-square","alphabet","letter"],char:'🅰️',fitzpatrick_scale:false,category:"symbols"},b:{keywords:["red-square","alphabet","letter"],char:'🅱️',fitzpatrick_scale:false,category:"symbols"},ab:{keywords:["red-square","alphabet"],char:'🆎',fitzpatrick_scale:false,category:"symbols"},cl:{keywords:["alphabet","words","red-square"],char:'🆑',fitzpatrick_scale:false,category:"symbols"},o2:{keywords:["alphabet","red-square","letter"],char:'🅾️',fitzpatrick_scale:false,category:"symbols"},sos:{keywords:["help","red-square","words","emergency","911"],char:'🆘',fitzpatrick_scale:false,category:"symbols"},no_entry:{keywords:["limit","security","privacy","bad","denied","stop","circle"],char:'⛔',fitzpatrick_scale:false,category:"symbols"},name_badge:{keywords:["fire","forbid"],char:'📛',fitzpatrick_scale:false,category:"symbols"},no_entry_sign:{keywords:["forbid","stop","limit","denied","disallow","circle"],char:'🚫',fitzpatrick_scale:false,category:"symbols"},x:{keywords:["no","delete","remove","cancel","red"],char:'❌',fitzpatrick_scale:false,category:"symbols"},o:{keywords:["circle","round"],char:'⭕',fitzpatrick_scale:false,category:"symbols"},stop_sign:{keywords:["stop"],char:'🛑',fitzpatrick_scale:false,category:"symbols"},anger:{keywords:["angry","mad"],char:'💢',fitzpatrick_scale:false,category:"symbols"},hotsprings:{keywords:["bath","warm","relax"],char:'♨️',fitzpatrick_scale:false,category:"symbols"},no_pedestrians:{keywords:["rules","crossing","walking","circle"],char:'🚷',fitzpatrick_scale:false,category:"symbols"},do_not_litter:{keywords:["trash","bin","garbage","circle"],char:'🚯',fitzpatrick_scale:false,category:"symbols"},no_bicycles:{keywords:["cyclist","prohibited","circle"],char:'🚳',fitzpatrick_scale:false,category:"symbols"},"non-potable_water":{keywords:["drink","faucet","tap","circle"],char:'🚱',fitzpatrick_scale:false,category:"symbols"},underage:{keywords:["18","drink","pub","night","minor","circle"],char:'🔞',fitzpatrick_scale:false,category:"symbols"},no_mobile_phones:{keywords:["iphone","mute","circle"],char:'📵',fitzpatrick_scale:false,category:"symbols"},exclamation:{keywords:["heavy_exclamation_mark","danger","surprise","punctuation","wow","warning"],char:'❗',fitzpatrick_scale:false,category:"symbols"},grey_exclamation:{keywords:["surprise","punctuation","gray","wow","warning"],char:'❕',fitzpatrick_scale:false,category:"symbols"},question:{keywords:["doubt","confused"],char:'❓',fitzpatrick_scale:false,category:"symbols"},grey_question:{keywords:["doubts","gray","huh","confused"],char:'❔',fitzpatrick_scale:false,category:"symbols"},bangbang:{keywords:["exclamation","surprise"],char:'‼️',fitzpatrick_scale:false,category:"symbols"},interrobang:{keywords:["wat","punctuation","surprise"],char:'⁉️',fitzpatrick_scale:false,category:"symbols"},low_brightness:{keywords:["sun","afternoon","warm","summer"],char:'🔅',fitzpatrick_scale:false,category:"symbols"},high_brightness:{keywords:["sun","light"],char:'🔆',fitzpatrick_scale:false,category:"symbols"},trident:{keywords:["weapon","spear"],char:'🔱',fitzpatrick_scale:false,category:"symbols"},fleur_de_lis:{keywords:["decorative","scout"],char:'⚜',fitzpatrick_scale:false,category:"symbols"},part_alternation_mark:{keywords:["graph","presentation","stats","business","economics","bad"],char:'〽️',fitzpatrick_scale:false,category:"symbols"},warning:{keywords:["exclamation","wip","alert","error","problem","issue"],char:'⚠️',fitzpatrick_scale:false,category:"symbols"},children_crossing:{keywords:["school","warning","danger","sign","driving","yellow-diamond"],char:'🚸',fitzpatrick_scale:false,category:"symbols"},beginner:{keywords:["badge","shield"],char:'🔰',fitzpatrick_scale:false,category:"symbols"},recycle:{keywords:["arrow","environment","garbage","trash"],char:'♻️',fitzpatrick_scale:false,category:"symbols"},u6307:{keywords:["chinese","point","green-square","kanji"],char:'🈯',fitzpatrick_scale:false,category:"symbols"},chart:{keywords:["green-square","graph","presentation","stats"],char:'💹',fitzpatrick_scale:false,category:"symbols"},sparkle:{keywords:["stars","green-square","awesome","good","fireworks"],char:'❇️',fitzpatrick_scale:false,category:"symbols"},eight_spoked_asterisk:{keywords:["star","sparkle","green-square"],char:'✳️',fitzpatrick_scale:false,category:"symbols"},negative_squared_cross_mark:{keywords:["x","green-square","no","deny"],char:'❎',fitzpatrick_scale:false,category:"symbols"},white_check_mark:{keywords:["green-square","ok","agree","vote","election","answer","tick"],char:'✅',fitzpatrick_scale:false,category:"symbols"},diamond_shape_with_a_dot_inside:{keywords:["jewel","blue","gem","crystal","fancy"],char:'💠',fitzpatrick_scale:false,category:"symbols"},cyclone:{keywords:["weather","swirl","blue","cloud","vortex","spiral","whirlpool","spin","tornado","hurricane","typhoon"],char:'🌀',fitzpatrick_scale:false,category:"symbols"},loop:{keywords:["tape","cassette"],char:'➿',fitzpatrick_scale:false,category:"symbols"},globe_with_meridians:{keywords:["earth","international","world","internet","interweb","i18n"],char:'🌐',fitzpatrick_scale:false,category:"symbols"},m:{keywords:["alphabet","blue-circle","letter"],char:'Ⓜ️',fitzpatrick_scale:false,category:"symbols"},atm:{keywords:["money","sales","cash","blue-square","payment","bank"],char:'🏧',fitzpatrick_scale:false,category:"symbols"},sa:{keywords:["japanese","blue-square","katakana"],char:'🈂️',fitzpatrick_scale:false,category:"symbols"},passport_control:{keywords:["custom","blue-square"],char:'🛂',fitzpatrick_scale:false,category:"symbols"},customs:{keywords:["passport","border","blue-square"],char:'🛃',fitzpatrick_scale:false,category:"symbols"},baggage_claim:{keywords:["blue-square","airport","transport"],char:'🛄',fitzpatrick_scale:false,category:"symbols"},left_luggage:{keywords:["blue-square","travel"],char:'🛅',fitzpatrick_scale:false,category:"symbols"},wheelchair:{keywords:["blue-square","disabled","a11y","accessibility"],char:'♿',fitzpatrick_scale:false,category:"symbols"},no_smoking:{keywords:["cigarette","blue-square","smell","smoke"],char:'🚭',fitzpatrick_scale:false,category:"symbols"},wc:{keywords:["toilet","restroom","blue-square"],char:'🚾',fitzpatrick_scale:false,category:"symbols"},parking:{keywords:["cars","blue-square","alphabet","letter"],char:'🅿️',fitzpatrick_scale:false,category:"symbols"},potable_water:{keywords:["blue-square","liquid","restroom","cleaning","faucet"],char:'🚰',fitzpatrick_scale:false,category:"symbols"},mens:{keywords:["toilet","restroom","wc","blue-square","gender","male"],char:'🚹',fitzpatrick_scale:false,category:"symbols"},womens:{keywords:["purple-square","woman","female","toilet","loo","restroom","gender"],char:'🚺',fitzpatrick_scale:false,category:"symbols"},baby_symbol:{keywords:["orange-square","child"],char:'🚼',fitzpatrick_scale:false,category:"symbols"},restroom:{keywords:["blue-square","toilet","refresh","wc","gender"],char:'🚻',fitzpatrick_scale:false,category:"symbols"},put_litter_in_its_place:{keywords:["blue-square","sign","human","info"],char:'🚮',fitzpatrick_scale:false,category:"symbols"},cinema:{keywords:["blue-square","record","film","movie","curtain","stage","theater"],char:'🎦',fitzpatrick_scale:false,category:"symbols"},signal_strength:{keywords:["blue-square","reception","phone","internet","connection","wifi","bluetooth","bars"],char:'📶',fitzpatrick_scale:false,category:"symbols"},koko:{keywords:["blue-square","here","katakana","japanese","destination"],char:'🈁',fitzpatrick_scale:false,category:"symbols"},ng:{keywords:["blue-square","words","shape","icon"],char:'🆖',fitzpatrick_scale:false,category:"symbols"},ok:{keywords:["good","agree","yes","blue-square"],char:'🆗',fitzpatrick_scale:false,category:"symbols"},up:{keywords:["blue-square","above","high"],char:'🆙',fitzpatrick_scale:false,category:"symbols"},cool:{keywords:["words","blue-square"],char:'🆒',fitzpatrick_scale:false,category:"symbols"},new:{keywords:["blue-square","words","start"],char:'🆕',fitzpatrick_scale:false,category:"symbols"},free:{keywords:["blue-square","words"],char:'🆓',fitzpatrick_scale:false,category:"symbols"},zero:{keywords:["0","numbers","blue-square","null"],char:'0️⃣',fitzpatrick_scale:false,category:"symbols"},one:{keywords:["blue-square","numbers","1"],char:'1️⃣',fitzpatrick_scale:false,category:"symbols"},two:{keywords:["numbers","2","prime","blue-square"],char:'2️⃣',fitzpatrick_scale:false,category:"symbols"},three:{keywords:["3","numbers","prime","blue-square"],char:'3️⃣',fitzpatrick_scale:false,category:"symbols"},four:{keywords:["4","numbers","blue-square"],char:'4️⃣',fitzpatrick_scale:false,category:"symbols"},five:{keywords:["5","numbers","blue-square","prime"],char:'5️⃣',fitzpatrick_scale:false,category:"symbols"},six:{keywords:["6","numbers","blue-square"],char:'6️⃣',fitzpatrick_scale:false,category:"symbols"},seven:{keywords:["7","numbers","blue-square","prime"],char:'7️⃣',fitzpatrick_scale:false,category:"symbols"},eight:{keywords:["8","blue-square","numbers"],char:'8️⃣',fitzpatrick_scale:false,category:"symbols"},nine:{keywords:["blue-square","numbers","9"],char:'9️⃣',fitzpatrick_scale:false,category:"symbols"},keycap_ten:{keywords:["numbers","10","blue-square"],char:'🔟',fitzpatrick_scale:false,category:"symbols"},asterisk:{keywords:["star","keycap"],char:'*⃣',fitzpatrick_scale:false,category:"symbols"},eject_button:{keywords:["blue-square"],char:'⏏️',fitzpatrick_scale:false,category:"symbols"},arrow_forward:{keywords:["blue-square","right","direction","play"],char:'▶️',fitzpatrick_scale:false,category:"symbols"},pause_button:{keywords:["pause","blue-square"],char:'⏸',fitzpatrick_scale:false,category:"symbols"},next_track_button:{keywords:["forward","next","blue-square"],char:'⏭',fitzpatrick_scale:false,category:"symbols"},stop_button:{keywords:["blue-square"],char:'⏹',fitzpatrick_scale:false,category:"symbols"},record_button:{keywords:["blue-square"],char:'⏺',fitzpatrick_scale:false,category:"symbols"},play_or_pause_button:{keywords:["blue-square","play","pause"],char:'⏯',fitzpatrick_scale:false,category:"symbols"},previous_track_button:{keywords:["backward"],char:'⏮',fitzpatrick_scale:false,category:"symbols"},fast_forward:{keywords:["blue-square","play","speed","continue"],char:'⏩',fitzpatrick_scale:false,category:"symbols"},rewind:{keywords:["play","blue-square"],char:'⏪',fitzpatrick_scale:false,category:"symbols"},twisted_rightwards_arrows:{keywords:["blue-square","shuffle","music","random"],char:'🔀',fitzpatrick_scale:false,category:"symbols"},repeat:{keywords:["loop","record"],char:'🔁',fitzpatrick_scale:false,category:"symbols"},repeat_one:{keywords:["blue-square","loop"],char:'🔂',fitzpatrick_scale:false,category:"symbols"},arrow_backward:{keywords:["blue-square","left","direction"],char:'◀️',fitzpatrick_scale:false,category:"symbols"},arrow_up_small:{keywords:["blue-square","triangle","direction","point","forward","top"],char:'🔼',fitzpatrick_scale:false,category:"symbols"},arrow_down_small:{keywords:["blue-square","direction","bottom"],char:'🔽',fitzpatrick_scale:false,category:"symbols"},arrow_double_up:{keywords:["blue-square","direction","top"],char:'⏫',fitzpatrick_scale:false,category:"symbols"},arrow_double_down:{keywords:["blue-square","direction","bottom"],char:'⏬',fitzpatrick_scale:false,category:"symbols"},arrow_right:{keywords:["blue-square","next"],char:'➡️',fitzpatrick_scale:false,category:"symbols"},arrow_left:{keywords:["blue-square","previous","back"],char:'⬅️',fitzpatrick_scale:false,category:"symbols"},arrow_up:{keywords:["blue-square","continue","top","direction"],char:'⬆️',fitzpatrick_scale:false,category:"symbols"},arrow_down:{keywords:["blue-square","direction","bottom"],char:'⬇️',fitzpatrick_scale:false,category:"symbols"},arrow_upper_right:{keywords:["blue-square","point","direction","diagonal","northeast"],char:'↗️',fitzpatrick_scale:false,category:"symbols"},arrow_lower_right:{keywords:["blue-square","direction","diagonal","southeast"],char:'↘️',fitzpatrick_scale:false,category:"symbols"},arrow_lower_left:{keywords:["blue-square","direction","diagonal","southwest"],char:'↙️',fitzpatrick_scale:false,category:"symbols"},arrow_upper_left:{keywords:["blue-square","point","direction","diagonal","northwest"],char:'↖️',fitzpatrick_scale:false,category:"symbols"},arrow_up_down:{keywords:["blue-square","direction","way","vertical"],char:'↕️',fitzpatrick_scale:false,category:"symbols"},left_right_arrow:{keywords:["shape","direction","horizontal","sideways"],char:'↔️',fitzpatrick_scale:false,category:"symbols"},arrows_counterclockwise:{keywords:["blue-square","sync","cycle"],char:'🔄',fitzpatrick_scale:false,category:"symbols"},arrow_right_hook:{keywords:["blue-square","return","rotate","direction"],char:'↪️',fitzpatrick_scale:false,category:"symbols"},leftwards_arrow_with_hook:{keywords:["back","return","blue-square","undo","enter"],char:'↩️',fitzpatrick_scale:false,category:"symbols"},arrow_heading_up:{keywords:["blue-square","direction","top"],char:'⤴️',fitzpatrick_scale:false,category:"symbols"},arrow_heading_down:{keywords:["blue-square","direction","bottom"],char:'⤵️',fitzpatrick_scale:false,category:"symbols"},hash:{keywords:["symbol","blue-square","twitter"],char:'#️⃣',fitzpatrick_scale:false,category:"symbols"},information_source:{keywords:["blue-square","alphabet","letter"],char:'ℹ️',fitzpatrick_scale:false,category:"symbols"},abc:{keywords:["blue-square","alphabet"],char:'🔤',fitzpatrick_scale:false,category:"symbols"},abcd:{keywords:["blue-square","alphabet"],char:'🔡',fitzpatrick_scale:false,category:"symbols"},capital_abcd:{keywords:["alphabet","words","blue-square"],char:'🔠',fitzpatrick_scale:false,category:"symbols"},symbols:{keywords:["blue-square","music","note","ampersand","percent","glyphs","characters"],char:'🔣',fitzpatrick_scale:false,category:"symbols"},musical_note:{keywords:["score","tone","sound"],char:'🎵',fitzpatrick_scale:false,category:"symbols"},notes:{keywords:["music","score"],char:'🎶',fitzpatrick_scale:false,category:"symbols"},wavy_dash:{keywords:["draw","line","moustache","mustache","squiggle","scribble"],char:'〰️',fitzpatrick_scale:false,category:"symbols"},curly_loop:{keywords:["scribble","draw","shape","squiggle"],char:'➰',fitzpatrick_scale:false,category:"symbols"},heavy_check_mark:{keywords:["ok","nike","answer","yes","tick"],char:'✔️',fitzpatrick_scale:false,category:"symbols"},arrows_clockwise:{keywords:["sync","cycle","round","repeat"],char:'🔃',fitzpatrick_scale:false,category:"symbols"},heavy_plus_sign:{keywords:["math","calculation","addition","more","increase"],char:'➕',fitzpatrick_scale:false,category:"symbols"},heavy_minus_sign:{keywords:["math","calculation","subtract","less"],char:'➖',fitzpatrick_scale:false,category:"symbols"},heavy_division_sign:{keywords:["divide","math","calculation"],char:'➗',fitzpatrick_scale:false,category:"symbols"},heavy_multiplication_x:{keywords:["math","calculation"],char:'✖️',fitzpatrick_scale:false,category:"symbols"},infinity:{keywords:["forever"],char:'♾',fitzpatrick_scale:false,category:"symbols"},heavy_dollar_sign:{keywords:["money","sales","payment","currency","buck"],char:'💲',fitzpatrick_scale:false,category:"symbols"},currency_exchange:{keywords:["money","sales","dollar","travel"],char:'💱',fitzpatrick_scale:false,category:"symbols"},copyright:{keywords:["ip","license","circle","law","legal"],char:'©️',fitzpatrick_scale:false,category:"symbols"},registered:{keywords:["alphabet","circle"],char:'®️',fitzpatrick_scale:false,category:"symbols"},tm:{keywords:["trademark","brand","law","legal"],char:'™️',fitzpatrick_scale:false,category:"symbols"},end:{keywords:["words","arrow"],char:'🔚',fitzpatrick_scale:false,category:"symbols"},back:{keywords:["arrow","words","return"],char:'🔙',fitzpatrick_scale:false,category:"symbols"},on:{keywords:["arrow","words"],char:'🔛',fitzpatrick_scale:false,category:"symbols"},top:{keywords:["words","blue-square"],char:'🔝',fitzpatrick_scale:false,category:"symbols"},soon:{keywords:["arrow","words"],char:'🔜',fitzpatrick_scale:false,category:"symbols"},ballot_box_with_check:{keywords:["ok","agree","confirm","black-square","vote","election","yes","tick"],char:'☑️',fitzpatrick_scale:false,category:"symbols"},radio_button:{keywords:["input","old","music","circle"],char:'🔘',fitzpatrick_scale:false,category:"symbols"},white_circle:{keywords:["shape","round"],char:'⚪',fitzpatrick_scale:false,category:"symbols"},black_circle:{keywords:["shape","button","round"],char:'⚫',fitzpatrick_scale:false,category:"symbols"},red_circle:{keywords:["shape","error","danger"],char:'🔴',fitzpatrick_scale:false,category:"symbols"},large_blue_circle:{keywords:["shape","icon","button"],char:'🔵',fitzpatrick_scale:false,category:"symbols"},small_orange_diamond:{keywords:["shape","jewel","gem"],char:'🔸',fitzpatrick_scale:false,category:"symbols"},small_blue_diamond:{keywords:["shape","jewel","gem"],char:'🔹',fitzpatrick_scale:false,category:"symbols"},large_orange_diamond:{keywords:["shape","jewel","gem"],char:'🔶',fitzpatrick_scale:false,category:"symbols"},large_blue_diamond:{keywords:["shape","jewel","gem"],char:'🔷',fitzpatrick_scale:false,category:"symbols"},small_red_triangle:{keywords:["shape","direction","up","top"],char:'🔺',fitzpatrick_scale:false,category:"symbols"},black_small_square:{keywords:["shape","icon"],char:'▪️',fitzpatrick_scale:false,category:"symbols"},white_small_square:{keywords:["shape","icon"],char:'▫️',fitzpatrick_scale:false,category:"symbols"},black_large_square:{keywords:["shape","icon","button"],char:'⬛',fitzpatrick_scale:false,category:"symbols"},white_large_square:{keywords:["shape","icon","stone","button"],char:'⬜',fitzpatrick_scale:false,category:"symbols"},small_red_triangle_down:{keywords:["shape","direction","bottom"],char:'🔻',fitzpatrick_scale:false,category:"symbols"},black_medium_square:{keywords:["shape","button","icon"],char:'◼️',fitzpatrick_scale:false,category:"symbols"},white_medium_square:{keywords:["shape","stone","icon"],char:'◻️',fitzpatrick_scale:false,category:"symbols"},black_medium_small_square:{keywords:["icon","shape","button"],char:'◾',fitzpatrick_scale:false,category:"symbols"},white_medium_small_square:{keywords:["shape","stone","icon","button"],char:'◽',fitzpatrick_scale:false,category:"symbols"},black_square_button:{keywords:["shape","input","frame"],char:'🔲',fitzpatrick_scale:false,category:"symbols"},white_square_button:{keywords:["shape","input"],char:'🔳',fitzpatrick_scale:false,category:"symbols"},speaker:{keywords:["sound","volume","silence","broadcast"],char:'🔈',fitzpatrick_scale:false,category:"symbols"},sound:{keywords:["volume","speaker","broadcast"],char:'🔉',fitzpatrick_scale:false,category:"symbols"},loud_sound:{keywords:["volume","noise","noisy","speaker","broadcast"],char:'🔊',fitzpatrick_scale:false,category:"symbols"},mute:{keywords:["sound","volume","silence","quiet"],char:'🔇',fitzpatrick_scale:false,category:"symbols"},mega:{keywords:["sound","speaker","volume"],char:'📣',fitzpatrick_scale:false,category:"symbols"},loudspeaker:{keywords:["volume","sound"],char:'📢',fitzpatrick_scale:false,category:"symbols"},bell:{keywords:["sound","notification","christmas","xmas","chime"],char:'🔔',fitzpatrick_scale:false,category:"symbols"},no_bell:{keywords:["sound","volume","mute","quiet","silent"],char:'🔕',fitzpatrick_scale:false,category:"symbols"},black_joker:{keywords:["poker","cards","game","play","magic"],char:'🃏',fitzpatrick_scale:false,category:"symbols"},mahjong:{keywords:["game","play","chinese","kanji"],char:'🀄',fitzpatrick_scale:false,category:"symbols"},spades:{keywords:["poker","cards","suits","magic"],char:'♠️',fitzpatrick_scale:false,category:"symbols"},clubs:{keywords:["poker","cards","magic","suits"],char:'♣️',fitzpatrick_scale:false,category:"symbols"},hearts:{keywords:["poker","cards","magic","suits"],char:'♥️',fitzpatrick_scale:false,category:"symbols"},diamonds:{keywords:["poker","cards","magic","suits"],char:'♦️',fitzpatrick_scale:false,category:"symbols"},flower_playing_cards:{keywords:["game","sunset","red"],char:'🎴',fitzpatrick_scale:false,category:"symbols"},thought_balloon:{keywords:["bubble","cloud","speech","thinking","dream"],char:'💭',fitzpatrick_scale:false,category:"symbols"},right_anger_bubble:{keywords:["caption","speech","thinking","mad"],char:'🗯',fitzpatrick_scale:false,category:"symbols"},speech_balloon:{keywords:["bubble","words","message","talk","chatting"],char:'💬',fitzpatrick_scale:false,category:"symbols"},left_speech_bubble:{keywords:["words","message","talk","chatting"],char:'🗨',fitzpatrick_scale:false,category:"symbols"},clock1:{keywords:["time","late","early","schedule"],char:'🕐',fitzpatrick_scale:false,category:"symbols"},clock2:{keywords:["time","late","early","schedule"],char:'🕑',fitzpatrick_scale:false,category:"symbols"},clock3:{keywords:["time","late","early","schedule"],char:'🕒',fitzpatrick_scale:false,category:"symbols"},clock4:{keywords:["time","late","early","schedule"],char:'🕓',fitzpatrick_scale:false,category:"symbols"},clock5:{keywords:["time","late","early","schedule"],char:'🕔',fitzpatrick_scale:false,category:"symbols"},clock6:{keywords:["time","late","early","schedule","dawn","dusk"],char:'🕕',fitzpatrick_scale:false,category:"symbols"},clock7:{keywords:["time","late","early","schedule"],char:'🕖',fitzpatrick_scale:false,category:"symbols"},clock8:{keywords:["time","late","early","schedule"],char:'🕗',fitzpatrick_scale:false,category:"symbols"},clock9:{keywords:["time","late","early","schedule"],char:'🕘',fitzpatrick_scale:false,category:"symbols"},clock10:{keywords:["time","late","early","schedule"],char:'🕙',fitzpatrick_scale:false,category:"symbols"},clock11:{keywords:["time","late","early","schedule"],char:'🕚',fitzpatrick_scale:false,category:"symbols"},clock12:{keywords:["time","noon","midnight","midday","late","early","schedule"],char:'🕛',fitzpatrick_scale:false,category:"symbols"},clock130:{keywords:["time","late","early","schedule"],char:'🕜',fitzpatrick_scale:false,category:"symbols"},clock230:{keywords:["time","late","early","schedule"],char:'🕝',fitzpatrick_scale:false,category:"symbols"},clock330:{keywords:["time","late","early","schedule"],char:'🕞',fitzpatrick_scale:false,category:"symbols"},clock430:{keywords:["time","late","early","schedule"],char:'🕟',fitzpatrick_scale:false,category:"symbols"},clock530:{keywords:["time","late","early","schedule"],char:'🕠',fitzpatrick_scale:false,category:"symbols"},clock630:{keywords:["time","late","early","schedule"],char:'🕡',fitzpatrick_scale:false,category:"symbols"},clock730:{keywords:["time","late","early","schedule"],char:'🕢',fitzpatrick_scale:false,category:"symbols"},clock830:{keywords:["time","late","early","schedule"],char:'🕣',fitzpatrick_scale:false,category:"symbols"},clock930:{keywords:["time","late","early","schedule"],char:'🕤',fitzpatrick_scale:false,category:"symbols"},clock1030:{keywords:["time","late","early","schedule"],char:'🕥',fitzpatrick_scale:false,category:"symbols"},clock1130:{keywords:["time","late","early","schedule"],char:'🕦',fitzpatrick_scale:false,category:"symbols"},clock1230:{keywords:["time","late","early","schedule"],char:'🕧',fitzpatrick_scale:false,category:"symbols"},afghanistan:{keywords:["af","flag","nation","country","banner"],char:'🇦🇫',fitzpatrick_scale:false,category:"flags"},aland_islands:{keywords:["Åland","islands","flag","nation","country","banner"],char:'🇦🇽',fitzpatrick_scale:false,category:"flags"},albania:{keywords:["al","flag","nation","country","banner"],char:'🇦🇱',fitzpatrick_scale:false,category:"flags"},algeria:{keywords:["dz","flag","nation","country","banner"],char:'🇩🇿',fitzpatrick_scale:false,category:"flags"},american_samoa:{keywords:["american","ws","flag","nation","country","banner"],char:'🇦🇸',fitzpatrick_scale:false,category:"flags"},andorra:{keywords:["ad","flag","nation","country","banner"],char:'🇦🇩',fitzpatrick_scale:false,category:"flags"},angola:{keywords:["ao","flag","nation","country","banner"],char:'🇦🇴',fitzpatrick_scale:false,category:"flags"},anguilla:{keywords:["ai","flag","nation","country","banner"],char:'🇦🇮',fitzpatrick_scale:false,category:"flags"},antarctica:{keywords:["aq","flag","nation","country","banner"],char:'🇦🇶',fitzpatrick_scale:false,category:"flags"},antigua_barbuda:{keywords:["antigua","barbuda","flag","nation","country","banner"],char:'🇦🇬',fitzpatrick_scale:false,category:"flags"},argentina:{keywords:["ar","flag","nation","country","banner"],char:'🇦🇷',fitzpatrick_scale:false,category:"flags"},armenia:{keywords:["am","flag","nation","country","banner"],char:'🇦🇲',fitzpatrick_scale:false,category:"flags"},aruba:{keywords:["aw","flag","nation","country","banner"],char:'🇦🇼',fitzpatrick_scale:false,category:"flags"},australia:{keywords:["au","flag","nation","country","banner"],char:'🇦🇺',fitzpatrick_scale:false,category:"flags"},austria:{keywords:["at","flag","nation","country","banner"],char:'🇦🇹',fitzpatrick_scale:false,category:"flags"},azerbaijan:{keywords:["az","flag","nation","country","banner"],char:'🇦🇿',fitzpatrick_scale:false,category:"flags"},bahamas:{keywords:["bs","flag","nation","country","banner"],char:'🇧🇸',fitzpatrick_scale:false,category:"flags"},bahrain:{keywords:["bh","flag","nation","country","banner"],char:'🇧🇭',fitzpatrick_scale:false,category:"flags"},bangladesh:{keywords:["bd","flag","nation","country","banner"],char:'🇧🇩',fitzpatrick_scale:false,category:"flags"},barbados:{keywords:["bb","flag","nation","country","banner"],char:'🇧🇧',fitzpatrick_scale:false,category:"flags"},belarus:{keywords:["by","flag","nation","country","banner"],char:'🇧🇾',fitzpatrick_scale:false,category:"flags"},belgium:{keywords:["be","flag","nation","country","banner"],char:'🇧🇪',fitzpatrick_scale:false,category:"flags"},belize:{keywords:["bz","flag","nation","country","banner"],char:'🇧🇿',fitzpatrick_scale:false,category:"flags"},benin:{keywords:["bj","flag","nation","country","banner"],char:'🇧🇯',fitzpatrick_scale:false,category:"flags"},bermuda:{keywords:["bm","flag","nation","country","banner"],char:'🇧🇲',fitzpatrick_scale:false,category:"flags"},bhutan:{keywords:["bt","flag","nation","country","banner"],char:'🇧🇹',fitzpatrick_scale:false,category:"flags"},bolivia:{keywords:["bo","flag","nation","country","banner"],char:'🇧🇴',fitzpatrick_scale:false,category:"flags"},caribbean_netherlands:{keywords:["bonaire","flag","nation","country","banner"],char:'🇧🇶',fitzpatrick_scale:false,category:"flags"},bosnia_herzegovina:{keywords:["bosnia","herzegovina","flag","nation","country","banner"],char:'🇧🇦',fitzpatrick_scale:false,category:"flags"},botswana:{keywords:["bw","flag","nation","country","banner"],char:'🇧🇼',fitzpatrick_scale:false,category:"flags"},brazil:{keywords:["br","flag","nation","country","banner"],char:'🇧🇷',fitzpatrick_scale:false,category:"flags"},british_indian_ocean_territory:{keywords:["british","indian","ocean","territory","flag","nation","country","banner"],char:'🇮🇴',fitzpatrick_scale:false,category:"flags"},british_virgin_islands:{keywords:["british","virgin","islands","bvi","flag","nation","country","banner"],char:'🇻🇬',fitzpatrick_scale:false,category:"flags"},brunei:{keywords:["bn","darussalam","flag","nation","country","banner"],char:'🇧🇳',fitzpatrick_scale:false,category:"flags"},bulgaria:{keywords:["bg","flag","nation","country","banner"],char:'🇧🇬',fitzpatrick_scale:false,category:"flags"},burkina_faso:{keywords:["burkina","faso","flag","nation","country","banner"],char:'🇧🇫',fitzpatrick_scale:false,category:"flags"},burundi:{keywords:["bi","flag","nation","country","banner"],char:'🇧🇮',fitzpatrick_scale:false,category:"flags"},cape_verde:{keywords:["cabo","verde","flag","nation","country","banner"],char:'🇨🇻',fitzpatrick_scale:false,category:"flags"},cambodia:{keywords:["kh","flag","nation","country","banner"],char:'🇰🇭',fitzpatrick_scale:false,category:"flags"},cameroon:{keywords:["cm","flag","nation","country","banner"],char:'🇨🇲',fitzpatrick_scale:false,category:"flags"},canada:{keywords:["ca","flag","nation","country","banner"],char:'🇨🇦',fitzpatrick_scale:false,category:"flags"},canary_islands:{keywords:["canary","islands","flag","nation","country","banner"],char:'🇮🇨',fitzpatrick_scale:false,category:"flags"},cayman_islands:{keywords:["cayman","islands","flag","nation","country","banner"],char:'🇰🇾',fitzpatrick_scale:false,category:"flags"},central_african_republic:{keywords:["central","african","republic","flag","nation","country","banner"],char:'🇨🇫',fitzpatrick_scale:false,category:"flags"},chad:{keywords:["td","flag","nation","country","banner"],char:'🇹🇩',fitzpatrick_scale:false,category:"flags"},chile:{keywords:["flag","nation","country","banner"],char:'🇨🇱',fitzpatrick_scale:false,category:"flags"},cn:{keywords:["china","chinese","prc","flag","country","nation","banner"],char:'🇨🇳',fitzpatrick_scale:false,category:"flags"},christmas_island:{keywords:["christmas","island","flag","nation","country","banner"],char:'🇨🇽',fitzpatrick_scale:false,category:"flags"},cocos_islands:{keywords:["cocos","keeling","islands","flag","nation","country","banner"],char:'🇨🇨',fitzpatrick_scale:false,category:"flags"},colombia:{keywords:["co","flag","nation","country","banner"],char:'🇨🇴',fitzpatrick_scale:false,category:"flags"},comoros:{keywords:["km","flag","nation","country","banner"],char:'🇰🇲',fitzpatrick_scale:false,category:"flags"},congo_brazzaville:{keywords:["congo","flag","nation","country","banner"],char:'🇨🇬',fitzpatrick_scale:false,category:"flags"},congo_kinshasa:{keywords:["congo","democratic","republic","flag","nation","country","banner"],char:'🇨🇩',fitzpatrick_scale:false,category:"flags"},cook_islands:{keywords:["cook","islands","flag","nation","country","banner"],char:'🇨🇰',fitzpatrick_scale:false,category:"flags"},costa_rica:{keywords:["costa","rica","flag","nation","country","banner"],char:'🇨🇷',fitzpatrick_scale:false,category:"flags"},croatia:{keywords:["hr","flag","nation","country","banner"],char:'🇭🇷',fitzpatrick_scale:false,category:"flags"},cuba:{keywords:["cu","flag","nation","country","banner"],char:'🇨🇺',fitzpatrick_scale:false,category:"flags"},curacao:{keywords:["curaçao","flag","nation","country","banner"],char:'🇨🇼',fitzpatrick_scale:false,category:"flags"},cyprus:{keywords:["cy","flag","nation","country","banner"],char:'🇨🇾',fitzpatrick_scale:false,category:"flags"},czech_republic:{keywords:["cz","flag","nation","country","banner"],char:'🇨🇿',fitzpatrick_scale:false,category:"flags"},denmark:{keywords:["dk","flag","nation","country","banner"],char:'🇩🇰',fitzpatrick_scale:false,category:"flags"},djibouti:{keywords:["dj","flag","nation","country","banner"],char:'🇩🇯',fitzpatrick_scale:false,category:"flags"},dominica:{keywords:["dm","flag","nation","country","banner"],char:'🇩🇲',fitzpatrick_scale:false,category:"flags"},dominican_republic:{keywords:["dominican","republic","flag","nation","country","banner"],char:'🇩🇴',fitzpatrick_scale:false,category:"flags"},ecuador:{keywords:["ec","flag","nation","country","banner"],char:'🇪🇨',fitzpatrick_scale:false,category:"flags"},egypt:{keywords:["eg","flag","nation","country","banner"],char:'🇪🇬',fitzpatrick_scale:false,category:"flags"},el_salvador:{keywords:["el","salvador","flag","nation","country","banner"],char:'🇸🇻',fitzpatrick_scale:false,category:"flags"},equatorial_guinea:{keywords:["equatorial","gn","flag","nation","country","banner"],char:'🇬🇶',fitzpatrick_scale:false,category:"flags"},eritrea:{keywords:["er","flag","nation","country","banner"],char:'🇪🇷',fitzpatrick_scale:false,category:"flags"},estonia:{keywords:["ee","flag","nation","country","banner"],char:'🇪🇪',fitzpatrick_scale:false,category:"flags"},ethiopia:{keywords:["et","flag","nation","country","banner"],char:'🇪🇹',fitzpatrick_scale:false,category:"flags"},eu:{keywords:["european","union","flag","banner"],char:'🇪🇺',fitzpatrick_scale:false,category:"flags"},falkland_islands:{keywords:["falkland","islands","malvinas","flag","nation","country","banner"],char:'🇫🇰',fitzpatrick_scale:false,category:"flags"},faroe_islands:{keywords:["faroe","islands","flag","nation","country","banner"],char:'🇫🇴',fitzpatrick_scale:false,category:"flags"},fiji:{keywords:["fj","flag","nation","country","banner"],char:'🇫🇯',fitzpatrick_scale:false,category:"flags"},finland:{keywords:["fi","flag","nation","country","banner"],char:'🇫🇮',fitzpatrick_scale:false,category:"flags"},fr:{keywords:["banner","flag","nation","france","french","country"],char:'🇫🇷',fitzpatrick_scale:false,category:"flags"},french_guiana:{keywords:["french","guiana","flag","nation","country","banner"],char:'🇬🇫',fitzpatrick_scale:false,category:"flags"},french_polynesia:{keywords:["french","polynesia","flag","nation","country","banner"],char:'🇵🇫',fitzpatrick_scale:false,category:"flags"},french_southern_territories:{keywords:["french","southern","territories","flag","nation","country","banner"],char:'🇹🇫',fitzpatrick_scale:false,category:"flags"},gabon:{keywords:["ga","flag","nation","country","banner"],char:'🇬🇦',fitzpatrick_scale:false,category:"flags"},gambia:{keywords:["gm","flag","nation","country","banner"],char:'🇬🇲',fitzpatrick_scale:false,category:"flags"},georgia:{keywords:["ge","flag","nation","country","banner"],char:'🇬🇪',fitzpatrick_scale:false,category:"flags"},de:{keywords:["german","nation","flag","country","banner"],char:'🇩🇪',fitzpatrick_scale:false,category:"flags"},ghana:{keywords:["gh","flag","nation","country","banner"],char:'🇬🇭',fitzpatrick_scale:false,category:"flags"},gibraltar:{keywords:["gi","flag","nation","country","banner"],char:'🇬🇮',fitzpatrick_scale:false,category:"flags"},greece:{keywords:["gr","flag","nation","country","banner"],char:'🇬🇷',fitzpatrick_scale:false,category:"flags"},greenland:{keywords:["gl","flag","nation","country","banner"],char:'🇬🇱',fitzpatrick_scale:false,category:"flags"},grenada:{keywords:["gd","flag","nation","country","banner"],char:'🇬🇩',fitzpatrick_scale:false,category:"flags"},guadeloupe:{keywords:["gp","flag","nation","country","banner"],char:'🇬🇵',fitzpatrick_scale:false,category:"flags"},guam:{keywords:["gu","flag","nation","country","banner"],char:'🇬🇺',fitzpatrick_scale:false,category:"flags"},guatemala:{keywords:["gt","flag","nation","country","banner"],char:'🇬🇹',fitzpatrick_scale:false,category:"flags"},guernsey:{keywords:["gg","flag","nation","country","banner"],char:'🇬🇬',fitzpatrick_scale:false,category:"flags"},guinea:{keywords:["gn","flag","nation","country","banner"],char:'🇬🇳',fitzpatrick_scale:false,category:"flags"},guinea_bissau:{keywords:["gw","bissau","flag","nation","country","banner"],char:'🇬🇼',fitzpatrick_scale:false,category:"flags"},guyana:{keywords:["gy","flag","nation","country","banner"],char:'🇬🇾',fitzpatrick_scale:false,category:"flags"},haiti:{keywords:["ht","flag","nation","country","banner"],char:'🇭🇹',fitzpatrick_scale:false,category:"flags"},honduras:{keywords:["hn","flag","nation","country","banner"],char:'🇭🇳',fitzpatrick_scale:false,category:"flags"},hong_kong:{keywords:["hong","kong","flag","nation","country","banner"],char:'🇭🇰',fitzpatrick_scale:false,category:"flags"},hungary:{keywords:["hu","flag","nation","country","banner"],char:'🇭🇺',fitzpatrick_scale:false,category:"flags"},iceland:{keywords:["is","flag","nation","country","banner"],char:'🇮🇸',fitzpatrick_scale:false,category:"flags"},india:{keywords:["in","flag","nation","country","banner"],char:'🇮🇳',fitzpatrick_scale:false,category:"flags"},indonesia:{keywords:["flag","nation","country","banner"],char:'🇮🇩',fitzpatrick_scale:false,category:"flags"},iran:{keywords:["iran,","islamic","republic","flag","nation","country","banner"],char:'🇮🇷',fitzpatrick_scale:false,category:"flags"},iraq:{keywords:["iq","flag","nation","country","banner"],char:'🇮🇶',fitzpatrick_scale:false,category:"flags"},ireland:{keywords:["ie","flag","nation","country","banner"],char:'🇮🇪',fitzpatrick_scale:false,category:"flags"},isle_of_man:{keywords:["isle","man","flag","nation","country","banner"],char:'🇮🇲',fitzpatrick_scale:false,category:"flags"},israel:{keywords:["il","flag","nation","country","banner"],char:'🇮🇱',fitzpatrick_scale:false,category:"flags"},it:{keywords:["italy","flag","nation","country","banner"],char:'🇮🇹',fitzpatrick_scale:false,category:"flags"},cote_divoire:{keywords:["ivory","coast","flag","nation","country","banner"],char:'🇨🇮',fitzpatrick_scale:false,category:"flags"},jamaica:{keywords:["jm","flag","nation","country","banner"],char:'🇯🇲',fitzpatrick_scale:false,category:"flags"},jp:{keywords:["japanese","nation","flag","country","banner"],char:'🇯🇵',fitzpatrick_scale:false,category:"flags"},jersey:{keywords:["je","flag","nation","country","banner"],char:'🇯🇪',fitzpatrick_scale:false,category:"flags"},jordan:{keywords:["jo","flag","nation","country","banner"],char:'🇯🇴',fitzpatrick_scale:false,category:"flags"},kazakhstan:{keywords:["kz","flag","nation","country","banner"],char:'🇰🇿',fitzpatrick_scale:false,category:"flags"},kenya:{keywords:["ke","flag","nation","country","banner"],char:'🇰🇪',fitzpatrick_scale:false,category:"flags"},kiribati:{keywords:["ki","flag","nation","country","banner"],char:'🇰🇮',fitzpatrick_scale:false,category:"flags"},kosovo:{keywords:["xk","flag","nation","country","banner"],char:'🇽🇰',fitzpatrick_scale:false,category:"flags"},kuwait:{keywords:["kw","flag","nation","country","banner"],char:'🇰🇼',fitzpatrick_scale:false,category:"flags"},kyrgyzstan:{keywords:["kg","flag","nation","country","banner"],char:'🇰🇬',fitzpatrick_scale:false,category:"flags"},laos:{keywords:["lao","democratic","republic","flag","nation","country","banner"],char:'🇱🇦',fitzpatrick_scale:false,category:"flags"},latvia:{keywords:["lv","flag","nation","country","banner"],char:'🇱🇻',fitzpatrick_scale:false,category:"flags"},lebanon:{keywords:["lb","flag","nation","country","banner"],char:'🇱🇧',fitzpatrick_scale:false,category:"flags"},lesotho:{keywords:["ls","flag","nation","country","banner"],char:'🇱🇸',fitzpatrick_scale:false,category:"flags"},liberia:{keywords:["lr","flag","nation","country","banner"],char:'🇱🇷',fitzpatrick_scale:false,category:"flags"},libya:{keywords:["ly","flag","nation","country","banner"],char:'🇱🇾',fitzpatrick_scale:false,category:"flags"},liechtenstein:{keywords:["li","flag","nation","country","banner"],char:'🇱🇮',fitzpatrick_scale:false,category:"flags"},lithuania:{keywords:["lt","flag","nation","country","banner"],char:'🇱🇹',fitzpatrick_scale:false,category:"flags"},luxembourg:{keywords:["lu","flag","nation","country","banner"],char:'🇱🇺',fitzpatrick_scale:false,category:"flags"},macau:{keywords:["macao","flag","nation","country","banner"],char:'🇲🇴',fitzpatrick_scale:false,category:"flags"},macedonia:{keywords:["macedonia,","flag","nation","country","banner"],char:'🇲🇰',fitzpatrick_scale:false,category:"flags"},madagascar:{keywords:["mg","flag","nation","country","banner"],char:'🇲🇬',fitzpatrick_scale:false,category:"flags"},malawi:{keywords:["mw","flag","nation","country","banner"],char:'🇲🇼',fitzpatrick_scale:false,category:"flags"},malaysia:{keywords:["my","flag","nation","country","banner"],char:'🇲🇾',fitzpatrick_scale:false,category:"flags"},maldives:{keywords:["mv","flag","nation","country","banner"],char:'🇲🇻',fitzpatrick_scale:false,category:"flags"},mali:{keywords:["ml","flag","nation","country","banner"],char:'🇲🇱',fitzpatrick_scale:false,category:"flags"},malta:{keywords:["mt","flag","nation","country","banner"],char:'🇲🇹',fitzpatrick_scale:false,category:"flags"},marshall_islands:{keywords:["marshall","islands","flag","nation","country","banner"],char:'🇲🇭',fitzpatrick_scale:false,category:"flags"},martinique:{keywords:["mq","flag","nation","country","banner"],char:'🇲🇶',fitzpatrick_scale:false,category:"flags"},mauritania:{keywords:["mr","flag","nation","country","banner"],char:'🇲🇷',fitzpatrick_scale:false,category:"flags"},mauritius:{keywords:["mu","flag","nation","country","banner"],char:'🇲🇺',fitzpatrick_scale:false,category:"flags"},mayotte:{keywords:["yt","flag","nation","country","banner"],char:'🇾🇹',fitzpatrick_scale:false,category:"flags"},mexico:{keywords:["mx","flag","nation","country","banner"],char:'🇲🇽',fitzpatrick_scale:false,category:"flags"},micronesia:{keywords:["micronesia,","federated","states","flag","nation","country","banner"],char:'🇫🇲',fitzpatrick_scale:false,category:"flags"},moldova:{keywords:["moldova,","republic","flag","nation","country","banner"],char:'🇲🇩',fitzpatrick_scale:false,category:"flags"},monaco:{keywords:["mc","flag","nation","country","banner"],char:'🇲🇨',fitzpatrick_scale:false,category:"flags"},mongolia:{keywords:["mn","flag","nation","country","banner"],char:'🇲🇳',fitzpatrick_scale:false,category:"flags"},montenegro:{keywords:["me","flag","nation","country","banner"],char:'🇲🇪',fitzpatrick_scale:false,category:"flags"},montserrat:{keywords:["ms","flag","nation","country","banner"],char:'🇲🇸',fitzpatrick_scale:false,category:"flags"},morocco:{keywords:["ma","flag","nation","country","banner"],char:'🇲🇦',fitzpatrick_scale:false,category:"flags"},mozambique:{keywords:["mz","flag","nation","country","banner"],char:'🇲🇿',fitzpatrick_scale:false,category:"flags"},myanmar:{keywords:["mm","flag","nation","country","banner"],char:'🇲🇲',fitzpatrick_scale:false,category:"flags"},namibia:{keywords:["na","flag","nation","country","banner"],char:'🇳🇦',fitzpatrick_scale:false,category:"flags"},nauru:{keywords:["nr","flag","nation","country","banner"],char:'🇳🇷',fitzpatrick_scale:false,category:"flags"},nepal:{keywords:["np","flag","nation","country","banner"],char:'🇳🇵',fitzpatrick_scale:false,category:"flags"},netherlands:{keywords:["nl","flag","nation","country","banner"],char:'🇳🇱',fitzpatrick_scale:false,category:"flags"},new_caledonia:{keywords:["new","caledonia","flag","nation","country","banner"],char:'🇳🇨',fitzpatrick_scale:false,category:"flags"},new_zealand:{keywords:["new","zealand","flag","nation","country","banner"],char:'🇳🇿',fitzpatrick_scale:false,category:"flags"},nicaragua:{keywords:["ni","flag","nation","country","banner"],char:'🇳🇮',fitzpatrick_scale:false,category:"flags"},niger:{keywords:["ne","flag","nation","country","banner"],char:'🇳🇪',fitzpatrick_scale:false,category:"flags"},nigeria:{keywords:["flag","nation","country","banner"],char:'🇳🇬',fitzpatrick_scale:false,category:"flags"},niue:{keywords:["nu","flag","nation","country","banner"],char:'🇳🇺',fitzpatrick_scale:false,category:"flags"},norfolk_island:{keywords:["norfolk","island","flag","nation","country","banner"],char:'🇳🇫',fitzpatrick_scale:false,category:"flags"},northern_mariana_islands:{keywords:["northern","mariana","islands","flag","nation","country","banner"],char:'🇲🇵',fitzpatrick_scale:false,category:"flags"},north_korea:{keywords:["north","korea","nation","flag","country","banner"],char:'🇰🇵',fitzpatrick_scale:false,category:"flags"},norway:{keywords:["no","flag","nation","country","banner"],char:'🇳🇴',fitzpatrick_scale:false,category:"flags"},oman:{keywords:["om_symbol","flag","nation","country","banner"],char:'🇴🇲',fitzpatrick_scale:false,category:"flags"},pakistan:{keywords:["pk","flag","nation","country","banner"],char:'🇵🇰',fitzpatrick_scale:false,category:"flags"},palau:{keywords:["pw","flag","nation","country","banner"],char:'🇵🇼',fitzpatrick_scale:false,category:"flags"},palestinian_territories:{keywords:["palestine","palestinian","territories","flag","nation","country","banner"],char:'🇵🇸',fitzpatrick_scale:false,category:"flags"},panama:{keywords:["pa","flag","nation","country","banner"],char:'🇵🇦',fitzpatrick_scale:false,category:"flags"},papua_new_guinea:{keywords:["papua","new","guinea","flag","nation","country","banner"],char:'🇵🇬',fitzpatrick_scale:false,category:"flags"},paraguay:{keywords:["py","flag","nation","country","banner"],char:'🇵🇾',fitzpatrick_scale:false,category:"flags"},peru:{keywords:["pe","flag","nation","country","banner"],char:'🇵🇪',fitzpatrick_scale:false,category:"flags"},philippines:{keywords:["ph","flag","nation","country","banner"],char:'🇵🇭',fitzpatrick_scale:false,category:"flags"},pitcairn_islands:{keywords:["pitcairn","flag","nation","country","banner"],char:'🇵🇳',fitzpatrick_scale:false,category:"flags"},poland:{keywords:["pl","flag","nation","country","banner"],char:'🇵🇱',fitzpatrick_scale:false,category:"flags"},portugal:{keywords:["pt","flag","nation","country","banner"],char:'🇵🇹',fitzpatrick_scale:false,category:"flags"},puerto_rico:{keywords:["puerto","rico","flag","nation","country","banner"],char:'🇵🇷',fitzpatrick_scale:false,category:"flags"},qatar:{keywords:["qa","flag","nation","country","banner"],char:'🇶🇦',fitzpatrick_scale:false,category:"flags"},reunion:{keywords:["réunion","flag","nation","country","banner"],char:'🇷🇪',fitzpatrick_scale:false,category:"flags"},romania:{keywords:["ro","flag","nation","country","banner"],char:'🇷🇴',fitzpatrick_scale:false,category:"flags"},ru:{keywords:["russian","federation","flag","nation","country","banner"],char:'🇷🇺',fitzpatrick_scale:false,category:"flags"},rwanda:{keywords:["rw","flag","nation","country","banner"],char:'🇷🇼',fitzpatrick_scale:false,category:"flags"},st_barthelemy:{keywords:["saint","barthélemy","flag","nation","country","banner"],char:'🇧🇱',fitzpatrick_scale:false,category:"flags"},st_helena:{keywords:["saint","helena","ascension","tristan","cunha","flag","nation","country","banner"],char:'🇸🇭',fitzpatrick_scale:false,category:"flags"},st_kitts_nevis:{keywords:["saint","kitts","nevis","flag","nation","country","banner"],char:'🇰🇳',fitzpatrick_scale:false,category:"flags"},st_lucia:{keywords:["saint","lucia","flag","nation","country","banner"],char:'🇱🇨',fitzpatrick_scale:false,category:"flags"},st_pierre_miquelon:{keywords:["saint","pierre","miquelon","flag","nation","country","banner"],char:'🇵🇲',fitzpatrick_scale:false,category:"flags"},st_vincent_grenadines:{keywords:["saint","vincent","grenadines","flag","nation","country","banner"],char:'🇻🇨',fitzpatrick_scale:false,category:"flags"},samoa:{keywords:["ws","flag","nation","country","banner"],char:'🇼🇸',fitzpatrick_scale:false,category:"flags"},san_marino:{keywords:["san","marino","flag","nation","country","banner"],char:'🇸🇲',fitzpatrick_scale:false,category:"flags"},sao_tome_principe:{keywords:["sao","tome","principe","flag","nation","country","banner"],char:'🇸🇹',fitzpatrick_scale:false,category:"flags"},saudi_arabia:{keywords:["flag","nation","country","banner"],char:'🇸🇦',fitzpatrick_scale:false,category:"flags"},senegal:{keywords:["sn","flag","nation","country","banner"],char:'🇸🇳',fitzpatrick_scale:false,category:"flags"},serbia:{keywords:["rs","flag","nation","country","banner"],char:'🇷🇸',fitzpatrick_scale:false,category:"flags"},seychelles:{keywords:["sc","flag","nation","country","banner"],char:'🇸🇨',fitzpatrick_scale:false,category:"flags"},sierra_leone:{keywords:["sierra","leone","flag","nation","country","banner"],char:'🇸🇱',fitzpatrick_scale:false,category:"flags"},singapore:{keywords:["sg","flag","nation","country","banner"],char:'🇸🇬',fitzpatrick_scale:false,category:"flags"},sint_maarten:{keywords:["sint","maarten","dutch","flag","nation","country","banner"],char:'🇸🇽',fitzpatrick_scale:false,category:"flags"},slovakia:{keywords:["sk","flag","nation","country","banner"],char:'🇸🇰',fitzpatrick_scale:false,category:"flags"},slovenia:{keywords:["si","flag","nation","country","banner"],char:'🇸🇮',fitzpatrick_scale:false,category:"flags"},solomon_islands:{keywords:["solomon","islands","flag","nation","country","banner"],char:'🇸🇧',fitzpatrick_scale:false,category:"flags"},somalia:{keywords:["so","flag","nation","country","banner"],char:'🇸🇴',fitzpatrick_scale:false,category:"flags"},south_africa:{keywords:["south","africa","flag","nation","country","banner"],char:'🇿🇦',fitzpatrick_scale:false,category:"flags"},south_georgia_south_sandwich_islands:{keywords:["south","georgia","sandwich","islands","flag","nation","country","banner"],char:'🇬🇸',fitzpatrick_scale:false,category:"flags"},kr:{keywords:["south","korea","nation","flag","country","banner"],char:'🇰🇷',fitzpatrick_scale:false,category:"flags"},south_sudan:{keywords:["south","sd","flag","nation","country","banner"],char:'🇸🇸',fitzpatrick_scale:false,category:"flags"},es:{keywords:["spain","flag","nation","country","banner"],char:'🇪🇸',fitzpatrick_scale:false,category:"flags"},sri_lanka:{keywords:["sri","lanka","flag","nation","country","banner"],char:'🇱🇰',fitzpatrick_scale:false,category:"flags"},sudan:{keywords:["sd","flag","nation","country","banner"],char:'🇸🇩',fitzpatrick_scale:false,category:"flags"},suriname:{keywords:["sr","flag","nation","country","banner"],char:'🇸🇷',fitzpatrick_scale:false,category:"flags"},swaziland:{keywords:["sz","flag","nation","country","banner"],char:'🇸🇿',fitzpatrick_scale:false,category:"flags"},sweden:{keywords:["se","flag","nation","country","banner"],char:'🇸🇪',fitzpatrick_scale:false,category:"flags"},switzerland:{keywords:["ch","flag","nation","country","banner"],char:'🇨🇭',fitzpatrick_scale:false,category:"flags"},syria:{keywords:["syrian","arab","republic","flag","nation","country","banner"],char:'🇸🇾',fitzpatrick_scale:false,category:"flags"},taiwan:{keywords:["tw","flag","nation","country","banner"],char:'🇹🇼',fitzpatrick_scale:false,category:"flags"},tajikistan:{keywords:["tj","flag","nation","country","banner"],char:'🇹🇯',fitzpatrick_scale:false,category:"flags"},tanzania:{keywords:["tanzania,","united","republic","flag","nation","country","banner"],char:'🇹🇿',fitzpatrick_scale:false,category:"flags"},thailand:{keywords:["th","flag","nation","country","banner"],char:'🇹🇭',fitzpatrick_scale:false,category:"flags"},timor_leste:{keywords:["timor","leste","flag","nation","country","banner"],char:'🇹🇱',fitzpatrick_scale:false,category:"flags"},togo:{keywords:["tg","flag","nation","country","banner"],char:'🇹🇬',fitzpatrick_scale:false,category:"flags"},tokelau:{keywords:["tk","flag","nation","country","banner"],char:'🇹🇰',fitzpatrick_scale:false,category:"flags"},tonga:{keywords:["to","flag","nation","country","banner"],char:'🇹🇴',fitzpatrick_scale:false,category:"flags"},trinidad_tobago:{keywords:["trinidad","tobago","flag","nation","country","banner"],char:'🇹🇹',fitzpatrick_scale:false,category:"flags"},tunisia:{keywords:["tn","flag","nation","country","banner"],char:'🇹🇳',fitzpatrick_scale:false,category:"flags"},tr:{keywords:["turkey","flag","nation","country","banner"],char:'🇹🇷',fitzpatrick_scale:false,category:"flags"},turkmenistan:{keywords:["flag","nation","country","banner"],char:'🇹🇲',fitzpatrick_scale:false,category:"flags"},turks_caicos_islands:{keywords:["turks","caicos","islands","flag","nation","country","banner"],char:'🇹🇨',fitzpatrick_scale:false,category:"flags"},tuvalu:{keywords:["flag","nation","country","banner"],char:'🇹🇻',fitzpatrick_scale:false,category:"flags"},uganda:{keywords:["ug","flag","nation","country","banner"],char:'🇺🇬',fitzpatrick_scale:false,category:"flags"},ukraine:{keywords:["ua","flag","nation","country","banner"],char:'🇺🇦',fitzpatrick_scale:false,category:"flags"},united_arab_emirates:{keywords:["united","arab","emirates","flag","nation","country","banner"],char:'🇦🇪',fitzpatrick_scale:false,category:"flags"},uk:{keywords:["united","kingdom","great","britain","northern","ireland","flag","nation","country","banner","british","UK","english","england","union jack"],char:'🇬🇧',fitzpatrick_scale:false,category:"flags"},england:{keywords:["flag","english"],char:'🏴󠁧󠁢󠁥󠁮󠁧󠁿',fitzpatrick_scale:false,category:"flags"},scotland:{keywords:["flag","scottish"],char:'🏴󠁧󠁢󠁳󠁣󠁴󠁿',fitzpatrick_scale:false,category:"flags"},wales:{keywords:["flag","welsh"],char:'🏴󠁧󠁢󠁷󠁬󠁳󠁿',fitzpatrick_scale:false,category:"flags"},us:{keywords:["united","states","america","flag","nation","country","banner"],char:'🇺🇸',fitzpatrick_scale:false,category:"flags"},us_virgin_islands:{keywords:["virgin","islands","us","flag","nation","country","banner"],char:'🇻🇮',fitzpatrick_scale:false,category:"flags"},uruguay:{keywords:["uy","flag","nation","country","banner"],char:'🇺🇾',fitzpatrick_scale:false,category:"flags"},uzbekistan:{keywords:["uz","flag","nation","country","banner"],char:'🇺🇿',fitzpatrick_scale:false,category:"flags"},vanuatu:{keywords:["vu","flag","nation","country","banner"],char:'🇻🇺',fitzpatrick_scale:false,category:"flags"},vatican_city:{keywords:["vatican","city","flag","nation","country","banner"],char:'🇻🇦',fitzpatrick_scale:false,category:"flags"},venezuela:{keywords:["ve","bolivarian","republic","flag","nation","country","banner"],char:'🇻🇪',fitzpatrick_scale:false,category:"flags"},vietnam:{keywords:["viet","nam","flag","nation","country","banner"],char:'🇻🇳',fitzpatrick_scale:false,category:"flags"},wallis_futuna:{keywords:["wallis","futuna","flag","nation","country","banner"],char:'🇼🇫',fitzpatrick_scale:false,category:"flags"},western_sahara:{keywords:["western","sahara","flag","nation","country","banner"],char:'🇪🇭',fitzpatrick_scale:false,category:"flags"},yemen:{keywords:["ye","flag","nation","country","banner"],char:'🇾🇪',fitzpatrick_scale:false,category:"flags"},zambia:{keywords:["zm","flag","nation","country","banner"],char:'🇿🇲',fitzpatrick_scale:false,category:"flags"},zimbabwe:{keywords:["zw","flag","nation","country","banner"],char:'🇿🇼',fitzpatrick_scale:false,category:"flags"},united_nations:{keywords:["un","flag","banner"],char:'🇺🇳',fitzpatrick_scale:false,category:"flags"},pirate_flag:{keywords:["skull","crossbones","flag","banner"],char:'🏴‍☠️',fitzpatrick_scale:false,category:"flags"}}); \ No newline at end of file diff --git a/static/js/tinymce/plugins/emoticons/js/emojiimages.min.js b/static/js/tinymce/plugins/emoticons/js/emojiimages.min.js new file mode 100644 index 0000000..37f3bcf --- /dev/null +++ b/static/js/tinymce/plugins/emoticons/js/emojiimages.min.js @@ -0,0 +1,3 @@ +// Source: npm package: emojilib +// Images provided by twemoji: https://github.com/twitter/twemoji +window.tinymce.Resource.add("tinymce.plugins.emoticons",{100:{keywords:["score","perfect","numbers","century","exam","quiz","test","pass","hundred"],char:'\u{1f4af}',fitzpatrick_scale:!1,category:"symbols"},1234:{keywords:["numbers","blue-square"],char:'\u{1f522}',fitzpatrick_scale:!1,category:"symbols"},grinning:{keywords:["face","smile","happy","joy",":D","grin"],char:'\u{1f600}',fitzpatrick_scale:!1,category:"people"},grimacing:{keywords:["face","grimace","teeth"],char:'\u{1f62c}',fitzpatrick_scale:!1,category:"people"},grin:{keywords:["face","happy","smile","joy","kawaii"],char:'\u{1f601}',fitzpatrick_scale:!1,category:"people"},joy:{keywords:["face","cry","tears","weep","happy","happytears","haha"],char:'\u{1f602}',fitzpatrick_scale:!1,category:"people"},rofl:{keywords:["face","rolling","floor","laughing","lol","haha"],char:'\u{1f923}',fitzpatrick_scale:!1,category:"people"},partying:{keywords:["face","celebration","woohoo"],char:'\u{1f973}',fitzpatrick_scale:!1,category:"people"},smiley:{keywords:["face","happy","joy","haha",":D",":)","smile","funny"],char:'\u{1f603}',fitzpatrick_scale:!1,category:"people"},smile:{keywords:["face","happy","joy","funny","haha","laugh","like",":D",":)"],char:'\u{1f604}',fitzpatrick_scale:!1,category:"people"},sweat_smile:{keywords:["face","hot","happy","laugh","sweat","smile","relief"],char:'\u{1f605}',fitzpatrick_scale:!1,category:"people"},laughing:{keywords:["happy","joy","lol","satisfied","haha","face","glad","XD","laugh"],char:'\u{1f606}',fitzpatrick_scale:!1,category:"people"},innocent:{keywords:["face","angel","heaven","halo"],char:'\u{1f607}',fitzpatrick_scale:!1,category:"people"},wink:{keywords:["face","happy","mischievous","secret",";)","smile","eye"],char:'\u{1f609}',fitzpatrick_scale:!1,category:"people"},blush:{keywords:["face","smile","happy","flushed","crush","embarrassed","shy","joy"],char:'\u{1f60a}',fitzpatrick_scale:!1,category:"people"},slightly_smiling_face:{keywords:["face","smile"],char:'\u{1f642}',fitzpatrick_scale:!1,category:"people"},upside_down_face:{keywords:["face","flipped","silly","smile"],char:'\u{1f643}',fitzpatrick_scale:!1,category:"people"},relaxed:{keywords:["face","blush","massage","happiness"],char:'\u263a\ufe0f',fitzpatrick_scale:!1,category:"people"},yum:{keywords:["happy","joy","tongue","smile","face","silly","yummy","nom","delicious","savouring"],char:'\u{1f60b}',fitzpatrick_scale:!1,category:"people"},relieved:{keywords:["face","relaxed","phew","massage","happiness"],char:'\u{1f60c}',fitzpatrick_scale:!1,category:"people"},heart_eyes:{keywords:["face","love","like","affection","valentines","infatuation","crush","heart"],char:'\u{1f60d}',fitzpatrick_scale:!1,category:"people"},smiling_face_with_three_hearts:{keywords:["face","love","like","affection","valentines","infatuation","crush","hearts","adore"],char:'\u{1f970}',fitzpatrick_scale:!1,category:"people"},kissing_heart:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:'\u{1f618}',fitzpatrick_scale:!1,category:"people"},kissing:{keywords:["love","like","face","3","valentines","infatuation","kiss"],char:'\u{1f617}',fitzpatrick_scale:!1,category:"people"},kissing_smiling_eyes:{keywords:["face","affection","valentines","infatuation","kiss"],char:'\u{1f619}',fitzpatrick_scale:!1,category:"people"},kissing_closed_eyes:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:'\u{1f61a}',fitzpatrick_scale:!1,category:"people"},stuck_out_tongue_winking_eye:{keywords:["face","prank","childish","playful","mischievous","smile","wink","tongue"],char:'\u{1f61c}',fitzpatrick_scale:!1,category:"people"},zany:{keywords:["face","goofy","crazy"],char:'\u{1f92a}',fitzpatrick_scale:!1,category:"people"},raised_eyebrow:{keywords:["face","distrust","scepticism","disapproval","disbelief","surprise"],char:'\u{1f928}',fitzpatrick_scale:!1,category:"people"},monocle:{keywords:["face","stuffy","wealthy"],char:'\u{1f9d0}',fitzpatrick_scale:!1,category:"people"},stuck_out_tongue_closed_eyes:{keywords:["face","prank","playful","mischievous","smile","tongue"],char:'\u{1f61d}',fitzpatrick_scale:!1,category:"people"},stuck_out_tongue:{keywords:["face","prank","childish","playful","mischievous","smile","tongue"],char:'\u{1f61b}',fitzpatrick_scale:!1,category:"people"},money_mouth_face:{keywords:["face","rich","dollar","money"],char:'\u{1f911}',fitzpatrick_scale:!1,category:"people"},nerd_face:{keywords:["face","nerdy","geek","dork"],char:'\u{1f913}',fitzpatrick_scale:!1,category:"people"},sunglasses:{keywords:["face","cool","smile","summer","beach","sunglass"],char:'\u{1f60e}',fitzpatrick_scale:!1,category:"people"},star_struck:{keywords:["face","smile","starry","eyes","grinning"],char:'\u{1f929}',fitzpatrick_scale:!1,category:"people"},clown_face:{keywords:["face"],char:'\u{1f921}',fitzpatrick_scale:!1,category:"people"},cowboy_hat_face:{keywords:["face","cowgirl","hat"],char:'\u{1f920}',fitzpatrick_scale:!1,category:"people"},hugs:{keywords:["face","smile","hug"],char:'\u{1f917}',fitzpatrick_scale:!1,category:"people"},smirk:{keywords:["face","smile","mean","prank","smug","sarcasm"],char:'\u{1f60f}',fitzpatrick_scale:!1,category:"people"},no_mouth:{keywords:["face","hellokitty"],char:'\u{1f636}',fitzpatrick_scale:!1,category:"people"},neutral_face:{keywords:["indifference","meh",":|","neutral"],char:'\u{1f610}',fitzpatrick_scale:!1,category:"people"},expressionless:{keywords:["face","indifferent","-_-","meh","deadpan"],char:'\u{1f611}',fitzpatrick_scale:!1,category:"people"},unamused:{keywords:["indifference","bored","straight face","serious","sarcasm","unimpressed","skeptical","dubious","side_eye"],char:'\u{1f612}',fitzpatrick_scale:!1,category:"people"},roll_eyes:{keywords:["face","eyeroll","frustrated"],char:'\u{1f644}',fitzpatrick_scale:!1,category:"people"},thinking:{keywords:["face","hmmm","think","consider"],char:'\u{1f914}',fitzpatrick_scale:!1,category:"people"},lying_face:{keywords:["face","lie","pinocchio"],char:'\u{1f925}',fitzpatrick_scale:!1,category:"people"},hand_over_mouth:{keywords:["face","whoops","shock","surprise"],char:'\u{1f92d}',fitzpatrick_scale:!1,category:"people"},shushing:{keywords:["face","quiet","shhh"],char:'\u{1f92b}',fitzpatrick_scale:!1,category:"people"},symbols_over_mouth:{keywords:["face","swearing","cursing","cussing","profanity","expletive"],char:'\u{1f92c}',fitzpatrick_scale:!1,category:"people"},exploding_head:{keywords:["face","shocked","mind","blown"],char:'\u{1f92f}',fitzpatrick_scale:!1,category:"people"},flushed:{keywords:["face","blush","shy","flattered"],char:'\u{1f633}',fitzpatrick_scale:!1,category:"people"},disappointed:{keywords:["face","sad","upset","depressed",":("],char:'\u{1f61e}',fitzpatrick_scale:!1,category:"people"},worried:{keywords:["face","concern","nervous",":("],char:'\u{1f61f}',fitzpatrick_scale:!1,category:"people"},angry:{keywords:["mad","face","annoyed","frustrated"],char:'\u{1f620}',fitzpatrick_scale:!1,category:"people"},rage:{keywords:["angry","mad","hate","despise"],char:'\u{1f621}',fitzpatrick_scale:!1,category:"people"},pensive:{keywords:["face","sad","depressed","upset"],char:'\u{1f614}',fitzpatrick_scale:!1,category:"people"},confused:{keywords:["face","indifference","huh","weird","hmmm",":/"],char:'\u{1f615}',fitzpatrick_scale:!1,category:"people"},slightly_frowning_face:{keywords:["face","frowning","disappointed","sad","upset"],char:'\u{1f641}',fitzpatrick_scale:!1,category:"people"},frowning_face:{keywords:["face","sad","upset","frown"],char:'\u2639',fitzpatrick_scale:!1,category:"people"},persevere:{keywords:["face","sick","no","upset","oops"],char:'\u{1f623}',fitzpatrick_scale:!1,category:"people"},confounded:{keywords:["face","confused","sick","unwell","oops",":S"],char:'\u{1f616}',fitzpatrick_scale:!1,category:"people"},tired_face:{keywords:["sick","whine","upset","frustrated"],char:'\u{1f62b}',fitzpatrick_scale:!1,category:"people"},weary:{keywords:["face","tired","sleepy","sad","frustrated","upset"],char:'\u{1f629}',fitzpatrick_scale:!1,category:"people"},pleading:{keywords:["face","begging","mercy"],char:'\u{1f97a}',fitzpatrick_scale:!1,category:"people"},triumph:{keywords:["face","gas","phew","proud","pride"],char:'\u{1f624}',fitzpatrick_scale:!1,category:"people"},open_mouth:{keywords:["face","surprise","impressed","wow","whoa",":O"],char:'\u{1f62e}',fitzpatrick_scale:!1,category:"people"},scream:{keywords:["face","munch","scared","omg"],char:'\u{1f631}',fitzpatrick_scale:!1,category:"people"},fearful:{keywords:["face","scared","terrified","nervous","oops","huh"],char:'\u{1f628}',fitzpatrick_scale:!1,category:"people"},cold_sweat:{keywords:["face","nervous","sweat"],char:'\u{1f630}',fitzpatrick_scale:!1,category:"people"},hushed:{keywords:["face","woo","shh"],char:'\u{1f62f}',fitzpatrick_scale:!1,category:"people"},frowning:{keywords:["face","aw","what"],char:'\u{1f626}',fitzpatrick_scale:!1,category:"people"},anguished:{keywords:["face","stunned","nervous"],char:'\u{1f627}',fitzpatrick_scale:!1,category:"people"},cry:{keywords:["face","tears","sad","depressed","upset",":'("],char:'\u{1f622}',fitzpatrick_scale:!1,category:"people"},disappointed_relieved:{keywords:["face","phew","sweat","nervous"],char:'\u{1f625}',fitzpatrick_scale:!1,category:"people"},drooling_face:{keywords:["face"],char:'\u{1f924}',fitzpatrick_scale:!1,category:"people"},sleepy:{keywords:["face","tired","rest","nap"],char:'\u{1f62a}',fitzpatrick_scale:!1,category:"people"},sweat:{keywords:["face","hot","sad","tired","exercise"],char:'\u{1f613}',fitzpatrick_scale:!1,category:"people"},hot:{keywords:["face","feverish","heat","red","sweating"],char:'\u{1f975}',fitzpatrick_scale:!1,category:"people"},cold:{keywords:["face","blue","freezing","frozen","frostbite","icicles"],char:'\u{1f976}',fitzpatrick_scale:!1,category:"people"},sob:{keywords:["face","cry","tears","sad","upset","depressed"],char:'\u{1f62d}',fitzpatrick_scale:!1,category:"people"},dizzy_face:{keywords:["spent","unconscious","xox","dizzy"],char:'\u{1f635}',fitzpatrick_scale:!1,category:"people"},astonished:{keywords:["face","xox","surprised","poisoned"],char:'\u{1f632}',fitzpatrick_scale:!1,category:"people"},zipper_mouth_face:{keywords:["face","sealed","zipper","secret"],char:'\u{1f910}',fitzpatrick_scale:!1,category:"people"},nauseated_face:{keywords:["face","vomit","gross","green","sick","throw up","ill"],char:'\u{1f922}',fitzpatrick_scale:!1,category:"people"},sneezing_face:{keywords:["face","gesundheit","sneeze","sick","allergy"],char:'\u{1f927}',fitzpatrick_scale:!1,category:"people"},vomiting:{keywords:["face","sick"],char:'\u{1f92e}',fitzpatrick_scale:!1,category:"people"},mask:{keywords:["face","sick","ill","disease"],char:'\u{1f637}',fitzpatrick_scale:!1,category:"people"},face_with_thermometer:{keywords:["sick","temperature","thermometer","cold","fever"],char:'\u{1f912}',fitzpatrick_scale:!1,category:"people"},face_with_head_bandage:{keywords:["injured","clumsy","bandage","hurt"],char:'\u{1f915}',fitzpatrick_scale:!1,category:"people"},woozy:{keywords:["face","dizzy","intoxicated","tipsy","wavy"],char:'\u{1f974}',fitzpatrick_scale:!1,category:"people"},sleeping:{keywords:["face","tired","sleepy","night","zzz"],char:'\u{1f634}',fitzpatrick_scale:!1,category:"people"},zzz:{keywords:["sleepy","tired","dream"],char:'\u{1f4a4}',fitzpatrick_scale:!1,category:"people"},poop:{keywords:["hankey","shitface","fail","turd","shit"],char:'\u{1f4a9}',fitzpatrick_scale:!1,category:"people"},smiling_imp:{keywords:["devil","horns"],char:'\u{1f608}',fitzpatrick_scale:!1,category:"people"},imp:{keywords:["devil","angry","horns"],char:'\u{1f47f}',fitzpatrick_scale:!1,category:"people"},japanese_ogre:{keywords:["monster","red","mask","halloween","scary","creepy","devil","demon","japanese","ogre"],char:'\u{1f479}',fitzpatrick_scale:!1,category:"people"},japanese_goblin:{keywords:["red","evil","mask","monster","scary","creepy","japanese","goblin"],char:'\u{1f47a}',fitzpatrick_scale:!1,category:"people"},skull:{keywords:["dead","skeleton","creepy","death"],char:'\u{1f480}',fitzpatrick_scale:!1,category:"people"},ghost:{keywords:["halloween","spooky","scary"],char:'\u{1f47b}',fitzpatrick_scale:!1,category:"people"},alien:{keywords:["UFO","paul","weird","outer_space"],char:'\u{1f47d}',fitzpatrick_scale:!1,category:"people"},robot:{keywords:["computer","machine","bot"],char:'\u{1f916}',fitzpatrick_scale:!1,category:"people"},smiley_cat:{keywords:["animal","cats","happy","smile"],char:'\u{1f63a}',fitzpatrick_scale:!1,category:"people"},smile_cat:{keywords:["animal","cats","smile"],char:'\u{1f638}',fitzpatrick_scale:!1,category:"people"},joy_cat:{keywords:["animal","cats","haha","happy","tears"],char:'\u{1f639}',fitzpatrick_scale:!1,category:"people"},heart_eyes_cat:{keywords:["animal","love","like","affection","cats","valentines","heart"],char:'\u{1f63b}',fitzpatrick_scale:!1,category:"people"},smirk_cat:{keywords:["animal","cats","smirk"],char:'\u{1f63c}',fitzpatrick_scale:!1,category:"people"},kissing_cat:{keywords:["animal","cats","kiss"],char:'\u{1f63d}',fitzpatrick_scale:!1,category:"people"},scream_cat:{keywords:["animal","cats","munch","scared","scream"],char:'\u{1f640}',fitzpatrick_scale:!1,category:"people"},crying_cat_face:{keywords:["animal","tears","weep","sad","cats","upset","cry"],char:'\u{1f63f}',fitzpatrick_scale:!1,category:"people"},pouting_cat:{keywords:["animal","cats"],char:'\u{1f63e}',fitzpatrick_scale:!1,category:"people"},palms_up:{keywords:["hands","gesture","cupped","prayer"],char:'\u{1f932}',fitzpatrick_scale:!0,category:"people"},raised_hands:{keywords:["gesture","hooray","yea","celebration","hands"],char:'\u{1f64c}',fitzpatrick_scale:!0,category:"people"},clap:{keywords:["hands","praise","applause","congrats","yay"],char:'\u{1f44f}',fitzpatrick_scale:!0,category:"people"},wave:{keywords:["hands","gesture","goodbye","solong","farewell","hello","hi","palm"],char:'\u{1f44b}',fitzpatrick_scale:!0,category:"people"},call_me_hand:{keywords:["hands","gesture"],char:'\u{1f919}',fitzpatrick_scale:!0,category:"people"},"+1":{keywords:["thumbsup","yes","awesome","good","agree","accept","cool","hand","like"],char:'\u{1f44d}',fitzpatrick_scale:!0,category:"people"},"-1":{keywords:["thumbsdown","no","dislike","hand"],char:'\u{1f44e}',fitzpatrick_scale:!0,category:"people"},facepunch:{keywords:["angry","violence","fist","hit","attack","hand"],char:'\u{1f44a}',fitzpatrick_scale:!0,category:"people"},fist:{keywords:["fingers","hand","grasp"],char:'\u270a',fitzpatrick_scale:!0,category:"people"},fist_left:{keywords:["hand","fistbump"],char:'\u{1f91b}',fitzpatrick_scale:!0,category:"people"},fist_right:{keywords:["hand","fistbump"],char:'\u{1f91c}',fitzpatrick_scale:!0,category:"people"},v:{keywords:["fingers","ohyeah","hand","peace","victory","two"],char:'\u270c',fitzpatrick_scale:!0,category:"people"},ok_hand:{keywords:["fingers","limbs","perfect","ok","okay"],char:'\u{1f44c}',fitzpatrick_scale:!0,category:"people"},raised_hand:{keywords:["fingers","stop","highfive","palm","ban"],char:'\u270b',fitzpatrick_scale:!0,category:"people"},raised_back_of_hand:{keywords:["fingers","raised","backhand"],char:'\u{1f91a}',fitzpatrick_scale:!0,category:"people"},open_hands:{keywords:["fingers","butterfly","hands","open"],char:'\u{1f450}',fitzpatrick_scale:!0,category:"people"},muscle:{keywords:["arm","flex","hand","summer","strong","biceps"],char:'\u{1f4aa}',fitzpatrick_scale:!0,category:"people"},pray:{keywords:["please","hope","wish","namaste","highfive"],char:'\u{1f64f}',fitzpatrick_scale:!0,category:"people"},foot:{keywords:["kick","stomp"],char:'\u{1f9b6}',fitzpatrick_scale:!0,category:"people"},leg:{keywords:["kick","limb"],char:'\u{1f9b5}',fitzpatrick_scale:!0,category:"people"},handshake:{keywords:["agreement","shake"],char:'\u{1f91d}',fitzpatrick_scale:!1,category:"people"},point_up:{keywords:["hand","fingers","direction","up"],char:'\u261d',fitzpatrick_scale:!0,category:"people"},point_up_2:{keywords:["fingers","hand","direction","up"],char:'\u{1f446}',fitzpatrick_scale:!0,category:"people"},point_down:{keywords:["fingers","hand","direction","down"],char:'\u{1f447}',fitzpatrick_scale:!0,category:"people"},point_left:{keywords:["direction","fingers","hand","left"],char:'\u{1f448}',fitzpatrick_scale:!0,category:"people"},point_right:{keywords:["fingers","hand","direction","right"],char:'\u{1f449}',fitzpatrick_scale:!0,category:"people"},fu:{keywords:["hand","fingers","rude","middle","flipping"],char:'\u{1f595}',fitzpatrick_scale:!0,category:"people"},raised_hand_with_fingers_splayed:{keywords:["hand","fingers","palm"],char:'\u{1f590}',fitzpatrick_scale:!0,category:"people"},love_you:{keywords:["hand","fingers","gesture"],char:'\u{1f91f}',fitzpatrick_scale:!0,category:"people"},metal:{keywords:["hand","fingers","evil_eye","sign_of_horns","rock_on"],char:'\u{1f918}',fitzpatrick_scale:!0,category:"people"},crossed_fingers:{keywords:["good","lucky"],char:'\u{1f91e}',fitzpatrick_scale:!0,category:"people"},vulcan_salute:{keywords:["hand","fingers","spock","star trek"],char:'\u{1f596}',fitzpatrick_scale:!0,category:"people"},writing_hand:{keywords:["lower_left_ballpoint_pen","stationery","write","compose"],char:'\u270d',fitzpatrick_scale:!0,category:"people"},selfie:{keywords:["camera","phone"],char:'\u{1f933}',fitzpatrick_scale:!0,category:"people"},nail_care:{keywords:["beauty","manicure","finger","fashion","nail"],char:'\u{1f485}',fitzpatrick_scale:!0,category:"people"},lips:{keywords:["mouth","kiss"],char:'\u{1f444}',fitzpatrick_scale:!1,category:"people"},tooth:{keywords:["teeth","dentist"],char:'\u{1f9b7}',fitzpatrick_scale:!1,category:"people"},tongue:{keywords:["mouth","playful"],char:'\u{1f445}',fitzpatrick_scale:!1,category:"people"},ear:{keywords:["face","hear","sound","listen"],char:'\u{1f442}',fitzpatrick_scale:!0,category:"people"},nose:{keywords:["smell","sniff"],char:'\u{1f443}',fitzpatrick_scale:!0,category:"people"},eye:{keywords:["face","look","see","watch","stare"],char:'\u{1f441}',fitzpatrick_scale:!1,category:"people"},eyes:{keywords:["look","watch","stalk","peek","see"],char:'\u{1f440}',fitzpatrick_scale:!1,category:"people"},brain:{keywords:["smart","intelligent"],char:'\u{1f9e0}',fitzpatrick_scale:!1,category:"people"},bust_in_silhouette:{keywords:["user","person","human"],char:'\u{1f464}',fitzpatrick_scale:!1,category:"people"},busts_in_silhouette:{keywords:["user","person","human","group","team"],char:'\u{1f465}',fitzpatrick_scale:!1,category:"people"},speaking_head:{keywords:["user","person","human","sing","say","talk"],char:'\u{1f5e3}',fitzpatrick_scale:!1,category:"people"},baby:{keywords:["child","boy","girl","toddler"],char:'\u{1f476}',fitzpatrick_scale:!0,category:"people"},child:{keywords:["gender-neutral","young"],char:'\u{1f9d2}',fitzpatrick_scale:!0,category:"people"},boy:{keywords:["man","male","guy","teenager"],char:'\u{1f466}',fitzpatrick_scale:!0,category:"people"},girl:{keywords:["female","woman","teenager"],char:'\u{1f467}',fitzpatrick_scale:!0,category:"people"},adult:{keywords:["gender-neutral","person"],char:'\u{1f9d1}',fitzpatrick_scale:!0,category:"people"},man:{keywords:["mustache","father","dad","guy","classy","sir","moustache"],char:'\u{1f468}',fitzpatrick_scale:!0,category:"people"},woman:{keywords:["female","girls","lady"],char:'\u{1f469}',fitzpatrick_scale:!0,category:"people"},blonde_woman:{keywords:["woman","female","girl","blonde","person"],char:'\u{1f471}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},blonde_man:{keywords:["man","male","boy","blonde","guy","person"],char:'\u{1f471}',fitzpatrick_scale:!0,category:"people"},bearded_person:{keywords:["person","bewhiskered"],char:'\u{1f9d4}',fitzpatrick_scale:!0,category:"people"},older_adult:{keywords:["human","elder","senior","gender-neutral"],char:'\u{1f9d3}',fitzpatrick_scale:!0,category:"people"},older_man:{keywords:["human","male","men","old","elder","senior"],char:'\u{1f474}',fitzpatrick_scale:!0,category:"people"},older_woman:{keywords:["human","female","women","lady","old","elder","senior"],char:'\u{1f475}',fitzpatrick_scale:!0,category:"people"},man_with_gua_pi_mao:{keywords:["male","boy","chinese"],char:'\u{1f472}',fitzpatrick_scale:!0,category:"people"},woman_with_headscarf:{keywords:["female","hijab","mantilla","tichel"],char:'\u{1f9d5}',fitzpatrick_scale:!0,category:"people"},woman_with_turban:{keywords:["female","indian","hinduism","arabs","woman"],char:'\u{1f473}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_with_turban:{keywords:["male","indian","hinduism","arabs"],char:'\u{1f473}',fitzpatrick_scale:!0,category:"people"},policewoman:{keywords:["woman","police","law","legal","enforcement","arrest","911","female"],char:'\u{1f46e}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},policeman:{keywords:["man","police","law","legal","enforcement","arrest","911"],char:'\u{1f46e}',fitzpatrick_scale:!0,category:"people"},construction_worker_woman:{keywords:["female","human","wip","build","construction","worker","labor","woman"],char:'\u{1f477}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},construction_worker_man:{keywords:["male","human","wip","guy","build","construction","worker","labor"],char:'\u{1f477}',fitzpatrick_scale:!0,category:"people"},guardswoman:{keywords:["uk","gb","british","female","royal","woman"],char:'\u{1f482}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},guardsman:{keywords:["uk","gb","british","male","guy","royal"],char:'\u{1f482}',fitzpatrick_scale:!0,category:"people"},female_detective:{keywords:["human","spy","detective","female","woman"],char:'\u{1f575}\ufe0f\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},male_detective:{keywords:["human","spy","detective"],char:'\u{1f575}',fitzpatrick_scale:!0,category:"people"},woman_health_worker:{keywords:["doctor","nurse","therapist","healthcare","woman","human"],char:'\u{1f469}\u200d\u2695\ufe0f',fitzpatrick_scale:!0,category:"people"},man_health_worker:{keywords:["doctor","nurse","therapist","healthcare","man","human"],char:'\u{1f468}\u200d\u2695\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_farmer:{keywords:["rancher","gardener","woman","human"],char:'\u{1f469}\u200d\u{1f33e}',fitzpatrick_scale:!0,category:"people"},man_farmer:{keywords:["rancher","gardener","man","human"],char:'\u{1f468}\u200d\u{1f33e}',fitzpatrick_scale:!0,category:"people"},woman_cook:{keywords:["chef","woman","human"],char:'\u{1f469}\u200d\u{1f373}',fitzpatrick_scale:!0,category:"people"},man_cook:{keywords:["chef","man","human"],char:'\u{1f468}\u200d\u{1f373}',fitzpatrick_scale:!0,category:"people"},woman_student:{keywords:["graduate","woman","human"],char:'\u{1f469}\u200d\u{1f393}',fitzpatrick_scale:!0,category:"people"},man_student:{keywords:["graduate","man","human"],char:'\u{1f468}\u200d\u{1f393}',fitzpatrick_scale:!0,category:"people"},woman_singer:{keywords:["rockstar","entertainer","woman","human"],char:'\u{1f469}\u200d\u{1f3a4}',fitzpatrick_scale:!0,category:"people"},man_singer:{keywords:["rockstar","entertainer","man","human"],char:'\u{1f468}\u200d\u{1f3a4}',fitzpatrick_scale:!0,category:"people"},woman_teacher:{keywords:["instructor","professor","woman","human"],char:'\u{1f469}\u200d\u{1f3eb}',fitzpatrick_scale:!0,category:"people"},man_teacher:{keywords:["instructor","professor","man","human"],char:'\u{1f468}\u200d\u{1f3eb}',fitzpatrick_scale:!0,category:"people"},woman_factory_worker:{keywords:["assembly","industrial","woman","human"],char:'\u{1f469}\u200d\u{1f3ed}',fitzpatrick_scale:!0,category:"people"},man_factory_worker:{keywords:["assembly","industrial","man","human"],char:'\u{1f468}\u200d\u{1f3ed}',fitzpatrick_scale:!0,category:"people"},woman_technologist:{keywords:["coder","developer","engineer","programmer","software","woman","human","laptop","computer"],char:'\u{1f469}\u200d\u{1f4bb}',fitzpatrick_scale:!0,category:"people"},man_technologist:{keywords:["coder","developer","engineer","programmer","software","man","human","laptop","computer"],char:'\u{1f468}\u200d\u{1f4bb}',fitzpatrick_scale:!0,category:"people"},woman_office_worker:{keywords:["business","manager","woman","human"],char:'\u{1f469}\u200d\u{1f4bc}',fitzpatrick_scale:!0,category:"people"},man_office_worker:{keywords:["business","manager","man","human"],char:'\u{1f468}\u200d\u{1f4bc}',fitzpatrick_scale:!0,category:"people"},woman_mechanic:{keywords:["plumber","woman","human","wrench"],char:'\u{1f469}\u200d\u{1f527}',fitzpatrick_scale:!0,category:"people"},man_mechanic:{keywords:["plumber","man","human","wrench"],char:'\u{1f468}\u200d\u{1f527}',fitzpatrick_scale:!0,category:"people"},woman_scientist:{keywords:["biologist","chemist","engineer","physicist","woman","human"],char:'\u{1f469}\u200d\u{1f52c}',fitzpatrick_scale:!0,category:"people"},man_scientist:{keywords:["biologist","chemist","engineer","physicist","man","human"],char:'\u{1f468}\u200d\u{1f52c}',fitzpatrick_scale:!0,category:"people"},woman_artist:{keywords:["painter","woman","human"],char:'\u{1f469}\u200d\u{1f3a8}',fitzpatrick_scale:!0,category:"people"},man_artist:{keywords:["painter","man","human"],char:'\u{1f468}\u200d\u{1f3a8}',fitzpatrick_scale:!0,category:"people"},woman_firefighter:{keywords:["fireman","woman","human"],char:'\u{1f469}\u200d\u{1f692}',fitzpatrick_scale:!0,category:"people"},man_firefighter:{keywords:["fireman","man","human"],char:'\u{1f468}\u200d\u{1f692}',fitzpatrick_scale:!0,category:"people"},woman_pilot:{keywords:["aviator","plane","woman","human"],char:'\u{1f469}\u200d\u2708\ufe0f',fitzpatrick_scale:!0,category:"people"},man_pilot:{keywords:["aviator","plane","man","human"],char:'\u{1f468}\u200d\u2708\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_astronaut:{keywords:["space","rocket","woman","human"],char:'\u{1f469}\u200d\u{1f680}',fitzpatrick_scale:!0,category:"people"},man_astronaut:{keywords:["space","rocket","man","human"],char:'\u{1f468}\u200d\u{1f680}',fitzpatrick_scale:!0,category:"people"},woman_judge:{keywords:["justice","court","woman","human"],char:'\u{1f469}\u200d\u2696\ufe0f',fitzpatrick_scale:!0,category:"people"},man_judge:{keywords:["justice","court","man","human"],char:'\u{1f468}\u200d\u2696\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_superhero:{keywords:["woman","female","good","heroine","superpowers"],char:'\u{1f9b8}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_superhero:{keywords:["man","male","good","hero","superpowers"],char:'\u{1f9b8}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_supervillain:{keywords:["woman","female","evil","bad","criminal","heroine","superpowers"],char:'\u{1f9b9}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_supervillain:{keywords:["man","male","evil","bad","criminal","hero","superpowers"],char:'\u{1f9b9}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},mrs_claus:{keywords:["woman","female","xmas","mother christmas"],char:'\u{1f936}',fitzpatrick_scale:!0,category:"people"},santa:{keywords:["festival","man","male","xmas","father christmas"],char:'\u{1f385}',fitzpatrick_scale:!0,category:"people"},sorceress:{keywords:["woman","female","mage","witch"],char:'\u{1f9d9}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},wizard:{keywords:["man","male","mage","sorcerer"],char:'\u{1f9d9}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_elf:{keywords:["woman","female"],char:'\u{1f9dd}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_elf:{keywords:["man","male"],char:'\u{1f9dd}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_vampire:{keywords:["woman","female"],char:'\u{1f9db}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_vampire:{keywords:["man","male","dracula"],char:'\u{1f9db}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_zombie:{keywords:["woman","female","undead","walking dead"],char:'\u{1f9df}\u200d\u2640\ufe0f',fitzpatrick_scale:!1,category:"people"},man_zombie:{keywords:["man","male","dracula","undead","walking dead"],char:'\u{1f9df}\u200d\u2642\ufe0f',fitzpatrick_scale:!1,category:"people"},woman_genie:{keywords:["woman","female"],char:'\u{1f9de}\u200d\u2640\ufe0f',fitzpatrick_scale:!1,category:"people"},man_genie:{keywords:["man","male"],char:'\u{1f9de}\u200d\u2642\ufe0f',fitzpatrick_scale:!1,category:"people"},mermaid:{keywords:["woman","female","merwoman","ariel"],char:'\u{1f9dc}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},merman:{keywords:["man","male","triton"],char:'\u{1f9dc}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_fairy:{keywords:["woman","female"],char:'\u{1f9da}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_fairy:{keywords:["man","male"],char:'\u{1f9da}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},angel:{keywords:["heaven","wings","halo"],char:'\u{1f47c}',fitzpatrick_scale:!0,category:"people"},pregnant_woman:{keywords:["baby"],char:'\u{1f930}',fitzpatrick_scale:!0,category:"people"},breastfeeding:{keywords:["nursing","baby"],char:'\u{1f931}',fitzpatrick_scale:!0,category:"people"},princess:{keywords:["girl","woman","female","blond","crown","royal","queen"],char:'\u{1f478}',fitzpatrick_scale:!0,category:"people"},prince:{keywords:["boy","man","male","crown","royal","king"],char:'\u{1f934}',fitzpatrick_scale:!0,category:"people"},bride_with_veil:{keywords:["couple","marriage","wedding","woman","bride"],char:'\u{1f470}',fitzpatrick_scale:!0,category:"people"},man_in_tuxedo:{keywords:["couple","marriage","wedding","groom"],char:'\u{1f935}',fitzpatrick_scale:!0,category:"people"},running_woman:{keywords:["woman","walking","exercise","race","running","female"],char:'\u{1f3c3}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},running_man:{keywords:["man","walking","exercise","race","running"],char:'\u{1f3c3}',fitzpatrick_scale:!0,category:"people"},walking_woman:{keywords:["human","feet","steps","woman","female"],char:'\u{1f6b6}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},walking_man:{keywords:["human","feet","steps"],char:'\u{1f6b6}',fitzpatrick_scale:!0,category:"people"},dancer:{keywords:["female","girl","woman","fun"],char:'\u{1f483}',fitzpatrick_scale:!0,category:"people"},man_dancing:{keywords:["male","boy","fun","dancer"],char:'\u{1f57a}',fitzpatrick_scale:!0,category:"people"},dancing_women:{keywords:["female","bunny","women","girls"],char:'\u{1f46f}',fitzpatrick_scale:!1,category:"people"},dancing_men:{keywords:["male","bunny","men","boys"],char:'\u{1f46f}\u200d\u2642\ufe0f',fitzpatrick_scale:!1,category:"people"},couple:{keywords:["pair","people","human","love","date","dating","like","affection","valentines","marriage"],char:'\u{1f46b}',fitzpatrick_scale:!1,category:"people"},two_men_holding_hands:{keywords:["pair","couple","love","like","bromance","friendship","people","human"],char:'\u{1f46c}',fitzpatrick_scale:!1,category:"people"},two_women_holding_hands:{keywords:["pair","friendship","couple","love","like","female","people","human"],char:'\u{1f46d}',fitzpatrick_scale:!1,category:"people"},bowing_woman:{keywords:["woman","female","girl"],char:'\u{1f647}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},bowing_man:{keywords:["man","male","boy"],char:'\u{1f647}',fitzpatrick_scale:!0,category:"people"},man_facepalming:{keywords:["man","male","boy","disbelief"],char:'\u{1f926}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_facepalming:{keywords:["woman","female","girl","disbelief"],char:'\u{1f926}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_shrugging:{keywords:["woman","female","girl","confused","indifferent","doubt"],char:'\u{1f937}',fitzpatrick_scale:!0,category:"people"},man_shrugging:{keywords:["man","male","boy","confused","indifferent","doubt"],char:'\u{1f937}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},tipping_hand_woman:{keywords:["female","girl","woman","human","information"],char:'\u{1f481}',fitzpatrick_scale:!0,category:"people"},tipping_hand_man:{keywords:["male","boy","man","human","information"],char:'\u{1f481}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},no_good_woman:{keywords:["female","girl","woman","nope"],char:'\u{1f645}',fitzpatrick_scale:!0,category:"people"},no_good_man:{keywords:["male","boy","man","nope"],char:'\u{1f645}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},ok_woman:{keywords:["women","girl","female","pink","human","woman"],char:'\u{1f646}',fitzpatrick_scale:!0,category:"people"},ok_man:{keywords:["men","boy","male","blue","human","man"],char:'\u{1f646}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},raising_hand_woman:{keywords:["female","girl","woman"],char:'\u{1f64b}',fitzpatrick_scale:!0,category:"people"},raising_hand_man:{keywords:["male","boy","man"],char:'\u{1f64b}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},pouting_woman:{keywords:["female","girl","woman"],char:'\u{1f64e}',fitzpatrick_scale:!0,category:"people"},pouting_man:{keywords:["male","boy","man"],char:'\u{1f64e}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},frowning_woman:{keywords:["female","girl","woman","sad","depressed","discouraged","unhappy"],char:'\u{1f64d}',fitzpatrick_scale:!0,category:"people"},frowning_man:{keywords:["male","boy","man","sad","depressed","discouraged","unhappy"],char:'\u{1f64d}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},haircut_woman:{keywords:["female","girl","woman"],char:'\u{1f487}',fitzpatrick_scale:!0,category:"people"},haircut_man:{keywords:["male","boy","man"],char:'\u{1f487}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},massage_woman:{keywords:["female","girl","woman","head"],char:'\u{1f486}',fitzpatrick_scale:!0,category:"people"},massage_man:{keywords:["male","boy","man","head"],char:'\u{1f486}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_in_steamy_room:{keywords:["female","woman","spa","steamroom","sauna"],char:'\u{1f9d6}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_in_steamy_room:{keywords:["male","man","spa","steamroom","sauna"],char:'\u{1f9d6}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},couple_with_heart_woman_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:'\u{1f491}',fitzpatrick_scale:!1,category:"people"},couple_with_heart_woman_woman:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:'\u{1f469}\u200d\u2764\ufe0f\u200d\u{1f469}',fitzpatrick_scale:!1,category:"people"},couple_with_heart_man_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:'\u{1f468}\u200d\u2764\ufe0f\u200d\u{1f468}',fitzpatrick_scale:!1,category:"people"},couplekiss_man_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:'\u{1f48f}',fitzpatrick_scale:!1,category:"people"},couplekiss_woman_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:'\u{1f469}\u200d\u2764\ufe0f\u200d\u{1f48b}\u200d\u{1f469}',fitzpatrick_scale:!1,category:"people"},couplekiss_man_man:{keywords:["pair","valentines","love","like","dating","marriage"],char:'\u{1f468}\u200d\u2764\ufe0f\u200d\u{1f48b}\u200d\u{1f468}',fitzpatrick_scale:!1,category:"people"},family_man_woman_boy:{keywords:["home","parents","child","mom","dad","father","mother","people","human"],char:'\u{1f46a}',fitzpatrick_scale:!1,category:"people"},family_man_woman_girl:{keywords:["home","parents","people","human","child"],char:'\u{1f468}\u200d\u{1f469}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},family_man_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:'\u{1f468}\u200d\u{1f469}\u200d\u{1f467}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_man_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:'\u{1f468}\u200d\u{1f469}\u200d\u{1f466}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_man_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:'\u{1f468}\u200d\u{1f469}\u200d\u{1f467}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},family_woman_woman_boy:{keywords:["home","parents","people","human","children"],char:'\u{1f469}\u200d\u{1f469}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl:{keywords:["home","parents","people","human","children"],char:'\u{1f469}\u200d\u{1f469}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:'\u{1f469}\u200d\u{1f469}\u200d\u{1f467}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_woman_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:'\u{1f469}\u200d\u{1f469}\u200d\u{1f466}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:'\u{1f469}\u200d\u{1f469}\u200d\u{1f467}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},family_man_man_boy:{keywords:["home","parents","people","human","children"],char:'\u{1f468}\u200d\u{1f468}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_man_man_girl:{keywords:["home","parents","people","human","children"],char:'\u{1f468}\u200d\u{1f468}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},family_man_man_girl_boy:{keywords:["home","parents","people","human","children"],char:'\u{1f468}\u200d\u{1f468}\u200d\u{1f467}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_man_man_boy_boy:{keywords:["home","parents","people","human","children"],char:'\u{1f468}\u200d\u{1f468}\u200d\u{1f466}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_man_man_girl_girl:{keywords:["home","parents","people","human","children"],char:'\u{1f468}\u200d\u{1f468}\u200d\u{1f467}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},family_woman_boy:{keywords:["home","parent","people","human","child"],char:'\u{1f469}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_woman_girl:{keywords:["home","parent","people","human","child"],char:'\u{1f469}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},family_woman_girl_boy:{keywords:["home","parent","people","human","children"],char:'\u{1f469}\u200d\u{1f467}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_woman_boy_boy:{keywords:["home","parent","people","human","children"],char:'\u{1f469}\u200d\u{1f466}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_woman_girl_girl:{keywords:["home","parent","people","human","children"],char:'\u{1f469}\u200d\u{1f467}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},family_man_boy:{keywords:["home","parent","people","human","child"],char:'\u{1f468}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_man_girl:{keywords:["home","parent","people","human","child"],char:'\u{1f468}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},family_man_girl_boy:{keywords:["home","parent","people","human","children"],char:'\u{1f468}\u200d\u{1f467}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_man_boy_boy:{keywords:["home","parent","people","human","children"],char:'\u{1f468}\u200d\u{1f466}\u200d\u{1f466}',fitzpatrick_scale:!1,category:"people"},family_man_girl_girl:{keywords:["home","parent","people","human","children"],char:'\u{1f468}\u200d\u{1f467}\u200d\u{1f467}',fitzpatrick_scale:!1,category:"people"},yarn:{keywords:["ball","crochet","knit"],char:'\u{1f9f6}',fitzpatrick_scale:!1,category:"people"},thread:{keywords:["needle","sewing","spool","string"],char:'\u{1f9f5}',fitzpatrick_scale:!1,category:"people"},coat:{keywords:["jacket"],char:'\u{1f9e5}',fitzpatrick_scale:!1,category:"people"},labcoat:{keywords:["doctor","experiment","scientist","chemist"],char:'\u{1f97c}',fitzpatrick_scale:!1,category:"people"},womans_clothes:{keywords:["fashion","shopping_bags","female"],char:'\u{1f45a}',fitzpatrick_scale:!1,category:"people"},tshirt:{keywords:["fashion","cloth","casual","shirt","tee"],char:'\u{1f455}',fitzpatrick_scale:!1,category:"people"},jeans:{keywords:["fashion","shopping"],char:'\u{1f456}',fitzpatrick_scale:!1,category:"people"},necktie:{keywords:["shirt","suitup","formal","fashion","cloth","business"],char:'\u{1f454}',fitzpatrick_scale:!1,category:"people"},dress:{keywords:["clothes","fashion","shopping"],char:'\u{1f457}',fitzpatrick_scale:!1,category:"people"},bikini:{keywords:["swimming","female","woman","girl","fashion","beach","summer"],char:'\u{1f459}',fitzpatrick_scale:!1,category:"people"},kimono:{keywords:["dress","fashion","women","female","japanese"],char:'\u{1f458}',fitzpatrick_scale:!1,category:"people"},lipstick:{keywords:["female","girl","fashion","woman"],char:'\u{1f484}',fitzpatrick_scale:!1,category:"people"},kiss:{keywords:["face","lips","love","like","affection","valentines"],char:'\u{1f48b}',fitzpatrick_scale:!1,category:"people"},footprints:{keywords:["feet","tracking","walking","beach"],char:'\u{1f463}',fitzpatrick_scale:!1,category:"people"},flat_shoe:{keywords:["ballet","slip-on","slipper"],char:'\u{1f97f}',fitzpatrick_scale:!1,category:"people"},high_heel:{keywords:["fashion","shoes","female","pumps","stiletto"],char:'\u{1f460}',fitzpatrick_scale:!1,category:"people"},sandal:{keywords:["shoes","fashion","flip flops"],char:'\u{1f461}',fitzpatrick_scale:!1,category:"people"},boot:{keywords:["shoes","fashion"],char:'\u{1f462}',fitzpatrick_scale:!1,category:"people"},mans_shoe:{keywords:["fashion","male"],char:'\u{1f45e}',fitzpatrick_scale:!1,category:"people"},athletic_shoe:{keywords:["shoes","sports","sneakers"],char:'\u{1f45f}',fitzpatrick_scale:!1,category:"people"},hiking_boot:{keywords:["backpacking","camping","hiking"],char:'\u{1f97e}',fitzpatrick_scale:!1,category:"people"},socks:{keywords:["stockings","clothes"],char:'\u{1f9e6}',fitzpatrick_scale:!1,category:"people"},gloves:{keywords:["hands","winter","clothes"],char:'\u{1f9e4}',fitzpatrick_scale:!1,category:"people"},scarf:{keywords:["neck","winter","clothes"],char:'\u{1f9e3}',fitzpatrick_scale:!1,category:"people"},womans_hat:{keywords:["fashion","accessories","female","lady","spring"],char:'\u{1f452}',fitzpatrick_scale:!1,category:"people"},tophat:{keywords:["magic","gentleman","classy","circus"],char:'\u{1f3a9}',fitzpatrick_scale:!1,category:"people"},billed_hat:{keywords:["cap","baseball"],char:'\u{1f9e2}',fitzpatrick_scale:!1,category:"people"},rescue_worker_helmet:{keywords:["construction","build"],char:'\u26d1',fitzpatrick_scale:!1,category:"people"},mortar_board:{keywords:["school","college","degree","university","graduation","cap","hat","legal","learn","education"],char:'\u{1f393}',fitzpatrick_scale:!1,category:"people"},crown:{keywords:["king","kod","leader","royalty","lord"],char:'\u{1f451}',fitzpatrick_scale:!1,category:"people"},school_satchel:{keywords:["student","education","bag","backpack"],char:'\u{1f392}',fitzpatrick_scale:!1,category:"people"},luggage:{keywords:["packing","travel"],char:'\u{1f9f3}',fitzpatrick_scale:!1,category:"people"},pouch:{keywords:["bag","accessories","shopping"],char:'\u{1f45d}',fitzpatrick_scale:!1,category:"people"},purse:{keywords:["fashion","accessories","money","sales","shopping"],char:'\u{1f45b}',fitzpatrick_scale:!1,category:"people"},handbag:{keywords:["fashion","accessory","accessories","shopping"],char:'\u{1f45c}',fitzpatrick_scale:!1,category:"people"},briefcase:{keywords:["business","documents","work","law","legal","job","career"],char:'\u{1f4bc}',fitzpatrick_scale:!1,category:"people"},eyeglasses:{keywords:["fashion","accessories","eyesight","nerdy","dork","geek"],char:'\u{1f453}',fitzpatrick_scale:!1,category:"people"},dark_sunglasses:{keywords:["face","cool","accessories"],char:'\u{1f576}',fitzpatrick_scale:!1,category:"people"},goggles:{keywords:["eyes","protection","safety"],char:'\u{1f97d}',fitzpatrick_scale:!1,category:"people"},ring:{keywords:["wedding","propose","marriage","valentines","diamond","fashion","jewelry","gem","engagement"],char:'\u{1f48d}',fitzpatrick_scale:!1,category:"people"},closed_umbrella:{keywords:["weather","rain","drizzle"],char:'\u{1f302}',fitzpatrick_scale:!1,category:"people"},dog:{keywords:["animal","friend","nature","woof","puppy","pet","faithful"],char:'\u{1f436}',fitzpatrick_scale:!1,category:"animals_and_nature"},cat:{keywords:["animal","meow","nature","pet","kitten"],char:'\u{1f431}',fitzpatrick_scale:!1,category:"animals_and_nature"},mouse:{keywords:["animal","nature","cheese_wedge","rodent"],char:'\u{1f42d}',fitzpatrick_scale:!1,category:"animals_and_nature"},hamster:{keywords:["animal","nature"],char:'\u{1f439}',fitzpatrick_scale:!1,category:"animals_and_nature"},rabbit:{keywords:["animal","nature","pet","spring","magic","bunny"],char:'\u{1f430}',fitzpatrick_scale:!1,category:"animals_and_nature"},fox_face:{keywords:["animal","nature","face"],char:'\u{1f98a}',fitzpatrick_scale:!1,category:"animals_and_nature"},bear:{keywords:["animal","nature","wild"],char:'\u{1f43b}',fitzpatrick_scale:!1,category:"animals_and_nature"},panda_face:{keywords:["animal","nature","panda"],char:'\u{1f43c}',fitzpatrick_scale:!1,category:"animals_and_nature"},koala:{keywords:["animal","nature"],char:'\u{1f428}',fitzpatrick_scale:!1,category:"animals_and_nature"},tiger:{keywords:["animal","cat","danger","wild","nature","roar"],char:'\u{1f42f}',fitzpatrick_scale:!1,category:"animals_and_nature"},lion:{keywords:["animal","nature"],char:'\u{1f981}',fitzpatrick_scale:!1,category:"animals_and_nature"},cow:{keywords:["beef","ox","animal","nature","moo","milk"],char:'\u{1f42e}',fitzpatrick_scale:!1,category:"animals_and_nature"},pig:{keywords:["animal","oink","nature"],char:'\u{1f437}',fitzpatrick_scale:!1,category:"animals_and_nature"},pig_nose:{keywords:["animal","oink"],char:'\u{1f43d}',fitzpatrick_scale:!1,category:"animals_and_nature"},frog:{keywords:["animal","nature","croak","toad"],char:'\u{1f438}',fitzpatrick_scale:!1,category:"animals_and_nature"},squid:{keywords:["animal","nature","ocean","sea"],char:'\u{1f991}',fitzpatrick_scale:!1,category:"animals_and_nature"},octopus:{keywords:["animal","creature","ocean","sea","nature","beach"],char:'\u{1f419}',fitzpatrick_scale:!1,category:"animals_and_nature"},shrimp:{keywords:["animal","ocean","nature","seafood"],char:'\u{1f990}',fitzpatrick_scale:!1,category:"animals_and_nature"},monkey_face:{keywords:["animal","nature","circus"],char:'\u{1f435}',fitzpatrick_scale:!1,category:"animals_and_nature"},gorilla:{keywords:["animal","nature","circus"],char:'\u{1f98d}',fitzpatrick_scale:!1,category:"animals_and_nature"},see_no_evil:{keywords:["monkey","animal","nature","haha"],char:'\u{1f648}',fitzpatrick_scale:!1,category:"animals_and_nature"},hear_no_evil:{keywords:["animal","monkey","nature"],char:'\u{1f649}',fitzpatrick_scale:!1,category:"animals_and_nature"},speak_no_evil:{keywords:["monkey","animal","nature","omg"],char:'\u{1f64a}',fitzpatrick_scale:!1,category:"animals_and_nature"},monkey:{keywords:["animal","nature","banana","circus"],char:'\u{1f412}',fitzpatrick_scale:!1,category:"animals_and_nature"},chicken:{keywords:["animal","cluck","nature","bird"],char:'\u{1f414}',fitzpatrick_scale:!1,category:"animals_and_nature"},penguin:{keywords:["animal","nature"],char:'\u{1f427}',fitzpatrick_scale:!1,category:"animals_and_nature"},bird:{keywords:["animal","nature","fly","tweet","spring"],char:'\u{1f426}',fitzpatrick_scale:!1,category:"animals_and_nature"},baby_chick:{keywords:["animal","chicken","bird"],char:'\u{1f424}',fitzpatrick_scale:!1,category:"animals_and_nature"},hatching_chick:{keywords:["animal","chicken","egg","born","baby","bird"],char:'\u{1f423}',fitzpatrick_scale:!1,category:"animals_and_nature"},hatched_chick:{keywords:["animal","chicken","baby","bird"],char:'\u{1f425}',fitzpatrick_scale:!1,category:"animals_and_nature"},duck:{keywords:["animal","nature","bird","mallard"],char:'\u{1f986}',fitzpatrick_scale:!1,category:"animals_and_nature"},eagle:{keywords:["animal","nature","bird"],char:'\u{1f985}',fitzpatrick_scale:!1,category:"animals_and_nature"},owl:{keywords:["animal","nature","bird","hoot"],char:'\u{1f989}',fitzpatrick_scale:!1,category:"animals_and_nature"},bat:{keywords:["animal","nature","blind","vampire"],char:'\u{1f987}',fitzpatrick_scale:!1,category:"animals_and_nature"},wolf:{keywords:["animal","nature","wild"],char:'\u{1f43a}',fitzpatrick_scale:!1,category:"animals_and_nature"},boar:{keywords:["animal","nature"],char:'\u{1f417}',fitzpatrick_scale:!1,category:"animals_and_nature"},horse:{keywords:["animal","brown","nature"],char:'\u{1f434}',fitzpatrick_scale:!1,category:"animals_and_nature"},unicorn:{keywords:["animal","nature","mystical"],char:'\u{1f984}',fitzpatrick_scale:!1,category:"animals_and_nature"},honeybee:{keywords:["animal","insect","nature","bug","spring","honey"],char:'\u{1f41d}',fitzpatrick_scale:!1,category:"animals_and_nature"},bug:{keywords:["animal","insect","nature","worm"],char:'\u{1f41b}',fitzpatrick_scale:!1,category:"animals_and_nature"},butterfly:{keywords:["animal","insect","nature","caterpillar"],char:'\u{1f98b}',fitzpatrick_scale:!1,category:"animals_and_nature"},snail:{keywords:["slow","animal","shell"],char:'\u{1f40c}',fitzpatrick_scale:!1,category:"animals_and_nature"},beetle:{keywords:["animal","insect","nature","ladybug"],char:'\u{1f41e}',fitzpatrick_scale:!1,category:"animals_and_nature"},ant:{keywords:["animal","insect","nature","bug"],char:'\u{1f41c}',fitzpatrick_scale:!1,category:"animals_and_nature"},grasshopper:{keywords:["animal","cricket","chirp"],char:'\u{1f997}',fitzpatrick_scale:!1,category:"animals_and_nature"},spider:{keywords:["animal","arachnid"],char:'\u{1f577}',fitzpatrick_scale:!1,category:"animals_and_nature"},scorpion:{keywords:["animal","arachnid"],char:'\u{1f982}',fitzpatrick_scale:!1,category:"animals_and_nature"},crab:{keywords:["animal","crustacean"],char:'\u{1f980}',fitzpatrick_scale:!1,category:"animals_and_nature"},snake:{keywords:["animal","evil","nature","hiss","python"],char:'\u{1f40d}',fitzpatrick_scale:!1,category:"animals_and_nature"},lizard:{keywords:["animal","nature","reptile"],char:'\u{1f98e}',fitzpatrick_scale:!1,category:"animals_and_nature"},"t-rex":{keywords:["animal","nature","dinosaur","tyrannosaurus","extinct"],char:'\u{1f996}',fitzpatrick_scale:!1,category:"animals_and_nature"},sauropod:{keywords:["animal","nature","dinosaur","brachiosaurus","brontosaurus","diplodocus","extinct"],char:'\u{1f995}',fitzpatrick_scale:!1,category:"animals_and_nature"},turtle:{keywords:["animal","slow","nature","tortoise"],char:'\u{1f422}',fitzpatrick_scale:!1,category:"animals_and_nature"},tropical_fish:{keywords:["animal","swim","ocean","beach","nemo"],char:'\u{1f420}',fitzpatrick_scale:!1,category:"animals_and_nature"},fish:{keywords:["animal","food","nature"],char:'\u{1f41f}',fitzpatrick_scale:!1,category:"animals_and_nature"},blowfish:{keywords:["animal","nature","food","sea","ocean"],char:'\u{1f421}',fitzpatrick_scale:!1,category:"animals_and_nature"},dolphin:{keywords:["animal","nature","fish","sea","ocean","flipper","fins","beach"],char:'\u{1f42c}',fitzpatrick_scale:!1,category:"animals_and_nature"},shark:{keywords:["animal","nature","fish","sea","ocean","jaws","fins","beach"],char:'\u{1f988}',fitzpatrick_scale:!1,category:"animals_and_nature"},whale:{keywords:["animal","nature","sea","ocean"],char:'\u{1f433}',fitzpatrick_scale:!1,category:"animals_and_nature"},whale2:{keywords:["animal","nature","sea","ocean"],char:'\u{1f40b}',fitzpatrick_scale:!1,category:"animals_and_nature"},crocodile:{keywords:["animal","nature","reptile","lizard","alligator"],char:'\u{1f40a}',fitzpatrick_scale:!1,category:"animals_and_nature"},leopard:{keywords:["animal","nature"],char:'\u{1f406}',fitzpatrick_scale:!1,category:"animals_and_nature"},zebra:{keywords:["animal","nature","stripes","safari"],char:'\u{1f993}',fitzpatrick_scale:!1,category:"animals_and_nature"},tiger2:{keywords:["animal","nature","roar"],char:'\u{1f405}',fitzpatrick_scale:!1,category:"animals_and_nature"},water_buffalo:{keywords:["animal","nature","ox","cow"],char:'\u{1f403}',fitzpatrick_scale:!1,category:"animals_and_nature"},ox:{keywords:["animal","cow","beef"],char:'\u{1f402}',fitzpatrick_scale:!1,category:"animals_and_nature"},cow2:{keywords:["beef","ox","animal","nature","moo","milk"],char:'\u{1f404}',fitzpatrick_scale:!1,category:"animals_and_nature"},deer:{keywords:["animal","nature","horns","venison"],char:'\u{1f98c}',fitzpatrick_scale:!1,category:"animals_and_nature"},dromedary_camel:{keywords:["animal","hot","desert","hump"],char:'\u{1f42a}',fitzpatrick_scale:!1,category:"animals_and_nature"},camel:{keywords:["animal","nature","hot","desert","hump"],char:'\u{1f42b}',fitzpatrick_scale:!1,category:"animals_and_nature"},giraffe:{keywords:["animal","nature","spots","safari"],char:'\u{1f992}',fitzpatrick_scale:!1,category:"animals_and_nature"},elephant:{keywords:["animal","nature","nose","th","circus"],char:'\u{1f418}',fitzpatrick_scale:!1,category:"animals_and_nature"},rhinoceros:{keywords:["animal","nature","horn"],char:'\u{1f98f}',fitzpatrick_scale:!1,category:"animals_and_nature"},goat:{keywords:["animal","nature"],char:'\u{1f410}',fitzpatrick_scale:!1,category:"animals_and_nature"},ram:{keywords:["animal","sheep","nature"],char:'\u{1f40f}',fitzpatrick_scale:!1,category:"animals_and_nature"},sheep:{keywords:["animal","nature","wool","shipit"],char:'\u{1f411}',fitzpatrick_scale:!1,category:"animals_and_nature"},racehorse:{keywords:["animal","gamble","luck"],char:'\u{1f40e}',fitzpatrick_scale:!1,category:"animals_and_nature"},pig2:{keywords:["animal","nature"],char:'\u{1f416}',fitzpatrick_scale:!1,category:"animals_and_nature"},rat:{keywords:["animal","mouse","rodent"],char:'\u{1f400}',fitzpatrick_scale:!1,category:"animals_and_nature"},mouse2:{keywords:["animal","nature","rodent"],char:'\u{1f401}',fitzpatrick_scale:!1,category:"animals_and_nature"},rooster:{keywords:["animal","nature","chicken"],char:'\u{1f413}',fitzpatrick_scale:!1,category:"animals_and_nature"},turkey:{keywords:["animal","bird"],char:'\u{1f983}',fitzpatrick_scale:!1,category:"animals_and_nature"},dove:{keywords:["animal","bird"],char:'\u{1f54a}',fitzpatrick_scale:!1,category:"animals_and_nature"},dog2:{keywords:["animal","nature","friend","doge","pet","faithful"],char:'\u{1f415}',fitzpatrick_scale:!1,category:"animals_and_nature"},poodle:{keywords:["dog","animal","101","nature","pet"],char:'\u{1f429}',fitzpatrick_scale:!1,category:"animals_and_nature"},cat2:{keywords:["animal","meow","pet","cats"],char:'\u{1f408}',fitzpatrick_scale:!1,category:"animals_and_nature"},rabbit2:{keywords:["animal","nature","pet","magic","spring"],char:'\u{1f407}',fitzpatrick_scale:!1,category:"animals_and_nature"},chipmunk:{keywords:["animal","nature","rodent","squirrel"],char:'\u{1f43f}',fitzpatrick_scale:!1,category:"animals_and_nature"},hedgehog:{keywords:["animal","nature","spiny"],char:'\u{1f994}',fitzpatrick_scale:!1,category:"animals_and_nature"},raccoon:{keywords:["animal","nature"],char:'\u{1f99d}',fitzpatrick_scale:!1,category:"animals_and_nature"},llama:{keywords:["animal","nature","alpaca"],char:'\u{1f999}',fitzpatrick_scale:!1,category:"animals_and_nature"},hippopotamus:{keywords:["animal","nature"],char:'\u{1f99b}',fitzpatrick_scale:!1,category:"animals_and_nature"},kangaroo:{keywords:["animal","nature","australia","joey","hop","marsupial"],char:'\u{1f998}',fitzpatrick_scale:!1,category:"animals_and_nature"},badger:{keywords:["animal","nature","honey"],char:'\u{1f9a1}',fitzpatrick_scale:!1,category:"animals_and_nature"},swan:{keywords:["animal","nature","bird"],char:'\u{1f9a2}',fitzpatrick_scale:!1,category:"animals_and_nature"},peacock:{keywords:["animal","nature","peahen","bird"],char:'\u{1f99a}',fitzpatrick_scale:!1,category:"animals_and_nature"},parrot:{keywords:["animal","nature","bird","pirate","talk"],char:'\u{1f99c}',fitzpatrick_scale:!1,category:"animals_and_nature"},lobster:{keywords:["animal","nature","bisque","claws","seafood"],char:'\u{1f99e}',fitzpatrick_scale:!1,category:"animals_and_nature"},mosquito:{keywords:["animal","nature","insect","malaria"],char:'\u{1f99f}',fitzpatrick_scale:!1,category:"animals_and_nature"},paw_prints:{keywords:["animal","tracking","footprints","dog","cat","pet","feet"],char:'\u{1f43e}',fitzpatrick_scale:!1,category:"animals_and_nature"},dragon:{keywords:["animal","myth","nature","chinese","green"],char:'\u{1f409}',fitzpatrick_scale:!1,category:"animals_and_nature"},dragon_face:{keywords:["animal","myth","nature","chinese","green"],char:'\u{1f432}',fitzpatrick_scale:!1,category:"animals_and_nature"},cactus:{keywords:["vegetable","plant","nature"],char:'\u{1f335}',fitzpatrick_scale:!1,category:"animals_and_nature"},christmas_tree:{keywords:["festival","vacation","december","xmas","celebration"],char:'\u{1f384}',fitzpatrick_scale:!1,category:"animals_and_nature"},evergreen_tree:{keywords:["plant","nature"],char:'\u{1f332}',fitzpatrick_scale:!1,category:"animals_and_nature"},deciduous_tree:{keywords:["plant","nature"],char:'\u{1f333}',fitzpatrick_scale:!1,category:"animals_and_nature"},palm_tree:{keywords:["plant","vegetable","nature","summer","beach","mojito","tropical"],char:'\u{1f334}',fitzpatrick_scale:!1,category:"animals_and_nature"},seedling:{keywords:["plant","nature","grass","lawn","spring"],char:'\u{1f331}',fitzpatrick_scale:!1,category:"animals_and_nature"},herb:{keywords:["vegetable","plant","medicine","weed","grass","lawn"],char:'\u{1f33f}',fitzpatrick_scale:!1,category:"animals_and_nature"},shamrock:{keywords:["vegetable","plant","nature","irish","clover"],char:'\u2618',fitzpatrick_scale:!1,category:"animals_and_nature"},four_leaf_clover:{keywords:["vegetable","plant","nature","lucky","irish"],char:'\u{1f340}',fitzpatrick_scale:!1,category:"animals_and_nature"},bamboo:{keywords:["plant","nature","vegetable","panda","pine_decoration"],char:'\u{1f38d}',fitzpatrick_scale:!1,category:"animals_and_nature"},tanabata_tree:{keywords:["plant","nature","branch","summer"],char:'\u{1f38b}',fitzpatrick_scale:!1,category:"animals_and_nature"},leaves:{keywords:["nature","plant","tree","vegetable","grass","lawn","spring"],char:'\u{1f343}',fitzpatrick_scale:!1,category:"animals_and_nature"},fallen_leaf:{keywords:["nature","plant","vegetable","leaves"],char:'\u{1f342}',fitzpatrick_scale:!1,category:"animals_and_nature"},maple_leaf:{keywords:["nature","plant","vegetable","ca","fall"],char:'\u{1f341}',fitzpatrick_scale:!1,category:"animals_and_nature"},ear_of_rice:{keywords:["nature","plant"],char:'\u{1f33e}',fitzpatrick_scale:!1,category:"animals_and_nature"},hibiscus:{keywords:["plant","vegetable","flowers","beach"],char:'\u{1f33a}',fitzpatrick_scale:!1,category:"animals_and_nature"},sunflower:{keywords:["nature","plant","fall"],char:'\u{1f33b}',fitzpatrick_scale:!1,category:"animals_and_nature"},rose:{keywords:["flowers","valentines","love","spring"],char:'\u{1f339}',fitzpatrick_scale:!1,category:"animals_and_nature"},wilted_flower:{keywords:["plant","nature","flower"],char:'\u{1f940}',fitzpatrick_scale:!1,category:"animals_and_nature"},tulip:{keywords:["flowers","plant","nature","summer","spring"],char:'\u{1f337}',fitzpatrick_scale:!1,category:"animals_and_nature"},blossom:{keywords:["nature","flowers","yellow"],char:'\u{1f33c}',fitzpatrick_scale:!1,category:"animals_and_nature"},cherry_blossom:{keywords:["nature","plant","spring","flower"],char:'\u{1f338}',fitzpatrick_scale:!1,category:"animals_and_nature"},bouquet:{keywords:["flowers","nature","spring"],char:'\u{1f490}',fitzpatrick_scale:!1,category:"animals_and_nature"},mushroom:{keywords:["plant","vegetable"],char:'\u{1f344}',fitzpatrick_scale:!1,category:"animals_and_nature"},chestnut:{keywords:["food","squirrel"],char:'\u{1f330}',fitzpatrick_scale:!1,category:"animals_and_nature"},jack_o_lantern:{keywords:["halloween","light","pumpkin","creepy","fall"],char:'\u{1f383}',fitzpatrick_scale:!1,category:"animals_and_nature"},shell:{keywords:["nature","sea","beach"],char:'\u{1f41a}',fitzpatrick_scale:!1,category:"animals_and_nature"},spider_web:{keywords:["animal","insect","arachnid","silk"],char:'\u{1f578}',fitzpatrick_scale:!1,category:"animals_and_nature"},earth_americas:{keywords:["globe","world","USA","international"],char:'\u{1f30e}',fitzpatrick_scale:!1,category:"animals_and_nature"},earth_africa:{keywords:["globe","world","international"],char:'\u{1f30d}',fitzpatrick_scale:!1,category:"animals_and_nature"},earth_asia:{keywords:["globe","world","east","international"],char:'\u{1f30f}',fitzpatrick_scale:!1,category:"animals_and_nature"},full_moon:{keywords:["nature","yellow","twilight","planet","space","night","evening","sleep"],char:'\u{1f315}',fitzpatrick_scale:!1,category:"animals_and_nature"},waning_gibbous_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep","waxing_gibbous_moon"],char:'\u{1f316}',fitzpatrick_scale:!1,category:"animals_and_nature"},last_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\u{1f317}',fitzpatrick_scale:!1,category:"animals_and_nature"},waning_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\u{1f318}',fitzpatrick_scale:!1,category:"animals_and_nature"},new_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\u{1f311}',fitzpatrick_scale:!1,category:"animals_and_nature"},waxing_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\u{1f312}',fitzpatrick_scale:!1,category:"animals_and_nature"},first_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\u{1f313}',fitzpatrick_scale:!1,category:"animals_and_nature"},waxing_gibbous_moon:{keywords:["nature","night","sky","gray","twilight","planet","space","evening","sleep"],char:'\u{1f314}',fitzpatrick_scale:!1,category:"animals_and_nature"},new_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\u{1f31a}',fitzpatrick_scale:!1,category:"animals_and_nature"},full_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\u{1f31d}',fitzpatrick_scale:!1,category:"animals_and_nature"},first_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\u{1f31b}',fitzpatrick_scale:!1,category:"animals_and_nature"},last_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\u{1f31c}',fitzpatrick_scale:!1,category:"animals_and_nature"},sun_with_face:{keywords:["nature","morning","sky"],char:'\u{1f31e}',fitzpatrick_scale:!1,category:"animals_and_nature"},crescent_moon:{keywords:["night","sleep","sky","evening","magic"],char:'\u{1f319}',fitzpatrick_scale:!1,category:"animals_and_nature"},star:{keywords:["night","yellow"],char:'\u2b50',fitzpatrick_scale:!1,category:"animals_and_nature"},star2:{keywords:["night","sparkle","awesome","good","magic"],char:'\u{1f31f}',fitzpatrick_scale:!1,category:"animals_and_nature"},dizzy:{keywords:["star","sparkle","shoot","magic"],char:'\u{1f4ab}',fitzpatrick_scale:!1,category:"animals_and_nature"},sparkles:{keywords:["stars","shine","shiny","cool","awesome","good","magic"],char:'\u2728',fitzpatrick_scale:!1,category:"animals_and_nature"},comet:{keywords:["space"],char:'\u2604',fitzpatrick_scale:!1,category:"animals_and_nature"},sunny:{keywords:["weather","nature","brightness","summer","beach","spring"],char:'\u2600\ufe0f',fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_small_cloud:{keywords:["weather"],char:'\u{1f324}',fitzpatrick_scale:!1,category:"animals_and_nature"},partly_sunny:{keywords:["weather","nature","cloudy","morning","fall","spring"],char:'\u26c5',fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_large_cloud:{keywords:["weather"],char:'\u{1f325}',fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_rain_cloud:{keywords:["weather"],char:'\u{1f326}',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud:{keywords:["weather","sky"],char:'\u2601\ufe0f',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_rain:{keywords:["weather"],char:'\u{1f327}',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_lightning_and_rain:{keywords:["weather","lightning"],char:'\u26c8',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_lightning:{keywords:["weather","thunder"],char:'\u{1f329}',fitzpatrick_scale:!1,category:"animals_and_nature"},zap:{keywords:["thunder","weather","lightning bolt","fast"],char:'\u26a1',fitzpatrick_scale:!1,category:"animals_and_nature"},fire:{keywords:["hot","cook","flame"],char:'\u{1f525}',fitzpatrick_scale:!1,category:"animals_and_nature"},boom:{keywords:["bomb","explode","explosion","collision","blown"],char:'\u{1f4a5}',fitzpatrick_scale:!1,category:"animals_and_nature"},snowflake:{keywords:["winter","season","cold","weather","christmas","xmas"],char:'\u2744\ufe0f',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_snow:{keywords:["weather"],char:'\u{1f328}',fitzpatrick_scale:!1,category:"animals_and_nature"},snowman:{keywords:["winter","season","cold","weather","christmas","xmas","frozen","without_snow"],char:'\u26c4',fitzpatrick_scale:!1,category:"animals_and_nature"},snowman_with_snow:{keywords:["winter","season","cold","weather","christmas","xmas","frozen"],char:'\u2603',fitzpatrick_scale:!1,category:"animals_and_nature"},wind_face:{keywords:["gust","air"],char:'\u{1f32c}',fitzpatrick_scale:!1,category:"animals_and_nature"},dash:{keywords:["wind","air","fast","shoo","fart","smoke","puff"],char:'\u{1f4a8}',fitzpatrick_scale:!1,category:"animals_and_nature"},tornado:{keywords:["weather","cyclone","twister"],char:'\u{1f32a}',fitzpatrick_scale:!1,category:"animals_and_nature"},fog:{keywords:["weather"],char:'\u{1f32b}',fitzpatrick_scale:!1,category:"animals_and_nature"},open_umbrella:{keywords:["weather","spring"],char:'\u2602',fitzpatrick_scale:!1,category:"animals_and_nature"},umbrella:{keywords:["rainy","weather","spring"],char:'\u2614',fitzpatrick_scale:!1,category:"animals_and_nature"},droplet:{keywords:["water","drip","faucet","spring"],char:'\u{1f4a7}',fitzpatrick_scale:!1,category:"animals_and_nature"},sweat_drops:{keywords:["water","drip","oops"],char:'\u{1f4a6}',fitzpatrick_scale:!1,category:"animals_and_nature"},ocean:{keywords:["sea","water","wave","nature","tsunami","disaster"],char:'\u{1f30a}',fitzpatrick_scale:!1,category:"animals_and_nature"},green_apple:{keywords:["fruit","nature"],char:'\u{1f34f}',fitzpatrick_scale:!1,category:"food_and_drink"},apple:{keywords:["fruit","mac","school"],char:'\u{1f34e}',fitzpatrick_scale:!1,category:"food_and_drink"},pear:{keywords:["fruit","nature","food"],char:'\u{1f350}',fitzpatrick_scale:!1,category:"food_and_drink"},tangerine:{keywords:["food","fruit","nature","orange"],char:'\u{1f34a}',fitzpatrick_scale:!1,category:"food_and_drink"},lemon:{keywords:["fruit","nature"],char:'\u{1f34b}',fitzpatrick_scale:!1,category:"food_and_drink"},banana:{keywords:["fruit","food","monkey"],char:'\u{1f34c}',fitzpatrick_scale:!1,category:"food_and_drink"},watermelon:{keywords:["fruit","food","picnic","summer"],char:'\u{1f349}',fitzpatrick_scale:!1,category:"food_and_drink"},grapes:{keywords:["fruit","food","wine"],char:'\u{1f347}',fitzpatrick_scale:!1,category:"food_and_drink"},strawberry:{keywords:["fruit","food","nature"],char:'\u{1f353}',fitzpatrick_scale:!1,category:"food_and_drink"},melon:{keywords:["fruit","nature","food"],char:'\u{1f348}',fitzpatrick_scale:!1,category:"food_and_drink"},cherries:{keywords:["food","fruit"],char:'\u{1f352}',fitzpatrick_scale:!1,category:"food_and_drink"},peach:{keywords:["fruit","nature","food"],char:'\u{1f351}',fitzpatrick_scale:!1,category:"food_and_drink"},pineapple:{keywords:["fruit","nature","food"],char:'\u{1f34d}',fitzpatrick_scale:!1,category:"food_and_drink"},coconut:{keywords:["fruit","nature","food","palm"],char:'\u{1f965}',fitzpatrick_scale:!1,category:"food_and_drink"},kiwi_fruit:{keywords:["fruit","food"],char:'\u{1f95d}',fitzpatrick_scale:!1,category:"food_and_drink"},mango:{keywords:["fruit","food","tropical"],char:'\u{1f96d}',fitzpatrick_scale:!1,category:"food_and_drink"},avocado:{keywords:["fruit","food"],char:'\u{1f951}',fitzpatrick_scale:!1,category:"food_and_drink"},broccoli:{keywords:["fruit","food","vegetable"],char:'\u{1f966}',fitzpatrick_scale:!1,category:"food_and_drink"},tomato:{keywords:["fruit","vegetable","nature","food"],char:'\u{1f345}',fitzpatrick_scale:!1,category:"food_and_drink"},eggplant:{keywords:["vegetable","nature","food","aubergine"],char:'\u{1f346}',fitzpatrick_scale:!1,category:"food_and_drink"},cucumber:{keywords:["fruit","food","pickle"],char:'\u{1f952}',fitzpatrick_scale:!1,category:"food_and_drink"},carrot:{keywords:["vegetable","food","orange"],char:'\u{1f955}',fitzpatrick_scale:!1,category:"food_and_drink"},hot_pepper:{keywords:["food","spicy","chilli","chili"],char:'\u{1f336}',fitzpatrick_scale:!1,category:"food_and_drink"},potato:{keywords:["food","tuber","vegatable","starch"],char:'\u{1f954}',fitzpatrick_scale:!1,category:"food_and_drink"},corn:{keywords:["food","vegetable","plant"],char:'\u{1f33d}',fitzpatrick_scale:!1,category:"food_and_drink"},leafy_greens:{keywords:["food","vegetable","plant","bok choy","cabbage","kale","lettuce"],char:'\u{1f96c}',fitzpatrick_scale:!1,category:"food_and_drink"},sweet_potato:{keywords:["food","nature"],char:'\u{1f360}',fitzpatrick_scale:!1,category:"food_and_drink"},peanuts:{keywords:["food","nut"],char:'\u{1f95c}',fitzpatrick_scale:!1,category:"food_and_drink"},honey_pot:{keywords:["bees","sweet","kitchen"],char:'\u{1f36f}',fitzpatrick_scale:!1,category:"food_and_drink"},croissant:{keywords:["food","bread","french"],char:'\u{1f950}',fitzpatrick_scale:!1,category:"food_and_drink"},bread:{keywords:["food","wheat","breakfast","toast"],char:'\u{1f35e}',fitzpatrick_scale:!1,category:"food_and_drink"},baguette_bread:{keywords:["food","bread","french"],char:'\u{1f956}',fitzpatrick_scale:!1,category:"food_and_drink"},bagel:{keywords:["food","bread","bakery","schmear"],char:'\u{1f96f}',fitzpatrick_scale:!1,category:"food_and_drink"},pretzel:{keywords:["food","bread","twisted"],char:'\u{1f968}',fitzpatrick_scale:!1,category:"food_and_drink"},cheese:{keywords:["food","chadder"],char:'\u{1f9c0}',fitzpatrick_scale:!1,category:"food_and_drink"},egg:{keywords:["food","chicken","breakfast"],char:'\u{1f95a}',fitzpatrick_scale:!1,category:"food_and_drink"},bacon:{keywords:["food","breakfast","pork","pig","meat"],char:'\u{1f953}',fitzpatrick_scale:!1,category:"food_and_drink"},steak:{keywords:["food","cow","meat","cut","chop","lambchop","porkchop"],char:'\u{1f969}',fitzpatrick_scale:!1,category:"food_and_drink"},pancakes:{keywords:["food","breakfast","flapjacks","hotcakes"],char:'\u{1f95e}',fitzpatrick_scale:!1,category:"food_and_drink"},poultry_leg:{keywords:["food","meat","drumstick","bird","chicken","turkey"],char:'\u{1f357}',fitzpatrick_scale:!1,category:"food_and_drink"},meat_on_bone:{keywords:["good","food","drumstick"],char:'\u{1f356}',fitzpatrick_scale:!1,category:"food_and_drink"},bone:{keywords:["skeleton"],char:'\u{1f9b4}',fitzpatrick_scale:!1,category:"food_and_drink"},fried_shrimp:{keywords:["food","animal","appetizer","summer"],char:'\u{1f364}',fitzpatrick_scale:!1,category:"food_and_drink"},fried_egg:{keywords:["food","breakfast","kitchen","egg"],char:'\u{1f373}',fitzpatrick_scale:!1,category:"food_and_drink"},hamburger:{keywords:["meat","fast food","beef","cheeseburger","mcdonalds","burger king"],char:'\u{1f354}',fitzpatrick_scale:!1,category:"food_and_drink"},fries:{keywords:["chips","snack","fast food"],char:'\u{1f35f}',fitzpatrick_scale:!1,category:"food_and_drink"},stuffed_flatbread:{keywords:["food","flatbread","stuffed","gyro"],char:'\u{1f959}',fitzpatrick_scale:!1,category:"food_and_drink"},hotdog:{keywords:["food","frankfurter"],char:'\u{1f32d}',fitzpatrick_scale:!1,category:"food_and_drink"},pizza:{keywords:["food","party"],char:'\u{1f355}',fitzpatrick_scale:!1,category:"food_and_drink"},sandwich:{keywords:["food","lunch","bread"],char:'\u{1f96a}',fitzpatrick_scale:!1,category:"food_and_drink"},canned_food:{keywords:["food","soup"],char:'\u{1f96b}',fitzpatrick_scale:!1,category:"food_and_drink"},spaghetti:{keywords:["food","italian","noodle"],char:'\u{1f35d}',fitzpatrick_scale:!1,category:"food_and_drink"},taco:{keywords:["food","mexican"],char:'\u{1f32e}',fitzpatrick_scale:!1,category:"food_and_drink"},burrito:{keywords:["food","mexican"],char:'\u{1f32f}',fitzpatrick_scale:!1,category:"food_and_drink"},green_salad:{keywords:["food","healthy","lettuce"],char:'\u{1f957}',fitzpatrick_scale:!1,category:"food_and_drink"},shallow_pan_of_food:{keywords:["food","cooking","casserole","paella"],char:'\u{1f958}',fitzpatrick_scale:!1,category:"food_and_drink"},ramen:{keywords:["food","japanese","noodle","chopsticks"],char:'\u{1f35c}',fitzpatrick_scale:!1,category:"food_and_drink"},stew:{keywords:["food","meat","soup"],char:'\u{1f372}',fitzpatrick_scale:!1,category:"food_and_drink"},fish_cake:{keywords:["food","japan","sea","beach","narutomaki","pink","swirl","kamaboko","surimi","ramen"],char:'\u{1f365}',fitzpatrick_scale:!1,category:"food_and_drink"},fortune_cookie:{keywords:["food","prophecy"],char:'\u{1f960}',fitzpatrick_scale:!1,category:"food_and_drink"},sushi:{keywords:["food","fish","japanese","rice"],char:'\u{1f363}',fitzpatrick_scale:!1,category:"food_and_drink"},bento:{keywords:["food","japanese","box"],char:'\u{1f371}',fitzpatrick_scale:!1,category:"food_and_drink"},curry:{keywords:["food","spicy","hot","indian"],char:'\u{1f35b}',fitzpatrick_scale:!1,category:"food_and_drink"},rice_ball:{keywords:["food","japanese"],char:'\u{1f359}',fitzpatrick_scale:!1,category:"food_and_drink"},rice:{keywords:["food","china","asian"],char:'\u{1f35a}',fitzpatrick_scale:!1,category:"food_and_drink"},rice_cracker:{keywords:["food","japanese"],char:'\u{1f358}',fitzpatrick_scale:!1,category:"food_and_drink"},oden:{keywords:["food","japanese"],char:'\u{1f362}',fitzpatrick_scale:!1,category:"food_and_drink"},dango:{keywords:["food","dessert","sweet","japanese","barbecue","meat"],char:'\u{1f361}',fitzpatrick_scale:!1,category:"food_and_drink"},shaved_ice:{keywords:["hot","dessert","summer"],char:'\u{1f367}',fitzpatrick_scale:!1,category:"food_and_drink"},ice_cream:{keywords:["food","hot","dessert"],char:'\u{1f368}',fitzpatrick_scale:!1,category:"food_and_drink"},icecream:{keywords:["food","hot","dessert","summer"],char:'\u{1f366}',fitzpatrick_scale:!1,category:"food_and_drink"},pie:{keywords:["food","dessert","pastry"],char:'\u{1f967}',fitzpatrick_scale:!1,category:"food_and_drink"},cake:{keywords:["food","dessert"],char:'\u{1f370}',fitzpatrick_scale:!1,category:"food_and_drink"},cupcake:{keywords:["food","dessert","bakery","sweet"],char:'\u{1f9c1}',fitzpatrick_scale:!1,category:"food_and_drink"},moon_cake:{keywords:["food","autumn"],char:'\u{1f96e}',fitzpatrick_scale:!1,category:"food_and_drink"},birthday:{keywords:["food","dessert","cake"],char:'\u{1f382}',fitzpatrick_scale:!1,category:"food_and_drink"},custard:{keywords:["dessert","food"],char:'\u{1f36e}',fitzpatrick_scale:!1,category:"food_and_drink"},candy:{keywords:["snack","dessert","sweet","lolly"],char:'\u{1f36c}',fitzpatrick_scale:!1,category:"food_and_drink"},lollipop:{keywords:["food","snack","candy","sweet"],char:'\u{1f36d}',fitzpatrick_scale:!1,category:"food_and_drink"},chocolate_bar:{keywords:["food","snack","dessert","sweet"],char:'\u{1f36b}',fitzpatrick_scale:!1,category:"food_and_drink"},popcorn:{keywords:["food","movie theater","films","snack"],char:'\u{1f37f}',fitzpatrick_scale:!1,category:"food_and_drink"},dumpling:{keywords:["food","empanada","pierogi","potsticker"],char:'\u{1f95f}',fitzpatrick_scale:!1,category:"food_and_drink"},doughnut:{keywords:["food","dessert","snack","sweet","donut"],char:'\u{1f369}',fitzpatrick_scale:!1,category:"food_and_drink"},cookie:{keywords:["food","snack","oreo","chocolate","sweet","dessert"],char:'\u{1f36a}',fitzpatrick_scale:!1,category:"food_and_drink"},milk_glass:{keywords:["beverage","drink","cow"],char:'\u{1f95b}',fitzpatrick_scale:!1,category:"food_and_drink"},beer:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:'\u{1f37a}',fitzpatrick_scale:!1,category:"food_and_drink"},beers:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:'\u{1f37b}',fitzpatrick_scale:!1,category:"food_and_drink"},clinking_glasses:{keywords:["beverage","drink","party","alcohol","celebrate","cheers","wine","champagne","toast"],char:'\u{1f942}',fitzpatrick_scale:!1,category:"food_and_drink"},wine_glass:{keywords:["drink","beverage","drunk","alcohol","booze"],char:'\u{1f377}',fitzpatrick_scale:!1,category:"food_and_drink"},tumbler_glass:{keywords:["drink","beverage","drunk","alcohol","liquor","booze","bourbon","scotch","whisky","glass","shot"],char:'\u{1f943}',fitzpatrick_scale:!1,category:"food_and_drink"},cocktail:{keywords:["drink","drunk","alcohol","beverage","booze","mojito"],char:'\u{1f378}',fitzpatrick_scale:!1,category:"food_and_drink"},tropical_drink:{keywords:["beverage","cocktail","summer","beach","alcohol","booze","mojito"],char:'\u{1f379}',fitzpatrick_scale:!1,category:"food_and_drink"},champagne:{keywords:["drink","wine","bottle","celebration"],char:'\u{1f37e}',fitzpatrick_scale:!1,category:"food_and_drink"},sake:{keywords:["wine","drink","drunk","beverage","japanese","alcohol","booze"],char:'\u{1f376}',fitzpatrick_scale:!1,category:"food_and_drink"},tea:{keywords:["drink","bowl","breakfast","green","british"],char:'\u{1f375}',fitzpatrick_scale:!1,category:"food_and_drink"},cup_with_straw:{keywords:["drink","soda"],char:'\u{1f964}',fitzpatrick_scale:!1,category:"food_and_drink"},coffee:{keywords:["beverage","caffeine","latte","espresso"],char:'\u2615',fitzpatrick_scale:!1,category:"food_and_drink"},baby_bottle:{keywords:["food","container","milk"],char:'\u{1f37c}',fitzpatrick_scale:!1,category:"food_and_drink"},salt:{keywords:["condiment","shaker"],char:'\u{1f9c2}',fitzpatrick_scale:!1,category:"food_and_drink"},spoon:{keywords:["cutlery","kitchen","tableware"],char:'\u{1f944}',fitzpatrick_scale:!1,category:"food_and_drink"},fork_and_knife:{keywords:["cutlery","kitchen"],char:'\u{1f374}',fitzpatrick_scale:!1,category:"food_and_drink"},plate_with_cutlery:{keywords:["food","eat","meal","lunch","dinner","restaurant"],char:'\u{1f37d}',fitzpatrick_scale:!1,category:"food_and_drink"},bowl_with_spoon:{keywords:["food","breakfast","cereal","oatmeal","porridge"],char:'\u{1f963}',fitzpatrick_scale:!1,category:"food_and_drink"},takeout_box:{keywords:["food","leftovers"],char:'\u{1f961}',fitzpatrick_scale:!1,category:"food_and_drink"},chopsticks:{keywords:["food"],char:'\u{1f962}',fitzpatrick_scale:!1,category:"food_and_drink"},soccer:{keywords:["sports","football"],char:'\u26bd',fitzpatrick_scale:!1,category:"activity"},basketball:{keywords:["sports","balls","NBA"],char:'\u{1f3c0}',fitzpatrick_scale:!1,category:"activity"},football:{keywords:["sports","balls","NFL"],char:'\u{1f3c8}',fitzpatrick_scale:!1,category:"activity"},baseball:{keywords:["sports","balls"],char:'\u26be',fitzpatrick_scale:!1,category:"activity"},softball:{keywords:["sports","balls"],char:'\u{1f94e}',fitzpatrick_scale:!1,category:"activity"},tennis:{keywords:["sports","balls","green"],char:'\u{1f3be}',fitzpatrick_scale:!1,category:"activity"},volleyball:{keywords:["sports","balls"],char:'\u{1f3d0}',fitzpatrick_scale:!1,category:"activity"},rugby_football:{keywords:["sports","team"],char:'\u{1f3c9}',fitzpatrick_scale:!1,category:"activity"},flying_disc:{keywords:["sports","frisbee","ultimate"],char:'\u{1f94f}',fitzpatrick_scale:!1,category:"activity"},"8ball":{keywords:["pool","hobby","game","luck","magic"],char:'\u{1f3b1}',fitzpatrick_scale:!1,category:"activity"},golf:{keywords:["sports","business","flag","hole","summer"],char:'\u26f3',fitzpatrick_scale:!1,category:"activity"},golfing_woman:{keywords:["sports","business","woman","female"],char:'\u{1f3cc}\ufe0f\u200d\u2640\ufe0f',fitzpatrick_scale:!1,category:"activity"},golfing_man:{keywords:["sports","business"],char:'\u{1f3cc}',fitzpatrick_scale:!0,category:"activity"},ping_pong:{keywords:["sports","pingpong"],char:'\u{1f3d3}',fitzpatrick_scale:!1,category:"activity"},badminton:{keywords:["sports"],char:'\u{1f3f8}',fitzpatrick_scale:!1,category:"activity"},goal_net:{keywords:["sports"],char:'\u{1f945}',fitzpatrick_scale:!1,category:"activity"},ice_hockey:{keywords:["sports"],char:'\u{1f3d2}',fitzpatrick_scale:!1,category:"activity"},field_hockey:{keywords:["sports"],char:'\u{1f3d1}',fitzpatrick_scale:!1,category:"activity"},lacrosse:{keywords:["sports","ball","stick"],char:'\u{1f94d}',fitzpatrick_scale:!1,category:"activity"},cricket:{keywords:["sports"],char:'\u{1f3cf}',fitzpatrick_scale:!1,category:"activity"},ski:{keywords:["sports","winter","cold","snow"],char:'\u{1f3bf}',fitzpatrick_scale:!1,category:"activity"},skier:{keywords:["sports","winter","snow"],char:'\u26f7',fitzpatrick_scale:!1,category:"activity"},snowboarder:{keywords:["sports","winter"],char:'\u{1f3c2}',fitzpatrick_scale:!0,category:"activity"},person_fencing:{keywords:["sports","fencing","sword"],char:'\u{1f93a}',fitzpatrick_scale:!1,category:"activity"},women_wrestling:{keywords:["sports","wrestlers"],char:'\u{1f93c}\u200d\u2640\ufe0f',fitzpatrick_scale:!1,category:"activity"},men_wrestling:{keywords:["sports","wrestlers"],char:'\u{1f93c}\u200d\u2642\ufe0f',fitzpatrick_scale:!1,category:"activity"},woman_cartwheeling:{keywords:["gymnastics"],char:'\u{1f938}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_cartwheeling:{keywords:["gymnastics"],char:'\u{1f938}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},woman_playing_handball:{keywords:["sports"],char:'\u{1f93e}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_playing_handball:{keywords:["sports"],char:'\u{1f93e}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},ice_skate:{keywords:["sports"],char:'\u26f8',fitzpatrick_scale:!1,category:"activity"},curling_stone:{keywords:["sports"],char:'\u{1f94c}',fitzpatrick_scale:!1,category:"activity"},skateboard:{keywords:["board"],char:'\u{1f6f9}',fitzpatrick_scale:!1,category:"activity"},sled:{keywords:["sleigh","luge","toboggan"],char:'\u{1f6f7}',fitzpatrick_scale:!1,category:"activity"},bow_and_arrow:{keywords:["sports"],char:'\u{1f3f9}',fitzpatrick_scale:!1,category:"activity"},fishing_pole_and_fish:{keywords:["food","hobby","summer"],char:'\u{1f3a3}',fitzpatrick_scale:!1,category:"activity"},boxing_glove:{keywords:["sports","fighting"],char:'\u{1f94a}',fitzpatrick_scale:!1,category:"activity"},martial_arts_uniform:{keywords:["judo","karate","taekwondo"],char:'\u{1f94b}',fitzpatrick_scale:!1,category:"activity"},rowing_woman:{keywords:["sports","hobby","water","ship","woman","female"],char:'\u{1f6a3}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},rowing_man:{keywords:["sports","hobby","water","ship"],char:'\u{1f6a3}',fitzpatrick_scale:!0,category:"activity"},climbing_woman:{keywords:["sports","hobby","woman","female","rock"],char:'\u{1f9d7}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},climbing_man:{keywords:["sports","hobby","man","male","rock"],char:'\u{1f9d7}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},swimming_woman:{keywords:["sports","exercise","human","athlete","water","summer","woman","female"],char:'\u{1f3ca}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},swimming_man:{keywords:["sports","exercise","human","athlete","water","summer"],char:'\u{1f3ca}',fitzpatrick_scale:!0,category:"activity"},woman_playing_water_polo:{keywords:["sports","pool"],char:'\u{1f93d}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_playing_water_polo:{keywords:["sports","pool"],char:'\u{1f93d}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},woman_in_lotus_position:{keywords:["woman","female","meditation","yoga","serenity","zen","mindfulness"],char:'\u{1f9d8}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_in_lotus_position:{keywords:["man","male","meditation","yoga","serenity","zen","mindfulness"],char:'\u{1f9d8}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},surfing_woman:{keywords:["sports","ocean","sea","summer","beach","woman","female"],char:'\u{1f3c4}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},surfing_man:{keywords:["sports","ocean","sea","summer","beach"],char:'\u{1f3c4}',fitzpatrick_scale:!0,category:"activity"},bath:{keywords:["clean","shower","bathroom"],char:'\u{1f6c0}',fitzpatrick_scale:!0,category:"activity"},basketball_woman:{keywords:["sports","human","woman","female"],char:'\u26f9\ufe0f\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},basketball_man:{keywords:["sports","human"],char:'\u26f9',fitzpatrick_scale:!0,category:"activity"},weight_lifting_woman:{keywords:["sports","training","exercise","woman","female"],char:'\u{1f3cb}\ufe0f\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},weight_lifting_man:{keywords:["sports","training","exercise"],char:'\u{1f3cb}',fitzpatrick_scale:!0,category:"activity"},biking_woman:{keywords:["sports","bike","exercise","hipster","woman","female"],char:'\u{1f6b4}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},biking_man:{keywords:["sports","bike","exercise","hipster"],char:'\u{1f6b4}',fitzpatrick_scale:!0,category:"activity"},mountain_biking_woman:{keywords:["transportation","sports","human","race","bike","woman","female"],char:'\u{1f6b5}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},mountain_biking_man:{keywords:["transportation","sports","human","race","bike"],char:'\u{1f6b5}',fitzpatrick_scale:!0,category:"activity"},horse_racing:{keywords:["animal","betting","competition","gambling","luck"],char:'\u{1f3c7}',fitzpatrick_scale:!0,category:"activity"},business_suit_levitating:{keywords:["suit","business","levitate","hover","jump"],char:'\u{1f574}',fitzpatrick_scale:!0,category:"activity"},trophy:{keywords:["win","award","contest","place","ftw","ceremony"],char:'\u{1f3c6}',fitzpatrick_scale:!1,category:"activity"},running_shirt_with_sash:{keywords:["play","pageant"],char:'\u{1f3bd}',fitzpatrick_scale:!1,category:"activity"},medal_sports:{keywords:["award","winning"],char:'\u{1f3c5}',fitzpatrick_scale:!1,category:"activity"},medal_military:{keywords:["award","winning","army"],char:'\u{1f396}',fitzpatrick_scale:!1,category:"activity"},"1st_place_medal":{keywords:["award","winning","first"],char:'\u{1f947}',fitzpatrick_scale:!1,category:"activity"},"2nd_place_medal":{keywords:["award","second"],char:'\u{1f948}',fitzpatrick_scale:!1,category:"activity"},"3rd_place_medal":{keywords:["award","third"],char:'\u{1f949}',fitzpatrick_scale:!1,category:"activity"},reminder_ribbon:{keywords:["sports","cause","support","awareness"],char:'\u{1f397}',fitzpatrick_scale:!1,category:"activity"},rosette:{keywords:["flower","decoration","military"],char:'\u{1f3f5}',fitzpatrick_scale:!1,category:"activity"},ticket:{keywords:["event","concert","pass"],char:'\u{1f3ab}',fitzpatrick_scale:!1,category:"activity"},tickets:{keywords:["sports","concert","entrance"],char:'\u{1f39f}',fitzpatrick_scale:!1,category:"activity"},performing_arts:{keywords:["acting","theater","drama"],char:'\u{1f3ad}',fitzpatrick_scale:!1,category:"activity"},art:{keywords:["design","paint","draw","colors"],char:'\u{1f3a8}',fitzpatrick_scale:!1,category:"activity"},circus_tent:{keywords:["festival","carnival","party"],char:'\u{1f3aa}',fitzpatrick_scale:!1,category:"activity"},woman_juggling:{keywords:["juggle","balance","skill","multitask"],char:'\u{1f939}\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_juggling:{keywords:["juggle","balance","skill","multitask"],char:'\u{1f939}\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},microphone:{keywords:["sound","music","PA","sing","talkshow"],char:'\u{1f3a4}',fitzpatrick_scale:!1,category:"activity"},headphones:{keywords:["music","score","gadgets"],char:'\u{1f3a7}',fitzpatrick_scale:!1,category:"activity"},musical_score:{keywords:["treble","clef","compose"],char:'\u{1f3bc}',fitzpatrick_scale:!1,category:"activity"},musical_keyboard:{keywords:["piano","instrument","compose"],char:'\u{1f3b9}',fitzpatrick_scale:!1,category:"activity"},drum:{keywords:["music","instrument","drumsticks","snare"],char:'\u{1f941}',fitzpatrick_scale:!1,category:"activity"},saxophone:{keywords:["music","instrument","jazz","blues"],char:'\u{1f3b7}',fitzpatrick_scale:!1,category:"activity"},trumpet:{keywords:["music","brass"],char:'\u{1f3ba}',fitzpatrick_scale:!1,category:"activity"},guitar:{keywords:["music","instrument"],char:'\u{1f3b8}',fitzpatrick_scale:!1,category:"activity"},violin:{keywords:["music","instrument","orchestra","symphony"],char:'\u{1f3bb}',fitzpatrick_scale:!1,category:"activity"},clapper:{keywords:["movie","film","record"],char:'\u{1f3ac}',fitzpatrick_scale:!1,category:"activity"},video_game:{keywords:["play","console","PS4","controller"],char:'\u{1f3ae}',fitzpatrick_scale:!1,category:"activity"},space_invader:{keywords:["game","arcade","play"],char:'\u{1f47e}',fitzpatrick_scale:!1,category:"activity"},dart:{keywords:["game","play","bar","target","bullseye"],char:'\u{1f3af}',fitzpatrick_scale:!1,category:"activity"},game_die:{keywords:["dice","random","tabletop","play","luck"],char:'\u{1f3b2}',fitzpatrick_scale:!1,category:"activity"},chess_pawn:{keywords:["expendable"],char:"\u265f",fitzpatrick_scale:!1,category:"activity"},slot_machine:{keywords:["bet","gamble","vegas","fruit machine","luck","casino"],char:'\u{1f3b0}',fitzpatrick_scale:!1,category:"activity"},jigsaw:{keywords:["interlocking","puzzle","piece"],char:'\u{1f9e9}',fitzpatrick_scale:!1,category:"activity"},bowling:{keywords:["sports","fun","play"],char:'\u{1f3b3}',fitzpatrick_scale:!1,category:"activity"},red_car:{keywords:["red","transportation","vehicle"],char:'\u{1f697}',fitzpatrick_scale:!1,category:"travel_and_places"},taxi:{keywords:["uber","vehicle","cars","transportation"],char:'\u{1f695}',fitzpatrick_scale:!1,category:"travel_and_places"},blue_car:{keywords:["transportation","vehicle"],char:'\u{1f699}',fitzpatrick_scale:!1,category:"travel_and_places"},bus:{keywords:["car","vehicle","transportation"],char:'\u{1f68c}',fitzpatrick_scale:!1,category:"travel_and_places"},trolleybus:{keywords:["bart","transportation","vehicle"],char:'\u{1f68e}',fitzpatrick_scale:!1,category:"travel_and_places"},racing_car:{keywords:["sports","race","fast","formula","f1"],char:'\u{1f3ce}',fitzpatrick_scale:!1,category:"travel_and_places"},police_car:{keywords:["vehicle","cars","transportation","law","legal","enforcement"],char:'\u{1f693}',fitzpatrick_scale:!1,category:"travel_and_places"},ambulance:{keywords:["health","911","hospital"],char:'\u{1f691}',fitzpatrick_scale:!1,category:"travel_and_places"},fire_engine:{keywords:["transportation","cars","vehicle"],char:'\u{1f692}',fitzpatrick_scale:!1,category:"travel_and_places"},minibus:{keywords:["vehicle","car","transportation"],char:'\u{1f690}',fitzpatrick_scale:!1,category:"travel_and_places"},truck:{keywords:["cars","transportation"],char:'\u{1f69a}',fitzpatrick_scale:!1,category:"travel_and_places"},articulated_lorry:{keywords:["vehicle","cars","transportation","express"],char:'\u{1f69b}',fitzpatrick_scale:!1,category:"travel_and_places"},tractor:{keywords:["vehicle","car","farming","agriculture"],char:'\u{1f69c}',fitzpatrick_scale:!1,category:"travel_and_places"},kick_scooter:{keywords:["vehicle","kick","razor"],char:'\u{1f6f4}',fitzpatrick_scale:!1,category:"travel_and_places"},motorcycle:{keywords:["race","sports","fast"],char:'\u{1f3cd}',fitzpatrick_scale:!1,category:"travel_and_places"},bike:{keywords:["sports","bicycle","exercise","hipster"],char:'\u{1f6b2}',fitzpatrick_scale:!1,category:"travel_and_places"},motor_scooter:{keywords:["vehicle","vespa","sasha"],char:'\u{1f6f5}',fitzpatrick_scale:!1,category:"travel_and_places"},rotating_light:{keywords:["police","ambulance","911","emergency","alert","error","pinged","law","legal"],char:'\u{1f6a8}',fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_police_car:{keywords:["vehicle","law","legal","enforcement","911"],char:'\u{1f694}',fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_bus:{keywords:["vehicle","transportation"],char:'\u{1f68d}',fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_automobile:{keywords:["car","vehicle","transportation"],char:'\u{1f698}',fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_taxi:{keywords:["vehicle","cars","uber"],char:'\u{1f696}',fitzpatrick_scale:!1,category:"travel_and_places"},aerial_tramway:{keywords:["transportation","vehicle","ski"],char:'\u{1f6a1}',fitzpatrick_scale:!1,category:"travel_and_places"},mountain_cableway:{keywords:["transportation","vehicle","ski"],char:'\u{1f6a0}',fitzpatrick_scale:!1,category:"travel_and_places"},suspension_railway:{keywords:["vehicle","transportation"],char:'\u{1f69f}',fitzpatrick_scale:!1,category:"travel_and_places"},railway_car:{keywords:["transportation","vehicle"],char:'\u{1f683}',fitzpatrick_scale:!1,category:"travel_and_places"},train:{keywords:["transportation","vehicle","carriage","public","travel"],char:'\u{1f68b}',fitzpatrick_scale:!1,category:"travel_and_places"},monorail:{keywords:["transportation","vehicle"],char:'\u{1f69d}',fitzpatrick_scale:!1,category:"travel_and_places"},bullettrain_side:{keywords:["transportation","vehicle"],char:'\u{1f684}',fitzpatrick_scale:!1,category:"travel_and_places"},bullettrain_front:{keywords:["transportation","vehicle","speed","fast","public","travel"],char:'\u{1f685}',fitzpatrick_scale:!1,category:"travel_and_places"},light_rail:{keywords:["transportation","vehicle"],char:'\u{1f688}',fitzpatrick_scale:!1,category:"travel_and_places"},mountain_railway:{keywords:["transportation","vehicle"],char:'\u{1f69e}',fitzpatrick_scale:!1,category:"travel_and_places"},steam_locomotive:{keywords:["transportation","vehicle","train"],char:'\u{1f682}',fitzpatrick_scale:!1,category:"travel_and_places"},train2:{keywords:["transportation","vehicle"],char:'\u{1f686}',fitzpatrick_scale:!1,category:"travel_and_places"},metro:{keywords:["transportation","blue-square","mrt","underground","tube"],char:'\u{1f687}',fitzpatrick_scale:!1,category:"travel_and_places"},tram:{keywords:["transportation","vehicle"],char:'\u{1f68a}',fitzpatrick_scale:!1,category:"travel_and_places"},station:{keywords:["transportation","vehicle","public"],char:'\u{1f689}',fitzpatrick_scale:!1,category:"travel_and_places"},flying_saucer:{keywords:["transportation","vehicle","ufo"],char:'\u{1f6f8}',fitzpatrick_scale:!1,category:"travel_and_places"},helicopter:{keywords:["transportation","vehicle","fly"],char:'\u{1f681}',fitzpatrick_scale:!1,category:"travel_and_places"},small_airplane:{keywords:["flight","transportation","fly","vehicle"],char:'\u{1f6e9}',fitzpatrick_scale:!1,category:"travel_and_places"},airplane:{keywords:["vehicle","transportation","flight","fly"],char:'\u2708\ufe0f',fitzpatrick_scale:!1,category:"travel_and_places"},flight_departure:{keywords:["airport","flight","landing"],char:'\u{1f6eb}',fitzpatrick_scale:!1,category:"travel_and_places"},flight_arrival:{keywords:["airport","flight","boarding"],char:'\u{1f6ec}',fitzpatrick_scale:!1,category:"travel_and_places"},sailboat:{keywords:["ship","summer","transportation","water","sailing"],char:'\u26f5',fitzpatrick_scale:!1,category:"travel_and_places"},motor_boat:{keywords:["ship"],char:'\u{1f6e5}',fitzpatrick_scale:!1,category:"travel_and_places"},speedboat:{keywords:["ship","transportation","vehicle","summer"],char:'\u{1f6a4}',fitzpatrick_scale:!1,category:"travel_and_places"},ferry:{keywords:["boat","ship","yacht"],char:'\u26f4',fitzpatrick_scale:!1,category:"travel_and_places"},passenger_ship:{keywords:["yacht","cruise","ferry"],char:'\u{1f6f3}',fitzpatrick_scale:!1,category:"travel_and_places"},rocket:{keywords:["launch","ship","staffmode","NASA","outer space","outer_space","fly"],char:'\u{1f680}',fitzpatrick_scale:!1,category:"travel_and_places"},artificial_satellite:{keywords:["communication","gps","orbit","spaceflight","NASA","ISS"],char:'\u{1f6f0}',fitzpatrick_scale:!1,category:"travel_and_places"},seat:{keywords:["sit","airplane","transport","bus","flight","fly"],char:'\u{1f4ba}',fitzpatrick_scale:!1,category:"travel_and_places"},canoe:{keywords:["boat","paddle","water","ship"],char:'\u{1f6f6}',fitzpatrick_scale:!1,category:"travel_and_places"},anchor:{keywords:["ship","ferry","sea","boat"],char:'\u2693',fitzpatrick_scale:!1,category:"travel_and_places"},construction:{keywords:["wip","progress","caution","warning"],char:'\u{1f6a7}',fitzpatrick_scale:!1,category:"travel_and_places"},fuelpump:{keywords:["gas station","petroleum"],char:'\u26fd',fitzpatrick_scale:!1,category:"travel_and_places"},busstop:{keywords:["transportation","wait"],char:'\u{1f68f}',fitzpatrick_scale:!1,category:"travel_and_places"},vertical_traffic_light:{keywords:["transportation","driving"],char:'\u{1f6a6}',fitzpatrick_scale:!1,category:"travel_and_places"},traffic_light:{keywords:["transportation","signal"],char:'\u{1f6a5}',fitzpatrick_scale:!1,category:"travel_and_places"},checkered_flag:{keywords:["contest","finishline","race","gokart"],char:'\u{1f3c1}',fitzpatrick_scale:!1,category:"travel_and_places"},ship:{keywords:["transportation","titanic","deploy"],char:'\u{1f6a2}',fitzpatrick_scale:!1,category:"travel_and_places"},ferris_wheel:{keywords:["photo","carnival","londoneye"],char:'\u{1f3a1}',fitzpatrick_scale:!1,category:"travel_and_places"},roller_coaster:{keywords:["carnival","playground","photo","fun"],char:'\u{1f3a2}',fitzpatrick_scale:!1,category:"travel_and_places"},carousel_horse:{keywords:["photo","carnival"],char:'\u{1f3a0}',fitzpatrick_scale:!1,category:"travel_and_places"},building_construction:{keywords:["wip","working","progress"],char:'\u{1f3d7}',fitzpatrick_scale:!1,category:"travel_and_places"},foggy:{keywords:["photo","mountain"],char:'\u{1f301}',fitzpatrick_scale:!1,category:"travel_and_places"},tokyo_tower:{keywords:["photo","japanese"],char:'\u{1f5fc}',fitzpatrick_scale:!1,category:"travel_and_places"},factory:{keywords:["building","industry","pollution","smoke"],char:'\u{1f3ed}',fitzpatrick_scale:!1,category:"travel_and_places"},fountain:{keywords:["photo","summer","water","fresh"],char:'\u26f2',fitzpatrick_scale:!1,category:"travel_and_places"},rice_scene:{keywords:["photo","japan","asia","tsukimi"],char:'\u{1f391}',fitzpatrick_scale:!1,category:"travel_and_places"},mountain:{keywords:["photo","nature","environment"],char:'\u26f0',fitzpatrick_scale:!1,category:"travel_and_places"},mountain_snow:{keywords:["photo","nature","environment","winter","cold"],char:'\u{1f3d4}',fitzpatrick_scale:!1,category:"travel_and_places"},mount_fuji:{keywords:["photo","mountain","nature","japanese"],char:'\u{1f5fb}',fitzpatrick_scale:!1,category:"travel_and_places"},volcano:{keywords:["photo","nature","disaster"],char:'\u{1f30b}',fitzpatrick_scale:!1,category:"travel_and_places"},japan:{keywords:["nation","country","japanese","asia"],char:'\u{1f5fe}',fitzpatrick_scale:!1,category:"travel_and_places"},camping:{keywords:["photo","outdoors","tent"],char:'\u{1f3d5}',fitzpatrick_scale:!1,category:"travel_and_places"},tent:{keywords:["photo","camping","outdoors"],char:'\u26fa',fitzpatrick_scale:!1,category:"travel_and_places"},national_park:{keywords:["photo","environment","nature"],char:'\u{1f3de}',fitzpatrick_scale:!1,category:"travel_and_places"},motorway:{keywords:["road","cupertino","interstate","highway"],char:'\u{1f6e3}',fitzpatrick_scale:!1,category:"travel_and_places"},railway_track:{keywords:["train","transportation"],char:'\u{1f6e4}',fitzpatrick_scale:!1,category:"travel_and_places"},sunrise:{keywords:["morning","view","vacation","photo"],char:'\u{1f305}',fitzpatrick_scale:!1,category:"travel_and_places"},sunrise_over_mountains:{keywords:["view","vacation","photo"],char:'\u{1f304}',fitzpatrick_scale:!1,category:"travel_and_places"},desert:{keywords:["photo","warm","saharah"],char:'\u{1f3dc}',fitzpatrick_scale:!1,category:"travel_and_places"},beach_umbrella:{keywords:["weather","summer","sunny","sand","mojito"],char:'\u{1f3d6}',fitzpatrick_scale:!1,category:"travel_and_places"},desert_island:{keywords:["photo","tropical","mojito"],char:'\u{1f3dd}',fitzpatrick_scale:!1,category:"travel_and_places"},city_sunrise:{keywords:["photo","good morning","dawn"],char:'\u{1f307}',fitzpatrick_scale:!1,category:"travel_and_places"},city_sunset:{keywords:["photo","evening","sky","buildings"],char:'\u{1f306}',fitzpatrick_scale:!1,category:"travel_and_places"},cityscape:{keywords:["photo","night life","urban"],char:'\u{1f3d9}',fitzpatrick_scale:!1,category:"travel_and_places"},night_with_stars:{keywords:["evening","city","downtown"],char:'\u{1f303}',fitzpatrick_scale:!1,category:"travel_and_places"},bridge_at_night:{keywords:["photo","sanfrancisco"],char:'\u{1f309}',fitzpatrick_scale:!1,category:"travel_and_places"},milky_way:{keywords:["photo","space","stars"],char:'\u{1f30c}',fitzpatrick_scale:!1,category:"travel_and_places"},stars:{keywords:["night","photo"],char:'\u{1f320}',fitzpatrick_scale:!1,category:"travel_and_places"},sparkler:{keywords:["stars","night","shine"],char:'\u{1f387}',fitzpatrick_scale:!1,category:"travel_and_places"},fireworks:{keywords:["photo","festival","carnival","congratulations"],char:'\u{1f386}',fitzpatrick_scale:!1,category:"travel_and_places"},rainbow:{keywords:["nature","happy","unicorn_face","photo","sky","spring"],char:'\u{1f308}',fitzpatrick_scale:!1,category:"travel_and_places"},houses:{keywords:["buildings","photo"],char:'\u{1f3d8}',fitzpatrick_scale:!1,category:"travel_and_places"},european_castle:{keywords:["building","royalty","history"],char:'\u{1f3f0}',fitzpatrick_scale:!1,category:"travel_and_places"},japanese_castle:{keywords:["photo","building"],char:'\u{1f3ef}',fitzpatrick_scale:!1,category:"travel_and_places"},stadium:{keywords:["photo","place","sports","concert","venue"],char:'\u{1f3df}',fitzpatrick_scale:!1,category:"travel_and_places"},statue_of_liberty:{keywords:["american","newyork"],char:'\u{1f5fd}',fitzpatrick_scale:!1,category:"travel_and_places"},house:{keywords:["building","home"],char:'\u{1f3e0}',fitzpatrick_scale:!1,category:"travel_and_places"},house_with_garden:{keywords:["home","plant","nature"],char:'\u{1f3e1}',fitzpatrick_scale:!1,category:"travel_and_places"},derelict_house:{keywords:["abandon","evict","broken","building"],char:'\u{1f3da}',fitzpatrick_scale:!1,category:"travel_and_places"},office:{keywords:["building","bureau","work"],char:'\u{1f3e2}',fitzpatrick_scale:!1,category:"travel_and_places"},department_store:{keywords:["building","shopping","mall"],char:'\u{1f3ec}',fitzpatrick_scale:!1,category:"travel_and_places"},post_office:{keywords:["building","envelope","communication"],char:'\u{1f3e3}',fitzpatrick_scale:!1,category:"travel_and_places"},european_post_office:{keywords:["building","email"],char:'\u{1f3e4}',fitzpatrick_scale:!1,category:"travel_and_places"},hospital:{keywords:["building","health","surgery","doctor"],char:'\u{1f3e5}',fitzpatrick_scale:!1,category:"travel_and_places"},bank:{keywords:["building","money","sales","cash","business","enterprise"],char:'\u{1f3e6}',fitzpatrick_scale:!1,category:"travel_and_places"},hotel:{keywords:["building","accomodation","checkin"],char:'\u{1f3e8}',fitzpatrick_scale:!1,category:"travel_and_places"},convenience_store:{keywords:["building","shopping","groceries"],char:'\u{1f3ea}',fitzpatrick_scale:!1,category:"travel_and_places"},school:{keywords:["building","student","education","learn","teach"],char:'\u{1f3eb}',fitzpatrick_scale:!1,category:"travel_and_places"},love_hotel:{keywords:["like","affection","dating"],char:'\u{1f3e9}',fitzpatrick_scale:!1,category:"travel_and_places"},wedding:{keywords:["love","like","affection","couple","marriage","bride","groom"],char:'\u{1f492}',fitzpatrick_scale:!1,category:"travel_and_places"},classical_building:{keywords:["art","culture","history"],char:'\u{1f3db}',fitzpatrick_scale:!1,category:"travel_and_places"},church:{keywords:["building","religion","christ"],char:'\u26ea',fitzpatrick_scale:!1,category:"travel_and_places"},mosque:{keywords:["islam","worship","minaret"],char:'\u{1f54c}',fitzpatrick_scale:!1,category:"travel_and_places"},synagogue:{keywords:["judaism","worship","temple","jewish"],char:'\u{1f54d}',fitzpatrick_scale:!1,category:"travel_and_places"},kaaba:{keywords:["mecca","mosque","islam"],char:'\u{1f54b}',fitzpatrick_scale:!1,category:"travel_and_places"},shinto_shrine:{keywords:["temple","japan","kyoto"],char:'\u26e9',fitzpatrick_scale:!1,category:"travel_and_places"},watch:{keywords:["time","accessories"],char:'\u231a',fitzpatrick_scale:!1,category:"objects"},iphone:{keywords:["technology","apple","gadgets","dial"],char:'\u{1f4f1}',fitzpatrick_scale:!1,category:"objects"},calling:{keywords:["iphone","incoming"],char:'\u{1f4f2}',fitzpatrick_scale:!1,category:"objects"},computer:{keywords:["technology","laptop","screen","display","monitor"],char:'\u{1f4bb}',fitzpatrick_scale:!1,category:"objects"},keyboard:{keywords:["technology","computer","type","input","text"],char:'\u2328',fitzpatrick_scale:!1,category:"objects"},desktop_computer:{keywords:["technology","computing","screen"],char:'\u{1f5a5}',fitzpatrick_scale:!1,category:"objects"},printer:{keywords:["paper","ink"],char:'\u{1f5a8}',fitzpatrick_scale:!1,category:"objects"},computer_mouse:{keywords:["click"],char:'\u{1f5b1}',fitzpatrick_scale:!1,category:"objects"},trackball:{keywords:["technology","trackpad"],char:'\u{1f5b2}',fitzpatrick_scale:!1,category:"objects"},joystick:{keywords:["game","play"],char:'\u{1f579}',fitzpatrick_scale:!1,category:"objects"},clamp:{keywords:["tool"],char:'\u{1f5dc}',fitzpatrick_scale:!1,category:"objects"},minidisc:{keywords:["technology","record","data","disk","90s"],char:'\u{1f4bd}',fitzpatrick_scale:!1,category:"objects"},floppy_disk:{keywords:["oldschool","technology","save","90s","80s"],char:'\u{1f4be}',fitzpatrick_scale:!1,category:"objects"},cd:{keywords:["technology","dvd","disk","disc","90s"],char:'\u{1f4bf}',fitzpatrick_scale:!1,category:"objects"},dvd:{keywords:["cd","disk","disc"],char:'\u{1f4c0}',fitzpatrick_scale:!1,category:"objects"},vhs:{keywords:["record","video","oldschool","90s","80s"],char:'\u{1f4fc}',fitzpatrick_scale:!1,category:"objects"},camera:{keywords:["gadgets","photography"],char:'\u{1f4f7}',fitzpatrick_scale:!1,category:"objects"},camera_flash:{keywords:["photography","gadgets"],char:'\u{1f4f8}',fitzpatrick_scale:!1,category:"objects"},video_camera:{keywords:["film","record"],char:'\u{1f4f9}',fitzpatrick_scale:!1,category:"objects"},movie_camera:{keywords:["film","record"],char:'\u{1f3a5}',fitzpatrick_scale:!1,category:"objects"},film_projector:{keywords:["video","tape","record","movie"],char:'\u{1f4fd}',fitzpatrick_scale:!1,category:"objects"},film_strip:{keywords:["movie"],char:'\u{1f39e}',fitzpatrick_scale:!1,category:"objects"},telephone_receiver:{keywords:["technology","communication","dial"],char:'\u{1f4de}',fitzpatrick_scale:!1,category:"objects"},phone:{keywords:["technology","communication","dial","telephone"],char:'\u260e\ufe0f',fitzpatrick_scale:!1,category:"objects"},pager:{keywords:["bbcall","oldschool","90s"],char:'\u{1f4df}',fitzpatrick_scale:!1,category:"objects"},fax:{keywords:["communication","technology"],char:'\u{1f4e0}',fitzpatrick_scale:!1,category:"objects"},tv:{keywords:["technology","program","oldschool","show","television"],char:'\u{1f4fa}',fitzpatrick_scale:!1,category:"objects"},radio:{keywords:["communication","music","podcast","program"],char:'\u{1f4fb}',fitzpatrick_scale:!1,category:"objects"},studio_microphone:{keywords:["sing","recording","artist","talkshow"],char:'\u{1f399}',fitzpatrick_scale:!1,category:"objects"},level_slider:{keywords:["scale"],char:'\u{1f39a}',fitzpatrick_scale:!1,category:"objects"},control_knobs:{keywords:["dial"],char:'\u{1f39b}',fitzpatrick_scale:!1,category:"objects"},compass:{keywords:["magnetic","navigation","orienteering"],char:'\u{1f9ed}',fitzpatrick_scale:!1,category:"objects"},stopwatch:{keywords:["time","deadline"],char:'\u23f1',fitzpatrick_scale:!1,category:"objects"},timer_clock:{keywords:["alarm"],char:'\u23f2',fitzpatrick_scale:!1,category:"objects"},alarm_clock:{keywords:["time","wake"],char:'\u23f0',fitzpatrick_scale:!1,category:"objects"},mantelpiece_clock:{keywords:["time"],char:'\u{1f570}',fitzpatrick_scale:!1,category:"objects"},hourglass_flowing_sand:{keywords:["oldschool","time","countdown"],char:'\u23f3',fitzpatrick_scale:!1,category:"objects"},hourglass:{keywords:["time","clock","oldschool","limit","exam","quiz","test"],char:'\u231b',fitzpatrick_scale:!1,category:"objects"},satellite:{keywords:["communication","future","radio","space"],char:'\u{1f4e1}',fitzpatrick_scale:!1,category:"objects"},battery:{keywords:["power","energy","sustain"],char:'\u{1f50b}',fitzpatrick_scale:!1,category:"objects"},electric_plug:{keywords:["charger","power"],char:'\u{1f50c}',fitzpatrick_scale:!1,category:"objects"},bulb:{keywords:["light","electricity","idea"],char:'\u{1f4a1}',fitzpatrick_scale:!1,category:"objects"},flashlight:{keywords:["dark","camping","sight","night"],char:'\u{1f526}',fitzpatrick_scale:!1,category:"objects"},candle:{keywords:["fire","wax"],char:'\u{1f56f}',fitzpatrick_scale:!1,category:"objects"},fire_extinguisher:{keywords:["quench"],char:'\u{1f9ef}',fitzpatrick_scale:!1,category:"objects"},wastebasket:{keywords:["bin","trash","rubbish","garbage","toss"],char:'\u{1f5d1}',fitzpatrick_scale:!1,category:"objects"},oil_drum:{keywords:["barrell"],char:'\u{1f6e2}',fitzpatrick_scale:!1,category:"objects"},money_with_wings:{keywords:["dollar","bills","payment","sale"],char:'\u{1f4b8}',fitzpatrick_scale:!1,category:"objects"},dollar:{keywords:["money","sales","bill","currency"],char:'\u{1f4b5}',fitzpatrick_scale:!1,category:"objects"},yen:{keywords:["money","sales","japanese","dollar","currency"],char:'\u{1f4b4}',fitzpatrick_scale:!1,category:"objects"},euro:{keywords:["money","sales","dollar","currency"],char:'\u{1f4b6}',fitzpatrick_scale:!1,category:"objects"},pound:{keywords:["british","sterling","money","sales","bills","uk","england","currency"],char:'\u{1f4b7}',fitzpatrick_scale:!1,category:"objects"},moneybag:{keywords:["dollar","payment","coins","sale"],char:'\u{1f4b0}',fitzpatrick_scale:!1,category:"objects"},credit_card:{keywords:["money","sales","dollar","bill","payment","shopping"],char:'\u{1f4b3}',fitzpatrick_scale:!1,category:"objects"},gem:{keywords:["blue","ruby","diamond","jewelry"],char:'\u{1f48e}',fitzpatrick_scale:!1,category:"objects"},balance_scale:{keywords:["law","fairness","weight"],char:'\u2696',fitzpatrick_scale:!1,category:"objects"},toolbox:{keywords:["tools","diy","fix","maintainer","mechanic"],char:'\u{1f9f0}',fitzpatrick_scale:!1,category:"objects"},wrench:{keywords:["tools","diy","ikea","fix","maintainer"],char:'\u{1f527}',fitzpatrick_scale:!1,category:"objects"},hammer:{keywords:["tools","build","create"],char:'\u{1f528}',fitzpatrick_scale:!1,category:"objects"},hammer_and_pick:{keywords:["tools","build","create"],char:'\u2692',fitzpatrick_scale:!1,category:"objects"},hammer_and_wrench:{keywords:["tools","build","create"],char:'\u{1f6e0}',fitzpatrick_scale:!1,category:"objects"},pick:{keywords:["tools","dig"],char:'\u26cf',fitzpatrick_scale:!1,category:"objects"},nut_and_bolt:{keywords:["handy","tools","fix"],char:'\u{1f529}',fitzpatrick_scale:!1,category:"objects"},gear:{keywords:["cog"],char:'\u2699',fitzpatrick_scale:!1,category:"objects"},brick:{keywords:["bricks"],char:'\u{1f9f1}',fitzpatrick_scale:!1,category:"objects"},chains:{keywords:["lock","arrest"],char:'\u26d3',fitzpatrick_scale:!1,category:"objects"},magnet:{keywords:["attraction","magnetic"],char:'\u{1f9f2}',fitzpatrick_scale:!1,category:"objects"},gun:{keywords:["violence","weapon","pistol","revolver"],char:'\u{1f52b}',fitzpatrick_scale:!1,category:"objects"},bomb:{keywords:["boom","explode","explosion","terrorism"],char:'\u{1f4a3}',fitzpatrick_scale:!1,category:"objects"},firecracker:{keywords:["dynamite","boom","explode","explosion","explosive"],char:'\u{1f9e8}',fitzpatrick_scale:!1,category:"objects"},hocho:{keywords:["knife","blade","cutlery","kitchen","weapon"],char:'\u{1f52a}',fitzpatrick_scale:!1,category:"objects"},dagger:{keywords:["weapon"],char:'\u{1f5e1}',fitzpatrick_scale:!1,category:"objects"},crossed_swords:{keywords:["weapon"],char:'\u2694',fitzpatrick_scale:!1,category:"objects"},shield:{keywords:["protection","security"],char:'\u{1f6e1}',fitzpatrick_scale:!1,category:"objects"},smoking:{keywords:["kills","tobacco","cigarette","joint","smoke"],char:'\u{1f6ac}',fitzpatrick_scale:!1,category:"objects"},skull_and_crossbones:{keywords:["poison","danger","deadly","scary","death","pirate","evil"],char:'\u2620',fitzpatrick_scale:!1,category:"objects"},coffin:{keywords:["vampire","dead","die","death","rip","graveyard","cemetery","casket","funeral","box"],char:'\u26b0',fitzpatrick_scale:!1,category:"objects"},funeral_urn:{keywords:["dead","die","death","rip","ashes"],char:'\u26b1',fitzpatrick_scale:!1,category:"objects"},amphora:{keywords:["vase","jar"],char:'\u{1f3fa}',fitzpatrick_scale:!1,category:"objects"},crystal_ball:{keywords:["disco","party","magic","circus","fortune_teller"],char:'\u{1f52e}',fitzpatrick_scale:!1,category:"objects"},prayer_beads:{keywords:["dhikr","religious"],char:'\u{1f4ff}',fitzpatrick_scale:!1,category:"objects"},nazar_amulet:{keywords:["bead","charm"],char:'\u{1f9ff}',fitzpatrick_scale:!1,category:"objects"},barber:{keywords:["hair","salon","style"],char:'\u{1f488}',fitzpatrick_scale:!1,category:"objects"},alembic:{keywords:["distilling","science","experiment","chemistry"],char:'\u2697',fitzpatrick_scale:!1,category:"objects"},telescope:{keywords:["stars","space","zoom","science","astronomy"],char:'\u{1f52d}',fitzpatrick_scale:!1,category:"objects"},microscope:{keywords:["laboratory","experiment","zoomin","science","study"],char:'\u{1f52c}',fitzpatrick_scale:!1,category:"objects"},hole:{keywords:["embarrassing"],char:'\u{1f573}',fitzpatrick_scale:!1,category:"objects"},pill:{keywords:["health","medicine","doctor","pharmacy","drug"],char:'\u{1f48a}',fitzpatrick_scale:!1,category:"objects"},syringe:{keywords:["health","hospital","drugs","blood","medicine","needle","doctor","nurse"],char:'\u{1f489}',fitzpatrick_scale:!1,category:"objects"},dna:{keywords:["biologist","genetics","life"],char:'\u{1f9ec}',fitzpatrick_scale:!1,category:"objects"},microbe:{keywords:["amoeba","bacteria","germs"],char:'\u{1f9a0}',fitzpatrick_scale:!1,category:"objects"},petri_dish:{keywords:["bacteria","biology","culture","lab"],char:'\u{1f9eb}',fitzpatrick_scale:!1,category:"objects"},test_tube:{keywords:["chemistry","experiment","lab","science"],char:'\u{1f9ea}',fitzpatrick_scale:!1,category:"objects"},thermometer:{keywords:["weather","temperature","hot","cold"],char:'\u{1f321}',fitzpatrick_scale:!1,category:"objects"},broom:{keywords:["cleaning","sweeping","witch"],char:'\u{1f9f9}',fitzpatrick_scale:!1,category:"objects"},basket:{keywords:["laundry"],char:'\u{1f9fa}',fitzpatrick_scale:!1,category:"objects"},toilet_paper:{keywords:["roll"],char:'\u{1f9fb}',fitzpatrick_scale:!1,category:"objects"},label:{keywords:["sale","tag"],char:'\u{1f3f7}',fitzpatrick_scale:!1,category:"objects"},bookmark:{keywords:["favorite","label","save"],char:'\u{1f516}',fitzpatrick_scale:!1,category:"objects"},toilet:{keywords:["restroom","wc","washroom","bathroom","potty"],char:'\u{1f6bd}',fitzpatrick_scale:!1,category:"objects"},shower:{keywords:["clean","water","bathroom"],char:'\u{1f6bf}',fitzpatrick_scale:!1,category:"objects"},bathtub:{keywords:["clean","shower","bathroom"],char:'\u{1f6c1}',fitzpatrick_scale:!1,category:"objects"},soap:{keywords:["bar","bathing","cleaning","lather"],char:'\u{1f9fc}',fitzpatrick_scale:!1,category:"objects"},sponge:{keywords:["absorbing","cleaning","porous"],char:'\u{1f9fd}',fitzpatrick_scale:!1,category:"objects"},lotion_bottle:{keywords:["moisturizer","sunscreen"],char:'\u{1f9f4}',fitzpatrick_scale:!1,category:"objects"},key:{keywords:["lock","door","password"],char:'\u{1f511}',fitzpatrick_scale:!1,category:"objects"},old_key:{keywords:["lock","door","password"],char:'\u{1f5dd}',fitzpatrick_scale:!1,category:"objects"},couch_and_lamp:{keywords:["read","chill"],char:'\u{1f6cb}',fitzpatrick_scale:!1,category:"objects"},sleeping_bed:{keywords:["bed","rest"],char:'\u{1f6cc}',fitzpatrick_scale:!0,category:"objects"},bed:{keywords:["sleep","rest"],char:'\u{1f6cf}',fitzpatrick_scale:!1,category:"objects"},door:{keywords:["house","entry","exit"],char:'\u{1f6aa}',fitzpatrick_scale:!1,category:"objects"},bellhop_bell:{keywords:["service"],char:'\u{1f6ce}',fitzpatrick_scale:!1,category:"objects"},teddy_bear:{keywords:["plush","stuffed"],char:'\u{1f9f8}',fitzpatrick_scale:!1,category:"objects"},framed_picture:{keywords:["photography"],char:'\u{1f5bc}',fitzpatrick_scale:!1,category:"objects"},world_map:{keywords:["location","direction"],char:'\u{1f5fa}',fitzpatrick_scale:!1,category:"objects"},parasol_on_ground:{keywords:["weather","summer"],char:'\u26f1',fitzpatrick_scale:!1,category:"objects"},moyai:{keywords:["rock","easter island","moai"],char:'\u{1f5ff}',fitzpatrick_scale:!1,category:"objects"},shopping:{keywords:["mall","buy","purchase"],char:'\u{1f6cd}',fitzpatrick_scale:!1,category:"objects"},shopping_cart:{keywords:["trolley"],char:'\u{1f6d2}',fitzpatrick_scale:!1,category:"objects"},balloon:{keywords:["party","celebration","birthday","circus"],char:'\u{1f388}',fitzpatrick_scale:!1,category:"objects"},flags:{keywords:["fish","japanese","koinobori","carp","banner"],char:'\u{1f38f}',fitzpatrick_scale:!1,category:"objects"},ribbon:{keywords:["decoration","pink","girl","bowtie"],char:'\u{1f380}',fitzpatrick_scale:!1,category:"objects"},gift:{keywords:["present","birthday","christmas","xmas"],char:'\u{1f381}',fitzpatrick_scale:!1,category:"objects"},confetti_ball:{keywords:["festival","party","birthday","circus"],char:'\u{1f38a}',fitzpatrick_scale:!1,category:"objects"},tada:{keywords:["party","congratulations","birthday","magic","circus","celebration"],char:'\u{1f389}',fitzpatrick_scale:!1,category:"objects"},dolls:{keywords:["japanese","toy","kimono"],char:'\u{1f38e}',fitzpatrick_scale:!1,category:"objects"},wind_chime:{keywords:["nature","ding","spring","bell"],char:'\u{1f390}',fitzpatrick_scale:!1,category:"objects"},crossed_flags:{keywords:["japanese","nation","country","border"],char:'\u{1f38c}',fitzpatrick_scale:!1,category:"objects"},izakaya_lantern:{keywords:["light","paper","halloween","spooky"],char:'\u{1f3ee}',fitzpatrick_scale:!1,category:"objects"},red_envelope:{keywords:["gift"],char:'\u{1f9e7}',fitzpatrick_scale:!1,category:"objects"},email:{keywords:["letter","postal","inbox","communication"],char:'\u2709\ufe0f',fitzpatrick_scale:!1,category:"objects"},envelope_with_arrow:{keywords:["email","communication"],char:'\u{1f4e9}',fitzpatrick_scale:!1,category:"objects"},incoming_envelope:{keywords:["email","inbox"],char:'\u{1f4e8}',fitzpatrick_scale:!1,category:"objects"},"e-mail":{keywords:["communication","inbox"],char:'\u{1f4e7}',fitzpatrick_scale:!1,category:"objects"},love_letter:{keywords:["email","like","affection","envelope","valentines"],char:'\u{1f48c}',fitzpatrick_scale:!1,category:"objects"},postbox:{keywords:["email","letter","envelope"],char:'\u{1f4ee}',fitzpatrick_scale:!1,category:"objects"},mailbox_closed:{keywords:["email","communication","inbox"],char:'\u{1f4ea}',fitzpatrick_scale:!1,category:"objects"},mailbox:{keywords:["email","inbox","communication"],char:'\u{1f4eb}',fitzpatrick_scale:!1,category:"objects"},mailbox_with_mail:{keywords:["email","inbox","communication"],char:'\u{1f4ec}',fitzpatrick_scale:!1,category:"objects"},mailbox_with_no_mail:{keywords:["email","inbox"],char:'\u{1f4ed}',fitzpatrick_scale:!1,category:"objects"},package:{keywords:["mail","gift","cardboard","box","moving"],char:'\u{1f4e6}',fitzpatrick_scale:!1,category:"objects"},postal_horn:{keywords:["instrument","music"],char:'\u{1f4ef}',fitzpatrick_scale:!1,category:"objects"},inbox_tray:{keywords:["email","documents"],char:'\u{1f4e5}',fitzpatrick_scale:!1,category:"objects"},outbox_tray:{keywords:["inbox","email"],char:'\u{1f4e4}',fitzpatrick_scale:!1,category:"objects"},scroll:{keywords:["documents","ancient","history","paper"],char:'\u{1f4dc}',fitzpatrick_scale:!1,category:"objects"},page_with_curl:{keywords:["documents","office","paper"],char:'\u{1f4c3}',fitzpatrick_scale:!1,category:"objects"},bookmark_tabs:{keywords:["favorite","save","order","tidy"],char:'\u{1f4d1}',fitzpatrick_scale:!1,category:"objects"},receipt:{keywords:["accounting","expenses"],char:'\u{1f9fe}',fitzpatrick_scale:!1,category:"objects"},bar_chart:{keywords:["graph","presentation","stats"],char:'\u{1f4ca}',fitzpatrick_scale:!1,category:"objects"},chart_with_upwards_trend:{keywords:["graph","presentation","stats","recovery","business","economics","money","sales","good","success"],char:'\u{1f4c8}',fitzpatrick_scale:!1,category:"objects"},chart_with_downwards_trend:{keywords:["graph","presentation","stats","recession","business","economics","money","sales","bad","failure"],char:'\u{1f4c9}',fitzpatrick_scale:!1,category:"objects"},page_facing_up:{keywords:["documents","office","paper","information"],char:'\u{1f4c4}',fitzpatrick_scale:!1,category:"objects"},date:{keywords:["calendar","schedule"],char:'\u{1f4c5}',fitzpatrick_scale:!1,category:"objects"},calendar:{keywords:["schedule","date","planning"],char:'\u{1f4c6}',fitzpatrick_scale:!1,category:"objects"},spiral_calendar:{keywords:["date","schedule","planning"],char:'\u{1f5d3}',fitzpatrick_scale:!1,category:"objects"},card_index:{keywords:["business","stationery"],char:'\u{1f4c7}',fitzpatrick_scale:!1,category:"objects"},card_file_box:{keywords:["business","stationery"],char:'\u{1f5c3}',fitzpatrick_scale:!1,category:"objects"},ballot_box:{keywords:["election","vote"],char:'\u{1f5f3}',fitzpatrick_scale:!1,category:"objects"},file_cabinet:{keywords:["filing","organizing"],char:'\u{1f5c4}',fitzpatrick_scale:!1,category:"objects"},clipboard:{keywords:["stationery","documents"],char:'\u{1f4cb}',fitzpatrick_scale:!1,category:"objects"},spiral_notepad:{keywords:["memo","stationery"],char:'\u{1f5d2}',fitzpatrick_scale:!1,category:"objects"},file_folder:{keywords:["documents","business","office"],char:'\u{1f4c1}',fitzpatrick_scale:!1,category:"objects"},open_file_folder:{keywords:["documents","load"],char:'\u{1f4c2}',fitzpatrick_scale:!1,category:"objects"},card_index_dividers:{keywords:["organizing","business","stationery"],char:'\u{1f5c2}',fitzpatrick_scale:!1,category:"objects"},newspaper_roll:{keywords:["press","headline"],char:'\u{1f5de}',fitzpatrick_scale:!1,category:"objects"},newspaper:{keywords:["press","headline"],char:'\u{1f4f0}',fitzpatrick_scale:!1,category:"objects"},notebook:{keywords:["stationery","record","notes","paper","study"],char:'\u{1f4d3}',fitzpatrick_scale:!1,category:"objects"},closed_book:{keywords:["read","library","knowledge","textbook","learn"],char:'\u{1f4d5}',fitzpatrick_scale:!1,category:"objects"},green_book:{keywords:["read","library","knowledge","study"],char:'\u{1f4d7}',fitzpatrick_scale:!1,category:"objects"},blue_book:{keywords:["read","library","knowledge","learn","study"],char:'\u{1f4d8}',fitzpatrick_scale:!1,category:"objects"},orange_book:{keywords:["read","library","knowledge","textbook","study"],char:'\u{1f4d9}',fitzpatrick_scale:!1,category:"objects"},notebook_with_decorative_cover:{keywords:["classroom","notes","record","paper","study"],char:'\u{1f4d4}',fitzpatrick_scale:!1,category:"objects"},ledger:{keywords:["notes","paper"],char:'\u{1f4d2}',fitzpatrick_scale:!1,category:"objects"},books:{keywords:["literature","library","study"],char:'\u{1f4da}',fitzpatrick_scale:!1,category:"objects"},open_book:{keywords:["book","read","library","knowledge","literature","learn","study"],char:'\u{1f4d6}',fitzpatrick_scale:!1,category:"objects"},safety_pin:{keywords:["diaper"],char:'\u{1f9f7}',fitzpatrick_scale:!1,category:"objects"},link:{keywords:["rings","url"],char:'\u{1f517}',fitzpatrick_scale:!1,category:"objects"},paperclip:{keywords:["documents","stationery"],char:'\u{1f4ce}',fitzpatrick_scale:!1,category:"objects"},paperclips:{keywords:["documents","stationery"],char:'\u{1f587}',fitzpatrick_scale:!1,category:"objects"},scissors:{keywords:["stationery","cut"],char:'\u2702\ufe0f',fitzpatrick_scale:!1,category:"objects"},triangular_ruler:{keywords:["stationery","math","architect","sketch"],char:'\u{1f4d0}',fitzpatrick_scale:!1,category:"objects"},straight_ruler:{keywords:["stationery","calculate","length","math","school","drawing","architect","sketch"],char:'\u{1f4cf}',fitzpatrick_scale:!1,category:"objects"},abacus:{keywords:["calculation"],char:'\u{1f9ee}',fitzpatrick_scale:!1,category:"objects"},pushpin:{keywords:["stationery","mark","here"],char:'\u{1f4cc}',fitzpatrick_scale:!1,category:"objects"},round_pushpin:{keywords:["stationery","location","map","here"],char:'\u{1f4cd}',fitzpatrick_scale:!1,category:"objects"},triangular_flag_on_post:{keywords:["mark","milestone","place"],char:'\u{1f6a9}',fitzpatrick_scale:!1,category:"objects"},white_flag:{keywords:["losing","loser","lost","surrender","give up","fail"],char:'\u{1f3f3}',fitzpatrick_scale:!1,category:"objects"},black_flag:{keywords:["pirate"],char:'\u{1f3f4}',fitzpatrick_scale:!1,category:"objects"},rainbow_flag:{keywords:["flag","rainbow","pride","gay","lgbt","glbt","queer","homosexual","lesbian","bisexual","transgender"],char:'\u{1f3f3}\ufe0f\u200d\u{1f308}',fitzpatrick_scale:!1,category:"objects"},closed_lock_with_key:{keywords:["security","privacy"],char:'\u{1f510}',fitzpatrick_scale:!1,category:"objects"},lock:{keywords:["security","password","padlock"],char:'\u{1f512}',fitzpatrick_scale:!1,category:"objects"},unlock:{keywords:["privacy","security"],char:'\u{1f513}',fitzpatrick_scale:!1,category:"objects"},lock_with_ink_pen:{keywords:["security","secret"],char:'\u{1f50f}',fitzpatrick_scale:!1,category:"objects"},pen:{keywords:["stationery","writing","write"],char:'\u{1f58a}',fitzpatrick_scale:!1,category:"objects"},fountain_pen:{keywords:["stationery","writing","write"],char:'\u{1f58b}',fitzpatrick_scale:!1,category:"objects"},black_nib:{keywords:["pen","stationery","writing","write"],char:'\u2712\ufe0f',fitzpatrick_scale:!1,category:"objects"},memo:{keywords:["write","documents","stationery","pencil","paper","writing","legal","exam","quiz","test","study","compose"],char:'\u{1f4dd}',fitzpatrick_scale:!1,category:"objects"},pencil2:{keywords:["stationery","write","paper","writing","school","study"],char:'\u270f\ufe0f',fitzpatrick_scale:!1,category:"objects"},crayon:{keywords:["drawing","creativity"],char:'\u{1f58d}',fitzpatrick_scale:!1,category:"objects"},paintbrush:{keywords:["drawing","creativity","art"],char:'\u{1f58c}',fitzpatrick_scale:!1,category:"objects"},mag:{keywords:["search","zoom","find","detective"],char:'\u{1f50d}',fitzpatrick_scale:!1,category:"objects"},mag_right:{keywords:["search","zoom","find","detective"],char:'\u{1f50e}',fitzpatrick_scale:!1,category:"objects"},heart:{keywords:["love","like","valentines"],char:'\u2764\ufe0f',fitzpatrick_scale:!1,category:"symbols"},orange_heart:{keywords:["love","like","affection","valentines"],char:'\u{1f9e1}',fitzpatrick_scale:!1,category:"symbols"},yellow_heart:{keywords:["love","like","affection","valentines"],char:'\u{1f49b}',fitzpatrick_scale:!1,category:"symbols"},green_heart:{keywords:["love","like","affection","valentines"],char:'\u{1f49a}',fitzpatrick_scale:!1,category:"symbols"},blue_heart:{keywords:["love","like","affection","valentines"],char:'\u{1f499}',fitzpatrick_scale:!1,category:"symbols"},purple_heart:{keywords:["love","like","affection","valentines"],char:'\u{1f49c}',fitzpatrick_scale:!1,category:"symbols"},black_heart:{keywords:["evil"],char:'\u{1f5a4}',fitzpatrick_scale:!1,category:"symbols"},broken_heart:{keywords:["sad","sorry","break","heart","heartbreak"],char:'\u{1f494}',fitzpatrick_scale:!1,category:"symbols"},heavy_heart_exclamation:{keywords:["decoration","love"],char:'\u2763',fitzpatrick_scale:!1,category:"symbols"},two_hearts:{keywords:["love","like","affection","valentines","heart"],char:'\u{1f495}',fitzpatrick_scale:!1,category:"symbols"},revolving_hearts:{keywords:["love","like","affection","valentines"],char:'\u{1f49e}',fitzpatrick_scale:!1,category:"symbols"},heartbeat:{keywords:["love","like","affection","valentines","pink","heart"],char:'\u{1f493}',fitzpatrick_scale:!1,category:"symbols"},heartpulse:{keywords:["like","love","affection","valentines","pink"],char:'\u{1f497}',fitzpatrick_scale:!1,category:"symbols"},sparkling_heart:{keywords:["love","like","affection","valentines"],char:'\u{1f496}',fitzpatrick_scale:!1,category:"symbols"},cupid:{keywords:["love","like","heart","affection","valentines"],char:'\u{1f498}',fitzpatrick_scale:!1,category:"symbols"},gift_heart:{keywords:["love","valentines"],char:'\u{1f49d}',fitzpatrick_scale:!1,category:"symbols"},heart_decoration:{keywords:["purple-square","love","like"],char:'\u{1f49f}',fitzpatrick_scale:!1,category:"symbols"},peace_symbol:{keywords:["hippie"],char:'\u262e',fitzpatrick_scale:!1,category:"symbols"},latin_cross:{keywords:["christianity"],char:'\u271d',fitzpatrick_scale:!1,category:"symbols"},star_and_crescent:{keywords:["islam"],char:'\u262a',fitzpatrick_scale:!1,category:"symbols"},om:{keywords:["hinduism","buddhism","sikhism","jainism"],char:'\u{1f549}',fitzpatrick_scale:!1,category:"symbols"},wheel_of_dharma:{keywords:["hinduism","buddhism","sikhism","jainism"],char:'\u2638',fitzpatrick_scale:!1,category:"symbols"},star_of_david:{keywords:["judaism"],char:'\u2721',fitzpatrick_scale:!1,category:"symbols"},six_pointed_star:{keywords:["purple-square","religion","jewish","hexagram"],char:'\u{1f52f}',fitzpatrick_scale:!1,category:"symbols"},menorah:{keywords:["hanukkah","candles","jewish"],char:'\u{1f54e}',fitzpatrick_scale:!1,category:"symbols"},yin_yang:{keywords:["balance"],char:'\u262f',fitzpatrick_scale:!1,category:"symbols"},orthodox_cross:{keywords:["suppedaneum","religion"],char:'\u2626',fitzpatrick_scale:!1,category:"symbols"},place_of_worship:{keywords:["religion","church","temple","prayer"],char:'\u{1f6d0}',fitzpatrick_scale:!1,category:"symbols"},ophiuchus:{keywords:["sign","purple-square","constellation","astrology"],char:'\u26ce',fitzpatrick_scale:!1,category:"symbols"},aries:{keywords:["sign","purple-square","zodiac","astrology"],char:'\u2648',fitzpatrick_scale:!1,category:"symbols"},taurus:{keywords:["purple-square","sign","zodiac","astrology"],char:'\u2649',fitzpatrick_scale:!1,category:"symbols"},gemini:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u264a',fitzpatrick_scale:!1,category:"symbols"},cancer:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u264b',fitzpatrick_scale:!1,category:"symbols"},leo:{keywords:["sign","purple-square","zodiac","astrology"],char:'\u264c',fitzpatrick_scale:!1,category:"symbols"},virgo:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u264d',fitzpatrick_scale:!1,category:"symbols"},libra:{keywords:["sign","purple-square","zodiac","astrology"],char:'\u264e',fitzpatrick_scale:!1,category:"symbols"},scorpius:{keywords:["sign","zodiac","purple-square","astrology","scorpio"],char:'\u264f',fitzpatrick_scale:!1,category:"symbols"},sagittarius:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u2650',fitzpatrick_scale:!1,category:"symbols"},capricorn:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u2651',fitzpatrick_scale:!1,category:"symbols"},aquarius:{keywords:["sign","purple-square","zodiac","astrology"],char:'\u2652',fitzpatrick_scale:!1,category:"symbols"},pisces:{keywords:["purple-square","sign","zodiac","astrology"],char:'\u2653',fitzpatrick_scale:!1,category:"symbols"},id:{keywords:["purple-square","words"],char:'\u{1f194}',fitzpatrick_scale:!1,category:"symbols"},atom_symbol:{keywords:["science","physics","chemistry"],char:'\u269b',fitzpatrick_scale:!1,category:"symbols"},u7a7a:{keywords:["kanji","japanese","chinese","empty","sky","blue-square"],char:'\u{1f233}',fitzpatrick_scale:!1,category:"symbols"},u5272:{keywords:["cut","divide","chinese","kanji","pink-square"],char:'\u{1f239}',fitzpatrick_scale:!1,category:"symbols"},radioactive:{keywords:["nuclear","danger"],char:'\u2622',fitzpatrick_scale:!1,category:"symbols"},biohazard:{keywords:["danger"],char:'\u2623',fitzpatrick_scale:!1,category:"symbols"},mobile_phone_off:{keywords:["mute","orange-square","silence","quiet"],char:'\u{1f4f4}',fitzpatrick_scale:!1,category:"symbols"},vibration_mode:{keywords:["orange-square","phone"],char:'\u{1f4f3}',fitzpatrick_scale:!1,category:"symbols"},u6709:{keywords:["orange-square","chinese","have","kanji"],char:'\u{1f236}',fitzpatrick_scale:!1,category:"symbols"},u7121:{keywords:["nothing","chinese","kanji","japanese","orange-square"],char:'\u{1f21a}',fitzpatrick_scale:!1,category:"symbols"},u7533:{keywords:["chinese","japanese","kanji","orange-square"],char:'\u{1f238}',fitzpatrick_scale:!1,category:"symbols"},u55b6:{keywords:["japanese","opening hours","orange-square"],char:'\u{1f23a}',fitzpatrick_scale:!1,category:"symbols"},u6708:{keywords:["chinese","month","moon","japanese","orange-square","kanji"],char:'\u{1f237}\ufe0f',fitzpatrick_scale:!1,category:"symbols"},eight_pointed_black_star:{keywords:["orange-square","shape","polygon"],char:'\u2734\ufe0f',fitzpatrick_scale:!1,category:"symbols"},vs:{keywords:["words","orange-square"],char:'\u{1f19a}',fitzpatrick_scale:!1,category:"symbols"},accept:{keywords:["ok","good","chinese","kanji","agree","yes","orange-circle"],char:'\u{1f251}',fitzpatrick_scale:!1,category:"symbols"},white_flower:{keywords:["japanese","spring"],char:'\u{1f4ae}',fitzpatrick_scale:!1,category:"symbols"},ideograph_advantage:{keywords:["chinese","kanji","obtain","get","circle"],char:'\u{1f250}',fitzpatrick_scale:!1,category:"symbols"},secret:{keywords:["privacy","chinese","sshh","kanji","red-circle"],char:'\u3299\ufe0f',fitzpatrick_scale:!1,category:"symbols"},congratulations:{keywords:["chinese","kanji","japanese","red-circle"],char:'\u3297\ufe0f',fitzpatrick_scale:!1,category:"symbols"},u5408:{keywords:["japanese","chinese","join","kanji","red-square"],char:'\u{1f234}',fitzpatrick_scale:!1,category:"symbols"},u6e80:{keywords:["full","chinese","japanese","red-square","kanji"],char:'\u{1f235}',fitzpatrick_scale:!1,category:"symbols"},u7981:{keywords:["kanji","japanese","chinese","forbidden","limit","restricted","red-square"],char:'\u{1f232}',fitzpatrick_scale:!1,category:"symbols"},a:{keywords:["red-square","alphabet","letter"],char:'\u{1f170}\ufe0f',fitzpatrick_scale:!1,category:"symbols"},b:{keywords:["red-square","alphabet","letter"],char:'\u{1f171}\ufe0f',fitzpatrick_scale:!1,category:"symbols"},ab:{keywords:["red-square","alphabet"],char:'\u{1f18e}',fitzpatrick_scale:!1,category:"symbols"},cl:{keywords:["alphabet","words","red-square"],char:'\u{1f191}',fitzpatrick_scale:!1,category:"symbols"},o2:{keywords:["alphabet","red-square","letter"],char:'\u{1f17e}\ufe0f',fitzpatrick_scale:!1,category:"symbols"},sos:{keywords:["help","red-square","words","emergency","911"],char:'\u{1f198}',fitzpatrick_scale:!1,category:"symbols"},no_entry:{keywords:["limit","security","privacy","bad","denied","stop","circle"],char:'\u26d4',fitzpatrick_scale:!1,category:"symbols"},name_badge:{keywords:["fire","forbid"],char:'\u{1f4db}',fitzpatrick_scale:!1,category:"symbols"},no_entry_sign:{keywords:["forbid","stop","limit","denied","disallow","circle"],char:'\u{1f6ab}',fitzpatrick_scale:!1,category:"symbols"},x:{keywords:["no","delete","remove","cancel","red"],char:'\u274c',fitzpatrick_scale:!1,category:"symbols"},o:{keywords:["circle","round"],char:'\u2b55',fitzpatrick_scale:!1,category:"symbols"},stop_sign:{keywords:["stop"],char:'\u{1f6d1}',fitzpatrick_scale:!1,category:"symbols"},anger:{keywords:["angry","mad"],char:'\u{1f4a2}',fitzpatrick_scale:!1,category:"symbols"},hotsprings:{keywords:["bath","warm","relax"],char:'\u2668\ufe0f',fitzpatrick_scale:!1,category:"symbols"},no_pedestrians:{keywords:["rules","crossing","walking","circle"],char:'\u{1f6b7}',fitzpatrick_scale:!1,category:"symbols"},do_not_litter:{keywords:["trash","bin","garbage","circle"],char:'\u{1f6af}',fitzpatrick_scale:!1,category:"symbols"},no_bicycles:{keywords:["cyclist","prohibited","circle"],char:'\u{1f6b3}',fitzpatrick_scale:!1,category:"symbols"},"non-potable_water":{keywords:["drink","faucet","tap","circle"],char:'\u{1f6b1}',fitzpatrick_scale:!1,category:"symbols"},underage:{keywords:["18","drink","pub","night","minor","circle"],char:'\u{1f51e}',fitzpatrick_scale:!1,category:"symbols"},no_mobile_phones:{keywords:["iphone","mute","circle"],char:'\u{1f4f5}',fitzpatrick_scale:!1,category:"symbols"},exclamation:{keywords:["heavy_exclamation_mark","danger","surprise","punctuation","wow","warning"],char:'\u2757',fitzpatrick_scale:!1,category:"symbols"},grey_exclamation:{keywords:["surprise","punctuation","gray","wow","warning"],char:'\u2755',fitzpatrick_scale:!1,category:"symbols"},question:{keywords:["doubt","confused"],char:'\u2753',fitzpatrick_scale:!1,category:"symbols"},grey_question:{keywords:["doubts","gray","huh","confused"],char:'\u2754',fitzpatrick_scale:!1,category:"symbols"},bangbang:{keywords:["exclamation","surprise"],char:'\u203c\ufe0f',fitzpatrick_scale:!1,category:"symbols"},interrobang:{keywords:["wat","punctuation","surprise"],char:'\u2049\ufe0f',fitzpatrick_scale:!1,category:"symbols"},low_brightness:{keywords:["sun","afternoon","warm","summer"],char:'\u{1f505}',fitzpatrick_scale:!1,category:"symbols"},high_brightness:{keywords:["sun","light"],char:'\u{1f506}',fitzpatrick_scale:!1,category:"symbols"},trident:{keywords:["weapon","spear"],char:'\u{1f531}',fitzpatrick_scale:!1,category:"symbols"},fleur_de_lis:{keywords:["decorative","scout"],char:'\u269c',fitzpatrick_scale:!1,category:"symbols"},part_alternation_mark:{keywords:["graph","presentation","stats","business","economics","bad"],char:'\u303d\ufe0f',fitzpatrick_scale:!1,category:"symbols"},warning:{keywords:["exclamation","wip","alert","error","problem","issue"],char:'\u26a0\ufe0f',fitzpatrick_scale:!1,category:"symbols"},children_crossing:{keywords:["school","warning","danger","sign","driving","yellow-diamond"],char:'\u{1f6b8}',fitzpatrick_scale:!1,category:"symbols"},beginner:{keywords:["badge","shield"],char:'\u{1f530}',fitzpatrick_scale:!1,category:"symbols"},recycle:{keywords:["arrow","environment","garbage","trash"],char:'\u267b\ufe0f',fitzpatrick_scale:!1,category:"symbols"},u6307:{keywords:["chinese","point","green-square","kanji"],char:'\u{1f22f}',fitzpatrick_scale:!1,category:"symbols"},chart:{keywords:["green-square","graph","presentation","stats"],char:'\u{1f4b9}',fitzpatrick_scale:!1,category:"symbols"},sparkle:{keywords:["stars","green-square","awesome","good","fireworks"],char:'\u2747\ufe0f',fitzpatrick_scale:!1,category:"symbols"},eight_spoked_asterisk:{keywords:["star","sparkle","green-square"],char:'\u2733\ufe0f',fitzpatrick_scale:!1,category:"symbols"},negative_squared_cross_mark:{keywords:["x","green-square","no","deny"],char:'\u274e',fitzpatrick_scale:!1,category:"symbols"},white_check_mark:{keywords:["green-square","ok","agree","vote","election","answer","tick"],char:'\u2705',fitzpatrick_scale:!1,category:"symbols"},diamond_shape_with_a_dot_inside:{keywords:["jewel","blue","gem","crystal","fancy"],char:'\u{1f4a0}',fitzpatrick_scale:!1,category:"symbols"},cyclone:{keywords:["weather","swirl","blue","cloud","vortex","spiral","whirlpool","spin","tornado","hurricane","typhoon"],char:'\u{1f300}',fitzpatrick_scale:!1,category:"symbols"},loop:{keywords:["tape","cassette"],char:'\u27bf',fitzpatrick_scale:!1,category:"symbols"},globe_with_meridians:{keywords:["earth","international","world","internet","interweb","i18n"],char:'\u{1f310}',fitzpatrick_scale:!1,category:"symbols"},m:{keywords:["alphabet","blue-circle","letter"],char:'\u24c2\ufe0f',fitzpatrick_scale:!1,category:"symbols"},atm:{keywords:["money","sales","cash","blue-square","payment","bank"],char:'\u{1f3e7}',fitzpatrick_scale:!1,category:"symbols"},sa:{keywords:["japanese","blue-square","katakana"],char:'\u{1f202}\ufe0f',fitzpatrick_scale:!1,category:"symbols"},passport_control:{keywords:["custom","blue-square"],char:'\u{1f6c2}',fitzpatrick_scale:!1,category:"symbols"},customs:{keywords:["passport","border","blue-square"],char:'\u{1f6c3}',fitzpatrick_scale:!1,category:"symbols"},baggage_claim:{keywords:["blue-square","airport","transport"],char:'\u{1f6c4}',fitzpatrick_scale:!1,category:"symbols"},left_luggage:{keywords:["blue-square","travel"],char:'\u{1f6c5}',fitzpatrick_scale:!1,category:"symbols"},wheelchair:{keywords:["blue-square","disabled","a11y","accessibility"],char:'\u267f',fitzpatrick_scale:!1,category:"symbols"},no_smoking:{keywords:["cigarette","blue-square","smell","smoke"],char:'\u{1f6ad}',fitzpatrick_scale:!1,category:"symbols"},wc:{keywords:["toilet","restroom","blue-square"],char:'\u{1f6be}',fitzpatrick_scale:!1,category:"symbols"},parking:{keywords:["cars","blue-square","alphabet","letter"],char:'\u{1f17f}\ufe0f',fitzpatrick_scale:!1,category:"symbols"},potable_water:{keywords:["blue-square","liquid","restroom","cleaning","faucet"],char:'\u{1f6b0}',fitzpatrick_scale:!1,category:"symbols"},mens:{keywords:["toilet","restroom","wc","blue-square","gender","male"],char:'\u{1f6b9}',fitzpatrick_scale:!1,category:"symbols"},womens:{keywords:["purple-square","woman","female","toilet","loo","restroom","gender"],char:'\u{1f6ba}',fitzpatrick_scale:!1,category:"symbols"},baby_symbol:{keywords:["orange-square","child"],char:'\u{1f6bc}',fitzpatrick_scale:!1,category:"symbols"},restroom:{keywords:["blue-square","toilet","refresh","wc","gender"],char:'\u{1f6bb}',fitzpatrick_scale:!1,category:"symbols"},put_litter_in_its_place:{keywords:["blue-square","sign","human","info"],char:'\u{1f6ae}',fitzpatrick_scale:!1,category:"symbols"},cinema:{keywords:["blue-square","record","film","movie","curtain","stage","theater"],char:'\u{1f3a6}',fitzpatrick_scale:!1,category:"symbols"},signal_strength:{keywords:["blue-square","reception","phone","internet","connection","wifi","bluetooth","bars"],char:'\u{1f4f6}',fitzpatrick_scale:!1,category:"symbols"},koko:{keywords:["blue-square","here","katakana","japanese","destination"],char:'\u{1f201}',fitzpatrick_scale:!1,category:"symbols"},ng:{keywords:["blue-square","words","shape","icon"],char:'\u{1f196}',fitzpatrick_scale:!1,category:"symbols"},ok:{keywords:["good","agree","yes","blue-square"],char:'\u{1f197}',fitzpatrick_scale:!1,category:"symbols"},up:{keywords:["blue-square","above","high"],char:'\u{1f199}',fitzpatrick_scale:!1,category:"symbols"},cool:{keywords:["words","blue-square"],char:'\u{1f192}',fitzpatrick_scale:!1,category:"symbols"},new:{keywords:["blue-square","words","start"],char:'\u{1f195}',fitzpatrick_scale:!1,category:"symbols"},free:{keywords:["blue-square","words"],char:'\u{1f193}',fitzpatrick_scale:!1,category:"symbols"},zero:{keywords:["0","numbers","blue-square","null"],char:'0\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},one:{keywords:["blue-square","numbers","1"],char:'1\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},two:{keywords:["numbers","2","prime","blue-square"],char:'2\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},three:{keywords:["3","numbers","prime","blue-square"],char:'3\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},four:{keywords:["4","numbers","blue-square"],char:'4\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},five:{keywords:["5","numbers","blue-square","prime"],char:'5\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},six:{keywords:["6","numbers","blue-square"],char:'6\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},seven:{keywords:["7","numbers","blue-square","prime"],char:'7\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},eight:{keywords:["8","blue-square","numbers"],char:'8\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},nine:{keywords:["blue-square","numbers","9"],char:'9\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},keycap_ten:{keywords:["numbers","10","blue-square"],char:'\u{1f51f}',fitzpatrick_scale:!1,category:"symbols"},asterisk:{keywords:["star","keycap"],char:'*\u20e3',fitzpatrick_scale:!1,category:"symbols"},eject_button:{keywords:["blue-square"],char:'\u23cf\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_forward:{keywords:["blue-square","right","direction","play"],char:'\u25b6\ufe0f',fitzpatrick_scale:!1,category:"symbols"},pause_button:{keywords:["pause","blue-square"],char:'\u23f8',fitzpatrick_scale:!1,category:"symbols"},next_track_button:{keywords:["forward","next","blue-square"],char:'\u23ed',fitzpatrick_scale:!1,category:"symbols"},stop_button:{keywords:["blue-square"],char:'\u23f9',fitzpatrick_scale:!1,category:"symbols"},record_button:{keywords:["blue-square"],char:'\u23fa',fitzpatrick_scale:!1,category:"symbols"},play_or_pause_button:{keywords:["blue-square","play","pause"],char:'\u23ef',fitzpatrick_scale:!1,category:"symbols"},previous_track_button:{keywords:["backward"],char:'\u23ee',fitzpatrick_scale:!1,category:"symbols"},fast_forward:{keywords:["blue-square","play","speed","continue"],char:'\u23e9',fitzpatrick_scale:!1,category:"symbols"},rewind:{keywords:["play","blue-square"],char:'\u23ea',fitzpatrick_scale:!1,category:"symbols"},twisted_rightwards_arrows:{keywords:["blue-square","shuffle","music","random"],char:'\u{1f500}',fitzpatrick_scale:!1,category:"symbols"},repeat:{keywords:["loop","record"],char:'\u{1f501}',fitzpatrick_scale:!1,category:"symbols"},repeat_one:{keywords:["blue-square","loop"],char:'\u{1f502}',fitzpatrick_scale:!1,category:"symbols"},arrow_backward:{keywords:["blue-square","left","direction"],char:'\u25c0\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_up_small:{keywords:["blue-square","triangle","direction","point","forward","top"],char:'\u{1f53c}',fitzpatrick_scale:!1,category:"symbols"},arrow_down_small:{keywords:["blue-square","direction","bottom"],char:'\u{1f53d}',fitzpatrick_scale:!1,category:"symbols"},arrow_double_up:{keywords:["blue-square","direction","top"],char:'\u23eb',fitzpatrick_scale:!1,category:"symbols"},arrow_double_down:{keywords:["blue-square","direction","bottom"],char:'\u23ec',fitzpatrick_scale:!1,category:"symbols"},arrow_right:{keywords:["blue-square","next"],char:'\u27a1\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_left:{keywords:["blue-square","previous","back"],char:'\u2b05\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_up:{keywords:["blue-square","continue","top","direction"],char:'\u2b06\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_down:{keywords:["blue-square","direction","bottom"],char:'\u2b07\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_upper_right:{keywords:["blue-square","point","direction","diagonal","northeast"],char:'\u2197\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_lower_right:{keywords:["blue-square","direction","diagonal","southeast"],char:'\u2198\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_lower_left:{keywords:["blue-square","direction","diagonal","southwest"],char:'\u2199\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_upper_left:{keywords:["blue-square","point","direction","diagonal","northwest"],char:'\u2196\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_up_down:{keywords:["blue-square","direction","way","vertical"],char:'\u2195\ufe0f',fitzpatrick_scale:!1,category:"symbols"},left_right_arrow:{keywords:["shape","direction","horizontal","sideways"],char:'\u2194\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrows_counterclockwise:{keywords:["blue-square","sync","cycle"],char:'\u{1f504}',fitzpatrick_scale:!1,category:"symbols"},arrow_right_hook:{keywords:["blue-square","return","rotate","direction"],char:'\u21aa\ufe0f',fitzpatrick_scale:!1,category:"symbols"},leftwards_arrow_with_hook:{keywords:["back","return","blue-square","undo","enter"],char:'\u21a9\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_heading_up:{keywords:["blue-square","direction","top"],char:'\u2934\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_heading_down:{keywords:["blue-square","direction","bottom"],char:'\u2935\ufe0f',fitzpatrick_scale:!1,category:"symbols"},hash:{keywords:["symbol","blue-square","twitter"],char:'#\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},information_source:{keywords:["blue-square","alphabet","letter"],char:'\u2139\ufe0f',fitzpatrick_scale:!1,category:"symbols"},abc:{keywords:["blue-square","alphabet"],char:'\u{1f524}',fitzpatrick_scale:!1,category:"symbols"},abcd:{keywords:["blue-square","alphabet"],char:'\u{1f521}',fitzpatrick_scale:!1,category:"symbols"},capital_abcd:{keywords:["alphabet","words","blue-square"],char:'\u{1f520}',fitzpatrick_scale:!1,category:"symbols"},symbols:{keywords:["blue-square","music","note","ampersand","percent","glyphs","characters"],char:'\u{1f523}',fitzpatrick_scale:!1,category:"symbols"},musical_note:{keywords:["score","tone","sound"],char:'\u{1f3b5}',fitzpatrick_scale:!1,category:"symbols"},notes:{keywords:["music","score"],char:'\u{1f3b6}',fitzpatrick_scale:!1,category:"symbols"},wavy_dash:{keywords:["draw","line","moustache","mustache","squiggle","scribble"],char:'\u3030\ufe0f',fitzpatrick_scale:!1,category:"symbols"},curly_loop:{keywords:["scribble","draw","shape","squiggle"],char:'\u27b0',fitzpatrick_scale:!1,category:"symbols"},heavy_check_mark:{keywords:["ok","nike","answer","yes","tick"],char:'\u2714\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrows_clockwise:{keywords:["sync","cycle","round","repeat"],char:'\u{1f503}',fitzpatrick_scale:!1,category:"symbols"},heavy_plus_sign:{keywords:["math","calculation","addition","more","increase"],char:'\u2795',fitzpatrick_scale:!1,category:"symbols"},heavy_minus_sign:{keywords:["math","calculation","subtract","less"],char:'\u2796',fitzpatrick_scale:!1,category:"symbols"},heavy_division_sign:{keywords:["divide","math","calculation"],char:'\u2797',fitzpatrick_scale:!1,category:"symbols"},heavy_multiplication_x:{keywords:["math","calculation"],char:'\u2716\ufe0f',fitzpatrick_scale:!1,category:"symbols"},infinity:{keywords:["forever"],char:'\u267e',fitzpatrick_scale:!1,category:"symbols"},heavy_dollar_sign:{keywords:["money","sales","payment","currency","buck"],char:'\u{1f4b2}',fitzpatrick_scale:!1,category:"symbols"},currency_exchange:{keywords:["money","sales","dollar","travel"],char:'\u{1f4b1}',fitzpatrick_scale:!1,category:"symbols"},copyright:{keywords:["ip","license","circle","law","legal"],char:'\xa9\ufe0f',fitzpatrick_scale:!1,category:"symbols"},registered:{keywords:["alphabet","circle"],char:'\xae\ufe0f',fitzpatrick_scale:!1,category:"symbols"},tm:{keywords:["trademark","brand","law","legal"],char:'\u2122\ufe0f',fitzpatrick_scale:!1,category:"symbols"},end:{keywords:["words","arrow"],char:'\u{1f51a}',fitzpatrick_scale:!1,category:"symbols"},back:{keywords:["arrow","words","return"],char:'\u{1f519}',fitzpatrick_scale:!1,category:"symbols"},on:{keywords:["arrow","words"],char:'\u{1f51b}',fitzpatrick_scale:!1,category:"symbols"},top:{keywords:["words","blue-square"],char:'\u{1f51d}',fitzpatrick_scale:!1,category:"symbols"},soon:{keywords:["arrow","words"],char:'\u{1f51c}',fitzpatrick_scale:!1,category:"symbols"},ballot_box_with_check:{keywords:["ok","agree","confirm","black-square","vote","election","yes","tick"],char:'\u2611\ufe0f',fitzpatrick_scale:!1,category:"symbols"},radio_button:{keywords:["input","old","music","circle"],char:'\u{1f518}',fitzpatrick_scale:!1,category:"symbols"},white_circle:{keywords:["shape","round"],char:'\u26aa',fitzpatrick_scale:!1,category:"symbols"},black_circle:{keywords:["shape","button","round"],char:'\u26ab',fitzpatrick_scale:!1,category:"symbols"},red_circle:{keywords:["shape","error","danger"],char:'\u{1f534}',fitzpatrick_scale:!1,category:"symbols"},large_blue_circle:{keywords:["shape","icon","button"],char:'\u{1f535}',fitzpatrick_scale:!1,category:"symbols"},small_orange_diamond:{keywords:["shape","jewel","gem"],char:'\u{1f538}',fitzpatrick_scale:!1,category:"symbols"},small_blue_diamond:{keywords:["shape","jewel","gem"],char:'\u{1f539}',fitzpatrick_scale:!1,category:"symbols"},large_orange_diamond:{keywords:["shape","jewel","gem"],char:'\u{1f536}',fitzpatrick_scale:!1,category:"symbols"},large_blue_diamond:{keywords:["shape","jewel","gem"],char:'\u{1f537}',fitzpatrick_scale:!1,category:"symbols"},small_red_triangle:{keywords:["shape","direction","up","top"],char:'\u{1f53a}',fitzpatrick_scale:!1,category:"symbols"},black_small_square:{keywords:["shape","icon"],char:'\u25aa\ufe0f',fitzpatrick_scale:!1,category:"symbols"},white_small_square:{keywords:["shape","icon"],char:'\u25ab\ufe0f',fitzpatrick_scale:!1,category:"symbols"},black_large_square:{keywords:["shape","icon","button"],char:'\u2b1b',fitzpatrick_scale:!1,category:"symbols"},white_large_square:{keywords:["shape","icon","stone","button"],char:'\u2b1c',fitzpatrick_scale:!1,category:"symbols"},small_red_triangle_down:{keywords:["shape","direction","bottom"],char:'\u{1f53b}',fitzpatrick_scale:!1,category:"symbols"},black_medium_square:{keywords:["shape","button","icon"],char:'\u25fc\ufe0f',fitzpatrick_scale:!1,category:"symbols"},white_medium_square:{keywords:["shape","stone","icon"],char:'\u25fb\ufe0f',fitzpatrick_scale:!1,category:"symbols"},black_medium_small_square:{keywords:["icon","shape","button"],char:'\u25fe',fitzpatrick_scale:!1,category:"symbols"},white_medium_small_square:{keywords:["shape","stone","icon","button"],char:'\u25fd',fitzpatrick_scale:!1,category:"symbols"},black_square_button:{keywords:["shape","input","frame"],char:'\u{1f532}',fitzpatrick_scale:!1,category:"symbols"},white_square_button:{keywords:["shape","input"],char:'\u{1f533}',fitzpatrick_scale:!1,category:"symbols"},speaker:{keywords:["sound","volume","silence","broadcast"],char:'\u{1f508}',fitzpatrick_scale:!1,category:"symbols"},sound:{keywords:["volume","speaker","broadcast"],char:'\u{1f509}',fitzpatrick_scale:!1,category:"symbols"},loud_sound:{keywords:["volume","noise","noisy","speaker","broadcast"],char:'\u{1f50a}',fitzpatrick_scale:!1,category:"symbols"},mute:{keywords:["sound","volume","silence","quiet"],char:'\u{1f507}',fitzpatrick_scale:!1,category:"symbols"},mega:{keywords:["sound","speaker","volume"],char:'\u{1f4e3}',fitzpatrick_scale:!1,category:"symbols"},loudspeaker:{keywords:["volume","sound"],char:'\u{1f4e2}',fitzpatrick_scale:!1,category:"symbols"},bell:{keywords:["sound","notification","christmas","xmas","chime"],char:'\u{1f514}',fitzpatrick_scale:!1,category:"symbols"},no_bell:{keywords:["sound","volume","mute","quiet","silent"],char:'\u{1f515}',fitzpatrick_scale:!1,category:"symbols"},black_joker:{keywords:["poker","cards","game","play","magic"],char:'\u{1f0cf}',fitzpatrick_scale:!1,category:"symbols"},mahjong:{keywords:["game","play","chinese","kanji"],char:'\u{1f004}',fitzpatrick_scale:!1,category:"symbols"},spades:{keywords:["poker","cards","suits","magic"],char:'\u2660\ufe0f',fitzpatrick_scale:!1,category:"symbols"},clubs:{keywords:["poker","cards","magic","suits"],char:'\u2663\ufe0f',fitzpatrick_scale:!1,category:"symbols"},hearts:{keywords:["poker","cards","magic","suits"],char:'\u2665\ufe0f',fitzpatrick_scale:!1,category:"symbols"},diamonds:{keywords:["poker","cards","magic","suits"],char:'\u2666\ufe0f',fitzpatrick_scale:!1,category:"symbols"},flower_playing_cards:{keywords:["game","sunset","red"],char:'\u{1f3b4}',fitzpatrick_scale:!1,category:"symbols"},thought_balloon:{keywords:["bubble","cloud","speech","thinking","dream"],char:'\u{1f4ad}',fitzpatrick_scale:!1,category:"symbols"},right_anger_bubble:{keywords:["caption","speech","thinking","mad"],char:'\u{1f5ef}',fitzpatrick_scale:!1,category:"symbols"},speech_balloon:{keywords:["bubble","words","message","talk","chatting"],char:'\u{1f4ac}',fitzpatrick_scale:!1,category:"symbols"},left_speech_bubble:{keywords:["words","message","talk","chatting"],char:'\u{1f5e8}',fitzpatrick_scale:!1,category:"symbols"},clock1:{keywords:["time","late","early","schedule"],char:'\u{1f550}',fitzpatrick_scale:!1,category:"symbols"},clock2:{keywords:["time","late","early","schedule"],char:'\u{1f551}',fitzpatrick_scale:!1,category:"symbols"},clock3:{keywords:["time","late","early","schedule"],char:'\u{1f552}',fitzpatrick_scale:!1,category:"symbols"},clock4:{keywords:["time","late","early","schedule"],char:'\u{1f553}',fitzpatrick_scale:!1,category:"symbols"},clock5:{keywords:["time","late","early","schedule"],char:'\u{1f554}',fitzpatrick_scale:!1,category:"symbols"},clock6:{keywords:["time","late","early","schedule","dawn","dusk"],char:'\u{1f555}',fitzpatrick_scale:!1,category:"symbols"},clock7:{keywords:["time","late","early","schedule"],char:'\u{1f556}',fitzpatrick_scale:!1,category:"symbols"},clock8:{keywords:["time","late","early","schedule"],char:'\u{1f557}',fitzpatrick_scale:!1,category:"symbols"},clock9:{keywords:["time","late","early","schedule"],char:'\u{1f558}',fitzpatrick_scale:!1,category:"symbols"},clock10:{keywords:["time","late","early","schedule"],char:'\u{1f559}',fitzpatrick_scale:!1,category:"symbols"},clock11:{keywords:["time","late","early","schedule"],char:'\u{1f55a}',fitzpatrick_scale:!1,category:"symbols"},clock12:{keywords:["time","noon","midnight","midday","late","early","schedule"],char:'\u{1f55b}',fitzpatrick_scale:!1,category:"symbols"},clock130:{keywords:["time","late","early","schedule"],char:'\u{1f55c}',fitzpatrick_scale:!1,category:"symbols"},clock230:{keywords:["time","late","early","schedule"],char:'\u{1f55d}',fitzpatrick_scale:!1,category:"symbols"},clock330:{keywords:["time","late","early","schedule"],char:'\u{1f55e}',fitzpatrick_scale:!1,category:"symbols"},clock430:{keywords:["time","late","early","schedule"],char:'\u{1f55f}',fitzpatrick_scale:!1,category:"symbols"},clock530:{keywords:["time","late","early","schedule"],char:'\u{1f560}',fitzpatrick_scale:!1,category:"symbols"},clock630:{keywords:["time","late","early","schedule"],char:'\u{1f561}',fitzpatrick_scale:!1,category:"symbols"},clock730:{keywords:["time","late","early","schedule"],char:'\u{1f562}',fitzpatrick_scale:!1,category:"symbols"},clock830:{keywords:["time","late","early","schedule"],char:'\u{1f563}',fitzpatrick_scale:!1,category:"symbols"},clock930:{keywords:["time","late","early","schedule"],char:'\u{1f564}',fitzpatrick_scale:!1,category:"symbols"},clock1030:{keywords:["time","late","early","schedule"],char:'\u{1f565}',fitzpatrick_scale:!1,category:"symbols"},clock1130:{keywords:["time","late","early","schedule"],char:'\u{1f566}',fitzpatrick_scale:!1,category:"symbols"},clock1230:{keywords:["time","late","early","schedule"],char:'\u{1f567}',fitzpatrick_scale:!1,category:"symbols"},afghanistan:{keywords:["af","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1eb}',fitzpatrick_scale:!1,category:"flags"},aland_islands:{keywords:["\xc5land","islands","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1fd}',fitzpatrick_scale:!1,category:"flags"},albania:{keywords:["al","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},algeria:{keywords:["dz","flag","nation","country","banner"],char:'\u{1f1e9}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},american_samoa:{keywords:["american","ws","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},andorra:{keywords:["ad","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1e9}',fitzpatrick_scale:!1,category:"flags"},angola:{keywords:["ao","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},anguilla:{keywords:["ai","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},antarctica:{keywords:["aq","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1f6}',fitzpatrick_scale:!1,category:"flags"},antigua_barbuda:{keywords:["antigua","barbuda","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},argentina:{keywords:["ar","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},armenia:{keywords:["am","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},aruba:{keywords:["aw","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},australia:{keywords:["au","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},austria:{keywords:["at","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},azerbaijan:{keywords:["az","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},bahamas:{keywords:["bs","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},bahrain:{keywords:["bh","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1ed}',fitzpatrick_scale:!1,category:"flags"},bangladesh:{keywords:["bd","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1e9}',fitzpatrick_scale:!1,category:"flags"},barbados:{keywords:["bb","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1e7}',fitzpatrick_scale:!1,category:"flags"},belarus:{keywords:["by","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1fe}',fitzpatrick_scale:!1,category:"flags"},belgium:{keywords:["be","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},belize:{keywords:["bz","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},benin:{keywords:["bj","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1ef}',fitzpatrick_scale:!1,category:"flags"},bermuda:{keywords:["bm","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},bhutan:{keywords:["bt","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},bolivia:{keywords:["bo","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},caribbean_netherlands:{keywords:["bonaire","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1f6}',fitzpatrick_scale:!1,category:"flags"},bosnia_herzegovina:{keywords:["bosnia","herzegovina","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},botswana:{keywords:["bw","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},brazil:{keywords:["br","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},british_indian_ocean_territory:{keywords:["british","indian","ocean","territory","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},british_virgin_islands:{keywords:["british","virgin","islands","bvi","flag","nation","country","banner"],char:'\u{1f1fb}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},brunei:{keywords:["bn","darussalam","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},bulgaria:{keywords:["bg","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},burkina_faso:{keywords:["burkina","faso","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1eb}',fitzpatrick_scale:!1,category:"flags"},burundi:{keywords:["bi","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},cape_verde:{keywords:["cabo","verde","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1fb}',fitzpatrick_scale:!1,category:"flags"},cambodia:{keywords:["kh","flag","nation","country","banner"],char:'\u{1f1f0}\u{1f1ed}',fitzpatrick_scale:!1,category:"flags"},cameroon:{keywords:["cm","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},canada:{keywords:["ca","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},canary_islands:{keywords:["canary","islands","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1e8}',fitzpatrick_scale:!1,category:"flags"},cayman_islands:{keywords:["cayman","islands","flag","nation","country","banner"],char:'\u{1f1f0}\u{1f1fe}',fitzpatrick_scale:!1,category:"flags"},central_african_republic:{keywords:["central","african","republic","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1eb}',fitzpatrick_scale:!1,category:"flags"},chad:{keywords:["td","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1e9}',fitzpatrick_scale:!1,category:"flags"},chile:{keywords:["flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},cn:{keywords:["china","chinese","prc","flag","country","nation","banner"],char:'\u{1f1e8}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},christmas_island:{keywords:["christmas","island","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1fd}',fitzpatrick_scale:!1,category:"flags"},cocos_islands:{keywords:["cocos","keeling","islands","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1e8}',fitzpatrick_scale:!1,category:"flags"},colombia:{keywords:["co","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},comoros:{keywords:["km","flag","nation","country","banner"],char:'\u{1f1f0}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},congo_brazzaville:{keywords:["congo","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},congo_kinshasa:{keywords:["congo","democratic","republic","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1e9}',fitzpatrick_scale:!1,category:"flags"},cook_islands:{keywords:["cook","islands","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},costa_rica:{keywords:["costa","rica","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},croatia:{keywords:["hr","flag","nation","country","banner"],char:'\u{1f1ed}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},cuba:{keywords:["cu","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},curacao:{keywords:["cura\xe7ao","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},cyprus:{keywords:["cy","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1fe}',fitzpatrick_scale:!1,category:"flags"},czech_republic:{keywords:["cz","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},denmark:{keywords:["dk","flag","nation","country","banner"],char:'\u{1f1e9}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},djibouti:{keywords:["dj","flag","nation","country","banner"],char:'\u{1f1e9}\u{1f1ef}',fitzpatrick_scale:!1,category:"flags"},dominica:{keywords:["dm","flag","nation","country","banner"],char:'\u{1f1e9}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},dominican_republic:{keywords:["dominican","republic","flag","nation","country","banner"],char:'\u{1f1e9}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},ecuador:{keywords:["ec","flag","nation","country","banner"],char:'\u{1f1ea}\u{1f1e8}',fitzpatrick_scale:!1,category:"flags"},egypt:{keywords:["eg","flag","nation","country","banner"],char:'\u{1f1ea}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},el_salvador:{keywords:["el","salvador","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1fb}',fitzpatrick_scale:!1,category:"flags"},equatorial_guinea:{keywords:["equatorial","gn","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1f6}',fitzpatrick_scale:!1,category:"flags"},eritrea:{keywords:["er","flag","nation","country","banner"],char:'\u{1f1ea}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},estonia:{keywords:["ee","flag","nation","country","banner"],char:'\u{1f1ea}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},ethiopia:{keywords:["et","flag","nation","country","banner"],char:'\u{1f1ea}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},eu:{keywords:["european","union","flag","banner"],char:'\u{1f1ea}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},falkland_islands:{keywords:["falkland","islands","malvinas","flag","nation","country","banner"],char:'\u{1f1eb}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},faroe_islands:{keywords:["faroe","islands","flag","nation","country","banner"],char:'\u{1f1eb}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},fiji:{keywords:["fj","flag","nation","country","banner"],char:'\u{1f1eb}\u{1f1ef}',fitzpatrick_scale:!1,category:"flags"},finland:{keywords:["fi","flag","nation","country","banner"],char:'\u{1f1eb}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},fr:{keywords:["banner","flag","nation","france","french","country"],char:'\u{1f1eb}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},french_guiana:{keywords:["french","guiana","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1eb}',fitzpatrick_scale:!1,category:"flags"},french_polynesia:{keywords:["french","polynesia","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1eb}',fitzpatrick_scale:!1,category:"flags"},french_southern_territories:{keywords:["french","southern","territories","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1eb}',fitzpatrick_scale:!1,category:"flags"},gabon:{keywords:["ga","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},gambia:{keywords:["gm","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},georgia:{keywords:["ge","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},de:{keywords:["german","nation","flag","country","banner"],char:'\u{1f1e9}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},ghana:{keywords:["gh","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1ed}',fitzpatrick_scale:!1,category:"flags"},gibraltar:{keywords:["gi","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},greece:{keywords:["gr","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},greenland:{keywords:["gl","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},grenada:{keywords:["gd","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1e9}',fitzpatrick_scale:!1,category:"flags"},guadeloupe:{keywords:["gp","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1f5}',fitzpatrick_scale:!1,category:"flags"},guam:{keywords:["gu","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},guatemala:{keywords:["gt","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},guernsey:{keywords:["gg","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},guinea:{keywords:["gn","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},guinea_bissau:{keywords:["gw","bissau","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},guyana:{keywords:["gy","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1fe}',fitzpatrick_scale:!1,category:"flags"},haiti:{keywords:["ht","flag","nation","country","banner"],char:'\u{1f1ed}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},honduras:{keywords:["hn","flag","nation","country","banner"],char:'\u{1f1ed}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},hong_kong:{keywords:["hong","kong","flag","nation","country","banner"],char:'\u{1f1ed}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},hungary:{keywords:["hu","flag","nation","country","banner"],char:'\u{1f1ed}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},iceland:{keywords:["is","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},india:{keywords:["in","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},indonesia:{keywords:["flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1e9}',fitzpatrick_scale:!1,category:"flags"},iran:{keywords:["iran,","islamic","republic","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},iraq:{keywords:["iq","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1f6}',fitzpatrick_scale:!1,category:"flags"},ireland:{keywords:["ie","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},isle_of_man:{keywords:["isle","man","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},israel:{keywords:["il","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},it:{keywords:["italy","flag","nation","country","banner"],char:'\u{1f1ee}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},cote_divoire:{keywords:["ivory","coast","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},jamaica:{keywords:["jm","flag","nation","country","banner"],char:'\u{1f1ef}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},jp:{keywords:["japanese","nation","flag","country","banner"],char:'\u{1f1ef}\u{1f1f5}',fitzpatrick_scale:!1,category:"flags"},jersey:{keywords:["je","flag","nation","country","banner"],char:'\u{1f1ef}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},jordan:{keywords:["jo","flag","nation","country","banner"],char:'\u{1f1ef}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},kazakhstan:{keywords:["kz","flag","nation","country","banner"],char:'\u{1f1f0}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},kenya:{keywords:["ke","flag","nation","country","banner"],char:'\u{1f1f0}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},kiribati:{keywords:["ki","flag","nation","country","banner"],char:'\u{1f1f0}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},kosovo:{keywords:["xk","flag","nation","country","banner"],char:'\u{1f1fd}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},kuwait:{keywords:["kw","flag","nation","country","banner"],char:'\u{1f1f0}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},kyrgyzstan:{keywords:["kg","flag","nation","country","banner"],char:'\u{1f1f0}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},laos:{keywords:["lao","democratic","republic","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},latvia:{keywords:["lv","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1fb}',fitzpatrick_scale:!1,category:"flags"},lebanon:{keywords:["lb","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1e7}',fitzpatrick_scale:!1,category:"flags"},lesotho:{keywords:["ls","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},liberia:{keywords:["lr","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},libya:{keywords:["ly","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1fe}',fitzpatrick_scale:!1,category:"flags"},liechtenstein:{keywords:["li","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},lithuania:{keywords:["lt","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},luxembourg:{keywords:["lu","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},macau:{keywords:["macao","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},macedonia:{keywords:["macedonia,","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},madagascar:{keywords:["mg","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},malawi:{keywords:["mw","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},malaysia:{keywords:["my","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1fe}',fitzpatrick_scale:!1,category:"flags"},maldives:{keywords:["mv","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1fb}',fitzpatrick_scale:!1,category:"flags"},mali:{keywords:["ml","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},malta:{keywords:["mt","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},marshall_islands:{keywords:["marshall","islands","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1ed}',fitzpatrick_scale:!1,category:"flags"},martinique:{keywords:["mq","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f6}',fitzpatrick_scale:!1,category:"flags"},mauritania:{keywords:["mr","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},mauritius:{keywords:["mu","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},mayotte:{keywords:["yt","flag","nation","country","banner"],char:'\u{1f1fe}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},mexico:{keywords:["mx","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1fd}',fitzpatrick_scale:!1,category:"flags"},micronesia:{keywords:["micronesia,","federated","states","flag","nation","country","banner"],char:'\u{1f1eb}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},moldova:{keywords:["moldova,","republic","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1e9}',fitzpatrick_scale:!1,category:"flags"},monaco:{keywords:["mc","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1e8}',fitzpatrick_scale:!1,category:"flags"},mongolia:{keywords:["mn","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},montenegro:{keywords:["me","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},montserrat:{keywords:["ms","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},morocco:{keywords:["ma","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},mozambique:{keywords:["mz","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},myanmar:{keywords:["mm","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},namibia:{keywords:["na","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},nauru:{keywords:["nr","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},nepal:{keywords:["np","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1f5}',fitzpatrick_scale:!1,category:"flags"},netherlands:{keywords:["nl","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},new_caledonia:{keywords:["new","caledonia","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1e8}',fitzpatrick_scale:!1,category:"flags"},new_zealand:{keywords:["new","zealand","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},nicaragua:{keywords:["ni","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},niger:{keywords:["ne","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},nigeria:{keywords:["flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},niue:{keywords:["nu","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},norfolk_island:{keywords:["norfolk","island","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1eb}',fitzpatrick_scale:!1,category:"flags"},northern_mariana_islands:{keywords:["northern","mariana","islands","flag","nation","country","banner"],char:'\u{1f1f2}\u{1f1f5}',fitzpatrick_scale:!1,category:"flags"},north_korea:{keywords:["north","korea","nation","flag","country","banner"],char:'\u{1f1f0}\u{1f1f5}',fitzpatrick_scale:!1,category:"flags"},norway:{keywords:["no","flag","nation","country","banner"],char:'\u{1f1f3}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},oman:{keywords:["om_symbol","flag","nation","country","banner"],char:'\u{1f1f4}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},pakistan:{keywords:["pk","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},palau:{keywords:["pw","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},palestinian_territories:{keywords:["palestine","palestinian","territories","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},panama:{keywords:["pa","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},papua_new_guinea:{keywords:["papua","new","guinea","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},paraguay:{keywords:["py","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1fe}',fitzpatrick_scale:!1,category:"flags"},peru:{keywords:["pe","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},philippines:{keywords:["ph","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1ed}',fitzpatrick_scale:!1,category:"flags"},pitcairn_islands:{keywords:["pitcairn","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},poland:{keywords:["pl","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},portugal:{keywords:["pt","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},puerto_rico:{keywords:["puerto","rico","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},qatar:{keywords:["qa","flag","nation","country","banner"],char:'\u{1f1f6}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},reunion:{keywords:["r\xe9union","flag","nation","country","banner"],char:'\u{1f1f7}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},romania:{keywords:["ro","flag","nation","country","banner"],char:'\u{1f1f7}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},ru:{keywords:["russian","federation","flag","nation","country","banner"],char:'\u{1f1f7}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},rwanda:{keywords:["rw","flag","nation","country","banner"],char:'\u{1f1f7}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},st_barthelemy:{keywords:["saint","barth\xe9lemy","flag","nation","country","banner"],char:'\u{1f1e7}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},st_helena:{keywords:["saint","helena","ascension","tristan","cunha","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1ed}',fitzpatrick_scale:!1,category:"flags"},st_kitts_nevis:{keywords:["saint","kitts","nevis","flag","nation","country","banner"],char:'\u{1f1f0}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},st_lucia:{keywords:["saint","lucia","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1e8}',fitzpatrick_scale:!1,category:"flags"},st_pierre_miquelon:{keywords:["saint","pierre","miquelon","flag","nation","country","banner"],char:'\u{1f1f5}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},st_vincent_grenadines:{keywords:["saint","vincent","grenadines","flag","nation","country","banner"],char:'\u{1f1fb}\u{1f1e8}',fitzpatrick_scale:!1,category:"flags"},samoa:{keywords:["ws","flag","nation","country","banner"],char:'\u{1f1fc}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},san_marino:{keywords:["san","marino","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},sao_tome_principe:{keywords:["sao","tome","principe","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},saudi_arabia:{keywords:["flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},senegal:{keywords:["sn","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},serbia:{keywords:["rs","flag","nation","country","banner"],char:'\u{1f1f7}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},seychelles:{keywords:["sc","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1e8}',fitzpatrick_scale:!1,category:"flags"},sierra_leone:{keywords:["sierra","leone","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},singapore:{keywords:["sg","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},sint_maarten:{keywords:["sint","maarten","dutch","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1fd}',fitzpatrick_scale:!1,category:"flags"},slovakia:{keywords:["sk","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},slovenia:{keywords:["si","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},solomon_islands:{keywords:["solomon","islands","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1e7}',fitzpatrick_scale:!1,category:"flags"},somalia:{keywords:["so","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},south_africa:{keywords:["south","africa","flag","nation","country","banner"],char:'\u{1f1ff}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},south_georgia_south_sandwich_islands:{keywords:["south","georgia","sandwich","islands","flag","nation","country","banner"],char:'\u{1f1ec}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},kr:{keywords:["south","korea","nation","flag","country","banner"],char:'\u{1f1f0}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},south_sudan:{keywords:["south","sd","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},es:{keywords:["spain","flag","nation","country","banner"],char:'\u{1f1ea}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},sri_lanka:{keywords:["sri","lanka","flag","nation","country","banner"],char:'\u{1f1f1}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},sudan:{keywords:["sd","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1e9}',fitzpatrick_scale:!1,category:"flags"},suriname:{keywords:["sr","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},swaziland:{keywords:["sz","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},sweden:{keywords:["se","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},switzerland:{keywords:["ch","flag","nation","country","banner"],char:'\u{1f1e8}\u{1f1ed}',fitzpatrick_scale:!1,category:"flags"},syria:{keywords:["syrian","arab","republic","flag","nation","country","banner"],char:'\u{1f1f8}\u{1f1fe}',fitzpatrick_scale:!1,category:"flags"},taiwan:{keywords:["tw","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},tajikistan:{keywords:["tj","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1ef}',fitzpatrick_scale:!1,category:"flags"},tanzania:{keywords:["tanzania,","united","republic","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},thailand:{keywords:["th","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1ed}',fitzpatrick_scale:!1,category:"flags"},timor_leste:{keywords:["timor","leste","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1f1}',fitzpatrick_scale:!1,category:"flags"},togo:{keywords:["tg","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},tokelau:{keywords:["tk","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1f0}',fitzpatrick_scale:!1,category:"flags"},tonga:{keywords:["to","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1f4}',fitzpatrick_scale:!1,category:"flags"},trinidad_tobago:{keywords:["trinidad","tobago","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1f9}',fitzpatrick_scale:!1,category:"flags"},tunisia:{keywords:["tn","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},tr:{keywords:["turkey","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1f7}',fitzpatrick_scale:!1,category:"flags"},turkmenistan:{keywords:["flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},turks_caicos_islands:{keywords:["turks","caicos","islands","flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1e8}',fitzpatrick_scale:!1,category:"flags"},tuvalu:{keywords:["flag","nation","country","banner"],char:'\u{1f1f9}\u{1f1fb}',fitzpatrick_scale:!1,category:"flags"},uganda:{keywords:["ug","flag","nation","country","banner"],char:'\u{1f1fa}\u{1f1ec}',fitzpatrick_scale:!1,category:"flags"},ukraine:{keywords:["ua","flag","nation","country","banner"],char:'\u{1f1fa}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},united_arab_emirates:{keywords:["united","arab","emirates","flag","nation","country","banner"],char:'\u{1f1e6}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},uk:{keywords:["united","kingdom","great","britain","northern","ireland","flag","nation","country","banner","british","UK","english","england","union jack"],char:'\u{1f1ec}\u{1f1e7}',fitzpatrick_scale:!1,category:"flags"},england:{keywords:["flag","english"],char:'\u{1f3f4}\u{e0067}\u{e0062}\u{e0065}\u{e006e}\u{e0067}\u{e007f}',fitzpatrick_scale:!1,category:"flags"},scotland:{keywords:["flag","scottish"],char:'\u{1f3f4}\u{e0067}\u{e0062}\u{e0073}\u{e0063}\u{e0074}\u{e007f}',fitzpatrick_scale:!1,category:"flags"},wales:{keywords:["flag","welsh"],char:'\u{1f3f4}\u{e0067}\u{e0062}\u{e0077}\u{e006c}\u{e0073}\u{e007f}',fitzpatrick_scale:!1,category:"flags"},us:{keywords:["united","states","america","flag","nation","country","banner"],char:'\u{1f1fa}\u{1f1f8}',fitzpatrick_scale:!1,category:"flags"},us_virgin_islands:{keywords:["virgin","islands","us","flag","nation","country","banner"],char:'\u{1f1fb}\u{1f1ee}',fitzpatrick_scale:!1,category:"flags"},uruguay:{keywords:["uy","flag","nation","country","banner"],char:'\u{1f1fa}\u{1f1fe}',fitzpatrick_scale:!1,category:"flags"},uzbekistan:{keywords:["uz","flag","nation","country","banner"],char:'\u{1f1fa}\u{1f1ff}',fitzpatrick_scale:!1,category:"flags"},vanuatu:{keywords:["vu","flag","nation","country","banner"],char:'\u{1f1fb}\u{1f1fa}',fitzpatrick_scale:!1,category:"flags"},vatican_city:{keywords:["vatican","city","flag","nation","country","banner"],char:'\u{1f1fb}\u{1f1e6}',fitzpatrick_scale:!1,category:"flags"},venezuela:{keywords:["ve","bolivarian","republic","flag","nation","country","banner"],char:'\u{1f1fb}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},vietnam:{keywords:["viet","nam","flag","nation","country","banner"],char:'\u{1f1fb}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},wallis_futuna:{keywords:["wallis","futuna","flag","nation","country","banner"],char:'\u{1f1fc}\u{1f1eb}',fitzpatrick_scale:!1,category:"flags"},western_sahara:{keywords:["western","sahara","flag","nation","country","banner"],char:'\u{1f1ea}\u{1f1ed}',fitzpatrick_scale:!1,category:"flags"},yemen:{keywords:["ye","flag","nation","country","banner"],char:'\u{1f1fe}\u{1f1ea}',fitzpatrick_scale:!1,category:"flags"},zambia:{keywords:["zm","flag","nation","country","banner"],char:'\u{1f1ff}\u{1f1f2}',fitzpatrick_scale:!1,category:"flags"},zimbabwe:{keywords:["zw","flag","nation","country","banner"],char:'\u{1f1ff}\u{1f1fc}',fitzpatrick_scale:!1,category:"flags"},united_nations:{keywords:["un","flag","banner"],char:'\u{1f1fa}\u{1f1f3}',fitzpatrick_scale:!1,category:"flags"},pirate_flag:{keywords:["skull","crossbones","flag","banner"],char:'\u{1f3f4}\u200d\u2620\ufe0f',fitzpatrick_scale:!1,category:"flags"}}); \ No newline at end of file diff --git a/static/js/tinymce/plugins/emoticons/js/emojis.js b/static/js/tinymce/plugins/emoticons/js/emojis.js new file mode 100644 index 0000000..88455e9 --- /dev/null +++ b/static/js/tinymce/plugins/emoticons/js/emojis.js @@ -0,0 +1 @@ +window.tinymce.Resource.add("tinymce.plugins.emoticons",{grinning:{keywords:["face","smile","happy","joy",":D","grin"],char:"😀",fitzpatrick_scale:false,category:"people"},grimacing:{keywords:["face","grimace","teeth"],char:"😬",fitzpatrick_scale:false,category:"people"},grin:{keywords:["face","happy","smile","joy","kawaii"],char:"😁",fitzpatrick_scale:false,category:"people"},joy:{keywords:["face","cry","tears","weep","happy","happytears","haha"],char:"😂",fitzpatrick_scale:false,category:"people"},rofl:{keywords:["face","rolling","floor","laughing","lol","haha"],char:"🤣",fitzpatrick_scale:false,category:"people"},partying:{keywords:["face","celebration","woohoo"],char:"🥳",fitzpatrick_scale:false,category:"people"},smiley:{keywords:["face","happy","joy","haha",":D",":)","smile","funny"],char:"😃",fitzpatrick_scale:false,category:"people"},smile:{keywords:["face","happy","joy","funny","haha","laugh","like",":D",":)"],char:"😄",fitzpatrick_scale:false,category:"people"},sweat_smile:{keywords:["face","hot","happy","laugh","sweat","smile","relief"],char:"😅",fitzpatrick_scale:false,category:"people"},laughing:{keywords:["happy","joy","lol","satisfied","haha","face","glad","XD","laugh"],char:"😆",fitzpatrick_scale:false,category:"people"},innocent:{keywords:["face","angel","heaven","halo"],char:"😇",fitzpatrick_scale:false,category:"people"},wink:{keywords:["face","happy","mischievous","secret",";)","smile","eye"],char:"😉",fitzpatrick_scale:false,category:"people"},blush:{keywords:["face","smile","happy","flushed","crush","embarrassed","shy","joy"],char:"😊",fitzpatrick_scale:false,category:"people"},slightly_smiling_face:{keywords:["face","smile"],char:"🙂",fitzpatrick_scale:false,category:"people"},upside_down_face:{keywords:["face","flipped","silly","smile"],char:"🙃",fitzpatrick_scale:false,category:"people"},relaxed:{keywords:["face","blush","massage","happiness"],char:"☺️",fitzpatrick_scale:false,category:"people"},yum:{keywords:["happy","joy","tongue","smile","face","silly","yummy","nom","delicious","savouring"],char:"😋",fitzpatrick_scale:false,category:"people"},relieved:{keywords:["face","relaxed","phew","massage","happiness"],char:"😌",fitzpatrick_scale:false,category:"people"},heart_eyes:{keywords:["face","love","like","affection","valentines","infatuation","crush","heart"],char:"😍",fitzpatrick_scale:false,category:"people"},smiling_face_with_three_hearts:{keywords:["face","love","like","affection","valentines","infatuation","crush","hearts","adore"],char:"🥰",fitzpatrick_scale:false,category:"people"},kissing_heart:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:"😘",fitzpatrick_scale:false,category:"people"},kissing:{keywords:["love","like","face","3","valentines","infatuation","kiss"],char:"😗",fitzpatrick_scale:false,category:"people"},kissing_smiling_eyes:{keywords:["face","affection","valentines","infatuation","kiss"],char:"😙",fitzpatrick_scale:false,category:"people"},kissing_closed_eyes:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:"😚",fitzpatrick_scale:false,category:"people"},stuck_out_tongue_winking_eye:{keywords:["face","prank","childish","playful","mischievous","smile","wink","tongue"],char:"😜",fitzpatrick_scale:false,category:"people"},zany:{keywords:["face","goofy","crazy"],char:"🤪",fitzpatrick_scale:false,category:"people"},raised_eyebrow:{keywords:["face","distrust","scepticism","disapproval","disbelief","surprise"],char:"🤨",fitzpatrick_scale:false,category:"people"},monocle:{keywords:["face","stuffy","wealthy"],char:"🧐",fitzpatrick_scale:false,category:"people"},stuck_out_tongue_closed_eyes:{keywords:["face","prank","playful","mischievous","smile","tongue"],char:"😝",fitzpatrick_scale:false,category:"people"},stuck_out_tongue:{keywords:["face","prank","childish","playful","mischievous","smile","tongue"],char:"😛",fitzpatrick_scale:false,category:"people"},money_mouth_face:{keywords:["face","rich","dollar","money"],char:"🤑",fitzpatrick_scale:false,category:"people"},nerd_face:{keywords:["face","nerdy","geek","dork"],char:"🤓",fitzpatrick_scale:false,category:"people"},sunglasses:{keywords:["face","cool","smile","summer","beach","sunglass"],char:"😎",fitzpatrick_scale:false,category:"people"},star_struck:{keywords:["face","smile","starry","eyes","grinning"],char:"🤩",fitzpatrick_scale:false,category:"people"},clown_face:{keywords:["face"],char:"🤡",fitzpatrick_scale:false,category:"people"},cowboy_hat_face:{keywords:["face","cowgirl","hat"],char:"🤠",fitzpatrick_scale:false,category:"people"},hugs:{keywords:["face","smile","hug"],char:"🤗",fitzpatrick_scale:false,category:"people"},smirk:{keywords:["face","smile","mean","prank","smug","sarcasm"],char:"😏",fitzpatrick_scale:false,category:"people"},no_mouth:{keywords:["face","hellokitty"],char:"😶",fitzpatrick_scale:false,category:"people"},neutral_face:{keywords:["indifference","meh",":|","neutral"],char:"😐",fitzpatrick_scale:false,category:"people"},expressionless:{keywords:["face","indifferent","-_-","meh","deadpan"],char:"😑",fitzpatrick_scale:false,category:"people"},unamused:{keywords:["indifference","bored","straight face","serious","sarcasm","unimpressed","skeptical","dubious","side_eye"],char:"😒",fitzpatrick_scale:false,category:"people"},roll_eyes:{keywords:["face","eyeroll","frustrated"],char:"🙄",fitzpatrick_scale:false,category:"people"},thinking:{keywords:["face","hmmm","think","consider"],char:"🤔",fitzpatrick_scale:false,category:"people"},lying_face:{keywords:["face","lie","pinocchio"],char:"🤥",fitzpatrick_scale:false,category:"people"},hand_over_mouth:{keywords:["face","whoops","shock","surprise"],char:"🤭",fitzpatrick_scale:false,category:"people"},shushing:{keywords:["face","quiet","shhh"],char:"🤫",fitzpatrick_scale:false,category:"people"},symbols_over_mouth:{keywords:["face","swearing","cursing","cussing","profanity","expletive"],char:"🤬",fitzpatrick_scale:false,category:"people"},exploding_head:{keywords:["face","shocked","mind","blown"],char:"🤯",fitzpatrick_scale:false,category:"people"},flushed:{keywords:["face","blush","shy","flattered"],char:"😳",fitzpatrick_scale:false,category:"people"},disappointed:{keywords:["face","sad","upset","depressed",":("],char:"😞",fitzpatrick_scale:false,category:"people"},worried:{keywords:["face","concern","nervous",":("],char:"😟",fitzpatrick_scale:false,category:"people"},angry:{keywords:["mad","face","annoyed","frustrated"],char:"😠",fitzpatrick_scale:false,category:"people"},rage:{keywords:["angry","mad","hate","despise"],char:"😡",fitzpatrick_scale:false,category:"people"},pensive:{keywords:["face","sad","depressed","upset"],char:"😔",fitzpatrick_scale:false,category:"people"},confused:{keywords:["face","indifference","huh","weird","hmmm",":/"],char:"😕",fitzpatrick_scale:false,category:"people"},slightly_frowning_face:{keywords:["face","frowning","disappointed","sad","upset"],char:"🙁",fitzpatrick_scale:false,category:"people"},frowning_face:{keywords:["face","sad","upset","frown"],char:"☹",fitzpatrick_scale:false,category:"people"},persevere:{keywords:["face","sick","no","upset","oops"],char:"😣",fitzpatrick_scale:false,category:"people"},confounded:{keywords:["face","confused","sick","unwell","oops",":S"],char:"😖",fitzpatrick_scale:false,category:"people"},tired_face:{keywords:["sick","whine","upset","frustrated"],char:"😫",fitzpatrick_scale:false,category:"people"},weary:{keywords:["face","tired","sleepy","sad","frustrated","upset"],char:"😩",fitzpatrick_scale:false,category:"people"},pleading:{keywords:["face","begging","mercy"],char:"🥺",fitzpatrick_scale:false,category:"people"},triumph:{keywords:["face","gas","phew","proud","pride"],char:"😤",fitzpatrick_scale:false,category:"people"},open_mouth:{keywords:["face","surprise","impressed","wow","whoa",":O"],char:"😮",fitzpatrick_scale:false,category:"people"},scream:{keywords:["face","munch","scared","omg"],char:"😱",fitzpatrick_scale:false,category:"people"},fearful:{keywords:["face","scared","terrified","nervous","oops","huh"],char:"😨",fitzpatrick_scale:false,category:"people"},cold_sweat:{keywords:["face","nervous","sweat"],char:"😰",fitzpatrick_scale:false,category:"people"},hushed:{keywords:["face","woo","shh"],char:"😯",fitzpatrick_scale:false,category:"people"},frowning:{keywords:["face","aw","what"],char:"😦",fitzpatrick_scale:false,category:"people"},anguished:{keywords:["face","stunned","nervous"],char:"😧",fitzpatrick_scale:false,category:"people"},cry:{keywords:["face","tears","sad","depressed","upset",":'("],char:"😢",fitzpatrick_scale:false,category:"people"},disappointed_relieved:{keywords:["face","phew","sweat","nervous"],char:"😥",fitzpatrick_scale:false,category:"people"},drooling_face:{keywords:["face"],char:"🤤",fitzpatrick_scale:false,category:"people"},sleepy:{keywords:["face","tired","rest","nap"],char:"😪",fitzpatrick_scale:false,category:"people"},sweat:{keywords:["face","hot","sad","tired","exercise"],char:"😓",fitzpatrick_scale:false,category:"people"},hot:{keywords:["face","feverish","heat","red","sweating"],char:"🥵",fitzpatrick_scale:false,category:"people"},cold:{keywords:["face","blue","freezing","frozen","frostbite","icicles"],char:"🥶",fitzpatrick_scale:false,category:"people"},sob:{keywords:["face","cry","tears","sad","upset","depressed"],char:"😭",fitzpatrick_scale:false,category:"people"},dizzy_face:{keywords:["spent","unconscious","xox","dizzy"],char:"😵",fitzpatrick_scale:false,category:"people"},astonished:{keywords:["face","xox","surprised","poisoned"],char:"😲",fitzpatrick_scale:false,category:"people"},zipper_mouth_face:{keywords:["face","sealed","zipper","secret"],char:"🤐",fitzpatrick_scale:false,category:"people"},nauseated_face:{keywords:["face","vomit","gross","green","sick","throw up","ill"],char:"🤢",fitzpatrick_scale:false,category:"people"},sneezing_face:{keywords:["face","gesundheit","sneeze","sick","allergy"],char:"🤧",fitzpatrick_scale:false,category:"people"},vomiting:{keywords:["face","sick"],char:"🤮",fitzpatrick_scale:false,category:"people"},mask:{keywords:["face","sick","ill","disease"],char:"😷",fitzpatrick_scale:false,category:"people"},face_with_thermometer:{keywords:["sick","temperature","thermometer","cold","fever"],char:"🤒",fitzpatrick_scale:false,category:"people"},face_with_head_bandage:{keywords:["injured","clumsy","bandage","hurt"],char:"🤕",fitzpatrick_scale:false,category:"people"},woozy:{keywords:["face","dizzy","intoxicated","tipsy","wavy"],char:"🥴",fitzpatrick_scale:false,category:"people"},sleeping:{keywords:["face","tired","sleepy","night","zzz"],char:"😴",fitzpatrick_scale:false,category:"people"},zzz:{keywords:["sleepy","tired","dream"],char:"💤",fitzpatrick_scale:false,category:"people"},poop:{keywords:["hankey","shitface","fail","turd","shit"],char:"💩",fitzpatrick_scale:false,category:"people"},smiling_imp:{keywords:["devil","horns"],char:"😈",fitzpatrick_scale:false,category:"people"},imp:{keywords:["devil","angry","horns"],char:"👿",fitzpatrick_scale:false,category:"people"},japanese_ogre:{keywords:["monster","red","mask","halloween","scary","creepy","devil","demon","japanese","ogre"],char:"👹",fitzpatrick_scale:false,category:"people"},japanese_goblin:{keywords:["red","evil","mask","monster","scary","creepy","japanese","goblin"],char:"👺",fitzpatrick_scale:false,category:"people"},skull:{keywords:["dead","skeleton","creepy","death"],char:"💀",fitzpatrick_scale:false,category:"people"},ghost:{keywords:["halloween","spooky","scary"],char:"👻",fitzpatrick_scale:false,category:"people"},alien:{keywords:["UFO","paul","weird","outer_space"],char:"👽",fitzpatrick_scale:false,category:"people"},robot:{keywords:["computer","machine","bot"],char:"🤖",fitzpatrick_scale:false,category:"people"},smiley_cat:{keywords:["animal","cats","happy","smile"],char:"😺",fitzpatrick_scale:false,category:"people"},smile_cat:{keywords:["animal","cats","smile"],char:"😸",fitzpatrick_scale:false,category:"people"},joy_cat:{keywords:["animal","cats","haha","happy","tears"],char:"😹",fitzpatrick_scale:false,category:"people"},heart_eyes_cat:{keywords:["animal","love","like","affection","cats","valentines","heart"],char:"😻",fitzpatrick_scale:false,category:"people"},smirk_cat:{keywords:["animal","cats","smirk"],char:"😼",fitzpatrick_scale:false,category:"people"},kissing_cat:{keywords:["animal","cats","kiss"],char:"😽",fitzpatrick_scale:false,category:"people"},scream_cat:{keywords:["animal","cats","munch","scared","scream"],char:"🙀",fitzpatrick_scale:false,category:"people"},crying_cat_face:{keywords:["animal","tears","weep","sad","cats","upset","cry"],char:"😿",fitzpatrick_scale:false,category:"people"},pouting_cat:{keywords:["animal","cats"],char:"😾",fitzpatrick_scale:false,category:"people"},palms_up:{keywords:["hands","gesture","cupped","prayer"],char:"🤲",fitzpatrick_scale:true,category:"people"},raised_hands:{keywords:["gesture","hooray","yea","celebration","hands"],char:"🙌",fitzpatrick_scale:true,category:"people"},clap:{keywords:["hands","praise","applause","congrats","yay"],char:"👏",fitzpatrick_scale:true,category:"people"},wave:{keywords:["hands","gesture","goodbye","solong","farewell","hello","hi","palm"],char:"👋",fitzpatrick_scale:true,category:"people"},call_me_hand:{keywords:["hands","gesture"],char:"🤙",fitzpatrick_scale:true,category:"people"},"+1":{keywords:["thumbsup","yes","awesome","good","agree","accept","cool","hand","like"],char:"👍",fitzpatrick_scale:true,category:"people"},"-1":{keywords:["thumbsdown","no","dislike","hand"],char:"👎",fitzpatrick_scale:true,category:"people"},facepunch:{keywords:["angry","violence","fist","hit","attack","hand"],char:"👊",fitzpatrick_scale:true,category:"people"},fist:{keywords:["fingers","hand","grasp"],char:"✊",fitzpatrick_scale:true,category:"people"},fist_left:{keywords:["hand","fistbump"],char:"🤛",fitzpatrick_scale:true,category:"people"},fist_right:{keywords:["hand","fistbump"],char:"🤜",fitzpatrick_scale:true,category:"people"},v:{keywords:["fingers","ohyeah","hand","peace","victory","two"],char:"✌",fitzpatrick_scale:true,category:"people"},ok_hand:{keywords:["fingers","limbs","perfect","ok","okay"],char:"👌",fitzpatrick_scale:true,category:"people"},raised_hand:{keywords:["fingers","stop","highfive","palm","ban"],char:"✋",fitzpatrick_scale:true,category:"people"},raised_back_of_hand:{keywords:["fingers","raised","backhand"],char:"🤚",fitzpatrick_scale:true,category:"people"},open_hands:{keywords:["fingers","butterfly","hands","open"],char:"👐",fitzpatrick_scale:true,category:"people"},muscle:{keywords:["arm","flex","hand","summer","strong","biceps"],char:"💪",fitzpatrick_scale:true,category:"people"},pray:{keywords:["please","hope","wish","namaste","highfive"],char:"🙏",fitzpatrick_scale:true,category:"people"},foot:{keywords:["kick","stomp"],char:"🦶",fitzpatrick_scale:true,category:"people"},leg:{keywords:["kick","limb"],char:"🦵",fitzpatrick_scale:true,category:"people"},handshake:{keywords:["agreement","shake"],char:"🤝",fitzpatrick_scale:false,category:"people"},point_up:{keywords:["hand","fingers","direction","up"],char:"☝",fitzpatrick_scale:true,category:"people"},point_up_2:{keywords:["fingers","hand","direction","up"],char:"👆",fitzpatrick_scale:true,category:"people"},point_down:{keywords:["fingers","hand","direction","down"],char:"👇",fitzpatrick_scale:true,category:"people"},point_left:{keywords:["direction","fingers","hand","left"],char:"👈",fitzpatrick_scale:true,category:"people"},point_right:{keywords:["fingers","hand","direction","right"],char:"👉",fitzpatrick_scale:true,category:"people"},fu:{keywords:["hand","fingers","rude","middle","flipping"],char:"🖕",fitzpatrick_scale:true,category:"people"},raised_hand_with_fingers_splayed:{keywords:["hand","fingers","palm"],char:"🖐",fitzpatrick_scale:true,category:"people"},love_you:{keywords:["hand","fingers","gesture"],char:"🤟",fitzpatrick_scale:true,category:"people"},metal:{keywords:["hand","fingers","evil_eye","sign_of_horns","rock_on"],char:"🤘",fitzpatrick_scale:true,category:"people"},crossed_fingers:{keywords:["good","lucky"],char:"🤞",fitzpatrick_scale:true,category:"people"},vulcan_salute:{keywords:["hand","fingers","spock","star trek"],char:"🖖",fitzpatrick_scale:true,category:"people"},writing_hand:{keywords:["lower_left_ballpoint_pen","stationery","write","compose"],char:"✍",fitzpatrick_scale:true,category:"people"},selfie:{keywords:["camera","phone"],char:"🤳",fitzpatrick_scale:true,category:"people"},nail_care:{keywords:["beauty","manicure","finger","fashion","nail"],char:"💅",fitzpatrick_scale:true,category:"people"},lips:{keywords:["mouth","kiss"],char:"👄",fitzpatrick_scale:false,category:"people"},tooth:{keywords:["teeth","dentist"],char:"🦷",fitzpatrick_scale:false,category:"people"},tongue:{keywords:["mouth","playful"],char:"👅",fitzpatrick_scale:false,category:"people"},ear:{keywords:["face","hear","sound","listen"],char:"👂",fitzpatrick_scale:true,category:"people"},nose:{keywords:["smell","sniff"],char:"👃",fitzpatrick_scale:true,category:"people"},eye:{keywords:["face","look","see","watch","stare"],char:"👁",fitzpatrick_scale:false,category:"people"},eyes:{keywords:["look","watch","stalk","peek","see"],char:"👀",fitzpatrick_scale:false,category:"people"},brain:{keywords:["smart","intelligent"],char:"🧠",fitzpatrick_scale:false,category:"people"},bust_in_silhouette:{keywords:["user","person","human"],char:"👤",fitzpatrick_scale:false,category:"people"},busts_in_silhouette:{keywords:["user","person","human","group","team"],char:"👥",fitzpatrick_scale:false,category:"people"},speaking_head:{keywords:["user","person","human","sing","say","talk"],char:"🗣",fitzpatrick_scale:false,category:"people"},baby:{keywords:["child","boy","girl","toddler"],char:"👶",fitzpatrick_scale:true,category:"people"},child:{keywords:["gender-neutral","young"],char:"🧒",fitzpatrick_scale:true,category:"people"},boy:{keywords:["man","male","guy","teenager"],char:"👦",fitzpatrick_scale:true,category:"people"},girl:{keywords:["female","woman","teenager"],char:"👧",fitzpatrick_scale:true,category:"people"},adult:{keywords:["gender-neutral","person"],char:"🧑",fitzpatrick_scale:true,category:"people"},man:{keywords:["mustache","father","dad","guy","classy","sir","moustache"],char:"👨",fitzpatrick_scale:true,category:"people"},woman:{keywords:["female","girls","lady"],char:"👩",fitzpatrick_scale:true,category:"people"},blonde_woman:{keywords:["woman","female","girl","blonde","person"],char:"👱‍♀️",fitzpatrick_scale:true,category:"people"},blonde_man:{keywords:["man","male","boy","blonde","guy","person"],char:"👱",fitzpatrick_scale:true,category:"people"},bearded_person:{keywords:["person","bewhiskered"],char:"🧔",fitzpatrick_scale:true,category:"people"},older_adult:{keywords:["human","elder","senior","gender-neutral"],char:"🧓",fitzpatrick_scale:true,category:"people"},older_man:{keywords:["human","male","men","old","elder","senior"],char:"👴",fitzpatrick_scale:true,category:"people"},older_woman:{keywords:["human","female","women","lady","old","elder","senior"],char:"👵",fitzpatrick_scale:true,category:"people"},man_with_gua_pi_mao:{keywords:["male","boy","chinese"],char:"👲",fitzpatrick_scale:true,category:"people"},woman_with_headscarf:{keywords:["female","hijab","mantilla","tichel"],char:"🧕",fitzpatrick_scale:true,category:"people"},woman_with_turban:{keywords:["female","indian","hinduism","arabs","woman"],char:"👳‍♀️",fitzpatrick_scale:true,category:"people"},man_with_turban:{keywords:["male","indian","hinduism","arabs"],char:"👳",fitzpatrick_scale:true,category:"people"},policewoman:{keywords:["woman","police","law","legal","enforcement","arrest","911","female"],char:"👮‍♀️",fitzpatrick_scale:true,category:"people"},policeman:{keywords:["man","police","law","legal","enforcement","arrest","911"],char:"👮",fitzpatrick_scale:true,category:"people"},construction_worker_woman:{keywords:["female","human","wip","build","construction","worker","labor","woman"],char:"👷‍♀️",fitzpatrick_scale:true,category:"people"},construction_worker_man:{keywords:["male","human","wip","guy","build","construction","worker","labor"],char:"👷",fitzpatrick_scale:true,category:"people"},guardswoman:{keywords:["uk","gb","british","female","royal","woman"],char:"💂‍♀️",fitzpatrick_scale:true,category:"people"},guardsman:{keywords:["uk","gb","british","male","guy","royal"],char:"💂",fitzpatrick_scale:true,category:"people"},female_detective:{keywords:["human","spy","detective","female","woman"],char:"🕵️‍♀️",fitzpatrick_scale:true,category:"people"},male_detective:{keywords:["human","spy","detective"],char:"🕵",fitzpatrick_scale:true,category:"people"},woman_health_worker:{keywords:["doctor","nurse","therapist","healthcare","woman","human"],char:"👩‍⚕️",fitzpatrick_scale:true,category:"people"},man_health_worker:{keywords:["doctor","nurse","therapist","healthcare","man","human"],char:"👨‍⚕️",fitzpatrick_scale:true,category:"people"},woman_farmer:{keywords:["rancher","gardener","woman","human"],char:"👩‍🌾",fitzpatrick_scale:true,category:"people"},man_farmer:{keywords:["rancher","gardener","man","human"],char:"👨‍🌾",fitzpatrick_scale:true,category:"people"},woman_cook:{keywords:["chef","woman","human"],char:"👩‍🍳",fitzpatrick_scale:true,category:"people"},man_cook:{keywords:["chef","man","human"],char:"👨‍🍳",fitzpatrick_scale:true,category:"people"},woman_student:{keywords:["graduate","woman","human"],char:"👩‍🎓",fitzpatrick_scale:true,category:"people"},man_student:{keywords:["graduate","man","human"],char:"👨‍🎓",fitzpatrick_scale:true,category:"people"},woman_singer:{keywords:["rockstar","entertainer","woman","human"],char:"👩‍🎤",fitzpatrick_scale:true,category:"people"},man_singer:{keywords:["rockstar","entertainer","man","human"],char:"👨‍🎤",fitzpatrick_scale:true,category:"people"},woman_teacher:{keywords:["instructor","professor","woman","human"],char:"👩‍🏫",fitzpatrick_scale:true,category:"people"},man_teacher:{keywords:["instructor","professor","man","human"],char:"👨‍🏫",fitzpatrick_scale:true,category:"people"},woman_factory_worker:{keywords:["assembly","industrial","woman","human"],char:"👩‍🏭",fitzpatrick_scale:true,category:"people"},man_factory_worker:{keywords:["assembly","industrial","man","human"],char:"👨‍🏭",fitzpatrick_scale:true,category:"people"},woman_technologist:{keywords:["coder","developer","engineer","programmer","software","woman","human","laptop","computer"],char:"👩‍💻",fitzpatrick_scale:true,category:"people"},man_technologist:{keywords:["coder","developer","engineer","programmer","software","man","human","laptop","computer"],char:"👨‍💻",fitzpatrick_scale:true,category:"people"},woman_office_worker:{keywords:["business","manager","woman","human"],char:"👩‍💼",fitzpatrick_scale:true,category:"people"},man_office_worker:{keywords:["business","manager","man","human"],char:"👨‍💼",fitzpatrick_scale:true,category:"people"},woman_mechanic:{keywords:["plumber","woman","human","wrench"],char:"👩‍🔧",fitzpatrick_scale:true,category:"people"},man_mechanic:{keywords:["plumber","man","human","wrench"],char:"👨‍🔧",fitzpatrick_scale:true,category:"people"},woman_scientist:{keywords:["biologist","chemist","engineer","physicist","woman","human"],char:"👩‍🔬",fitzpatrick_scale:true,category:"people"},man_scientist:{keywords:["biologist","chemist","engineer","physicist","man","human"],char:"👨‍🔬",fitzpatrick_scale:true,category:"people"},woman_artist:{keywords:["painter","woman","human"],char:"👩‍🎨",fitzpatrick_scale:true,category:"people"},man_artist:{keywords:["painter","man","human"],char:"👨‍🎨",fitzpatrick_scale:true,category:"people"},woman_firefighter:{keywords:["fireman","woman","human"],char:"👩‍🚒",fitzpatrick_scale:true,category:"people"},man_firefighter:{keywords:["fireman","man","human"],char:"👨‍🚒",fitzpatrick_scale:true,category:"people"},woman_pilot:{keywords:["aviator","plane","woman","human"],char:"👩‍✈️",fitzpatrick_scale:true,category:"people"},man_pilot:{keywords:["aviator","plane","man","human"],char:"👨‍✈️",fitzpatrick_scale:true,category:"people"},woman_astronaut:{keywords:["space","rocket","woman","human"],char:"👩‍🚀",fitzpatrick_scale:true,category:"people"},man_astronaut:{keywords:["space","rocket","man","human"],char:"👨‍🚀",fitzpatrick_scale:true,category:"people"},woman_judge:{keywords:["justice","court","woman","human"],char:"👩‍⚖️",fitzpatrick_scale:true,category:"people"},man_judge:{keywords:["justice","court","man","human"],char:"👨‍⚖️",fitzpatrick_scale:true,category:"people"},woman_superhero:{keywords:["woman","female","good","heroine","superpowers"],char:"🦸‍♀️",fitzpatrick_scale:true,category:"people"},man_superhero:{keywords:["man","male","good","hero","superpowers"],char:"🦸‍♂️",fitzpatrick_scale:true,category:"people"},woman_supervillain:{keywords:["woman","female","evil","bad","criminal","heroine","superpowers"],char:"🦹‍♀️",fitzpatrick_scale:true,category:"people"},man_supervillain:{keywords:["man","male","evil","bad","criminal","hero","superpowers"],char:"🦹‍♂️",fitzpatrick_scale:true,category:"people"},mrs_claus:{keywords:["woman","female","xmas","mother christmas"],char:"🤶",fitzpatrick_scale:true,category:"people"},santa:{keywords:["festival","man","male","xmas","father christmas"],char:"🎅",fitzpatrick_scale:true,category:"people"},sorceress:{keywords:["woman","female","mage","witch"],char:"🧙‍♀️",fitzpatrick_scale:true,category:"people"},wizard:{keywords:["man","male","mage","sorcerer"],char:"🧙‍♂️",fitzpatrick_scale:true,category:"people"},woman_elf:{keywords:["woman","female"],char:"🧝‍♀️",fitzpatrick_scale:true,category:"people"},man_elf:{keywords:["man","male"],char:"🧝‍♂️",fitzpatrick_scale:true,category:"people"},woman_vampire:{keywords:["woman","female"],char:"🧛‍♀️",fitzpatrick_scale:true,category:"people"},man_vampire:{keywords:["man","male","dracula"],char:"🧛‍♂️",fitzpatrick_scale:true,category:"people"},woman_zombie:{keywords:["woman","female","undead","walking dead"],char:"🧟‍♀️",fitzpatrick_scale:false,category:"people"},man_zombie:{keywords:["man","male","dracula","undead","walking dead"],char:"🧟‍♂️",fitzpatrick_scale:false,category:"people"},woman_genie:{keywords:["woman","female"],char:"🧞‍♀️",fitzpatrick_scale:false,category:"people"},man_genie:{keywords:["man","male"],char:"🧞‍♂️",fitzpatrick_scale:false,category:"people"},mermaid:{keywords:["woman","female","merwoman","ariel"],char:"🧜‍♀️",fitzpatrick_scale:true,category:"people"},merman:{keywords:["man","male","triton"],char:"🧜‍♂️",fitzpatrick_scale:true,category:"people"},woman_fairy:{keywords:["woman","female"],char:"🧚‍♀️",fitzpatrick_scale:true,category:"people"},man_fairy:{keywords:["man","male"],char:"🧚‍♂️",fitzpatrick_scale:true,category:"people"},angel:{keywords:["heaven","wings","halo"],char:"👼",fitzpatrick_scale:true,category:"people"},pregnant_woman:{keywords:["baby"],char:"🤰",fitzpatrick_scale:true,category:"people"},breastfeeding:{keywords:["nursing","baby"],char:"🤱",fitzpatrick_scale:true,category:"people"},princess:{keywords:["girl","woman","female","blond","crown","royal","queen"],char:"👸",fitzpatrick_scale:true,category:"people"},prince:{keywords:["boy","man","male","crown","royal","king"],char:"🤴",fitzpatrick_scale:true,category:"people"},bride_with_veil:{keywords:["couple","marriage","wedding","woman","bride"],char:"👰",fitzpatrick_scale:true,category:"people"},man_in_tuxedo:{keywords:["couple","marriage","wedding","groom"],char:"🤵",fitzpatrick_scale:true,category:"people"},running_woman:{keywords:["woman","walking","exercise","race","running","female"],char:"🏃‍♀️",fitzpatrick_scale:true,category:"people"},running_man:{keywords:["man","walking","exercise","race","running"],char:"🏃",fitzpatrick_scale:true,category:"people"},walking_woman:{keywords:["human","feet","steps","woman","female"],char:"🚶‍♀️",fitzpatrick_scale:true,category:"people"},walking_man:{keywords:["human","feet","steps"],char:"🚶",fitzpatrick_scale:true,category:"people"},dancer:{keywords:["female","girl","woman","fun"],char:"💃",fitzpatrick_scale:true,category:"people"},man_dancing:{keywords:["male","boy","fun","dancer"],char:"🕺",fitzpatrick_scale:true,category:"people"},dancing_women:{keywords:["female","bunny","women","girls"],char:"👯",fitzpatrick_scale:false,category:"people"},dancing_men:{keywords:["male","bunny","men","boys"],char:"👯‍♂️",fitzpatrick_scale:false,category:"people"},couple:{keywords:["pair","people","human","love","date","dating","like","affection","valentines","marriage"],char:"👫",fitzpatrick_scale:false,category:"people"},two_men_holding_hands:{keywords:["pair","couple","love","like","bromance","friendship","people","human"],char:"👬",fitzpatrick_scale:false,category:"people"},two_women_holding_hands:{keywords:["pair","friendship","couple","love","like","female","people","human"],char:"👭",fitzpatrick_scale:false,category:"people"},bowing_woman:{keywords:["woman","female","girl"],char:"🙇‍♀️",fitzpatrick_scale:true,category:"people"},bowing_man:{keywords:["man","male","boy"],char:"🙇",fitzpatrick_scale:true,category:"people"},man_facepalming:{keywords:["man","male","boy","disbelief"],char:"🤦‍♂️",fitzpatrick_scale:true,category:"people"},woman_facepalming:{keywords:["woman","female","girl","disbelief"],char:"🤦‍♀️",fitzpatrick_scale:true,category:"people"},woman_shrugging:{keywords:["woman","female","girl","confused","indifferent","doubt"],char:"🤷",fitzpatrick_scale:true,category:"people"},man_shrugging:{keywords:["man","male","boy","confused","indifferent","doubt"],char:"🤷‍♂️",fitzpatrick_scale:true,category:"people"},tipping_hand_woman:{keywords:["female","girl","woman","human","information"],char:"💁",fitzpatrick_scale:true,category:"people"},tipping_hand_man:{keywords:["male","boy","man","human","information"],char:"💁‍♂️",fitzpatrick_scale:true,category:"people"},no_good_woman:{keywords:["female","girl","woman","nope"],char:"🙅",fitzpatrick_scale:true,category:"people"},no_good_man:{keywords:["male","boy","man","nope"],char:"🙅‍♂️",fitzpatrick_scale:true,category:"people"},ok_woman:{keywords:["women","girl","female","pink","human","woman"],char:"🙆",fitzpatrick_scale:true,category:"people"},ok_man:{keywords:["men","boy","male","blue","human","man"],char:"🙆‍♂️",fitzpatrick_scale:true,category:"people"},raising_hand_woman:{keywords:["female","girl","woman"],char:"🙋",fitzpatrick_scale:true,category:"people"},raising_hand_man:{keywords:["male","boy","man"],char:"🙋‍♂️",fitzpatrick_scale:true,category:"people"},pouting_woman:{keywords:["female","girl","woman"],char:"🙎",fitzpatrick_scale:true,category:"people"},pouting_man:{keywords:["male","boy","man"],char:"🙎‍♂️",fitzpatrick_scale:true,category:"people"},frowning_woman:{keywords:["female","girl","woman","sad","depressed","discouraged","unhappy"],char:"🙍",fitzpatrick_scale:true,category:"people"},frowning_man:{keywords:["male","boy","man","sad","depressed","discouraged","unhappy"],char:"🙍‍♂️",fitzpatrick_scale:true,category:"people"},haircut_woman:{keywords:["female","girl","woman"],char:"💇",fitzpatrick_scale:true,category:"people"},haircut_man:{keywords:["male","boy","man"],char:"💇‍♂️",fitzpatrick_scale:true,category:"people"},massage_woman:{keywords:["female","girl","woman","head"],char:"💆",fitzpatrick_scale:true,category:"people"},massage_man:{keywords:["male","boy","man","head"],char:"💆‍♂️",fitzpatrick_scale:true,category:"people"},woman_in_steamy_room:{keywords:["female","woman","spa","steamroom","sauna"],char:"🧖‍♀️",fitzpatrick_scale:true,category:"people"},man_in_steamy_room:{keywords:["male","man","spa","steamroom","sauna"],char:"🧖‍♂️",fitzpatrick_scale:true,category:"people"},couple_with_heart_woman_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:"💑",fitzpatrick_scale:false,category:"people"},couple_with_heart_woman_woman:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:"👩‍❤️‍👩",fitzpatrick_scale:false,category:"people"},couple_with_heart_man_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:"👨‍❤️‍👨",fitzpatrick_scale:false,category:"people"},couplekiss_man_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:"💏",fitzpatrick_scale:false,category:"people"},couplekiss_woman_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:"👩‍❤️‍💋‍👩",fitzpatrick_scale:false,category:"people"},couplekiss_man_man:{keywords:["pair","valentines","love","like","dating","marriage"],char:"👨‍❤️‍💋‍👨",fitzpatrick_scale:false,category:"people"},family_man_woman_boy:{keywords:["home","parents","child","mom","dad","father","mother","people","human"],char:"👪",fitzpatrick_scale:false,category:"people"},family_man_woman_girl:{keywords:["home","parents","people","human","child"],char:"👨‍👩‍👧",fitzpatrick_scale:false,category:"people"},family_man_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:"👨‍👩‍👧‍👦",fitzpatrick_scale:false,category:"people"},family_man_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:"👨‍👩‍👦‍👦",fitzpatrick_scale:false,category:"people"},family_man_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:"👨‍👩‍👧‍👧",fitzpatrick_scale:false,category:"people"},family_woman_woman_boy:{keywords:["home","parents","people","human","children"],char:"👩‍👩‍👦",fitzpatrick_scale:false,category:"people"},family_woman_woman_girl:{keywords:["home","parents","people","human","children"],char:"👩‍👩‍👧",fitzpatrick_scale:false,category:"people"},family_woman_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:"👩‍👩‍👧‍👦",fitzpatrick_scale:false,category:"people"},family_woman_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:"👩‍👩‍👦‍👦",fitzpatrick_scale:false,category:"people"},family_woman_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:"👩‍👩‍👧‍👧",fitzpatrick_scale:false,category:"people"},family_man_man_boy:{keywords:["home","parents","people","human","children"],char:"👨‍👨‍👦",fitzpatrick_scale:false,category:"people"},family_man_man_girl:{keywords:["home","parents","people","human","children"],char:"👨‍👨‍👧",fitzpatrick_scale:false,category:"people"},family_man_man_girl_boy:{keywords:["home","parents","people","human","children"],char:"👨‍👨‍👧‍👦",fitzpatrick_scale:false,category:"people"},family_man_man_boy_boy:{keywords:["home","parents","people","human","children"],char:"👨‍👨‍👦‍👦",fitzpatrick_scale:false,category:"people"},family_man_man_girl_girl:{keywords:["home","parents","people","human","children"],char:"👨‍👨‍👧‍👧",fitzpatrick_scale:false,category:"people"},family_woman_boy:{keywords:["home","parent","people","human","child"],char:"👩‍👦",fitzpatrick_scale:false,category:"people"},family_woman_girl:{keywords:["home","parent","people","human","child"],char:"👩‍👧",fitzpatrick_scale:false,category:"people"},family_woman_girl_boy:{keywords:["home","parent","people","human","children"],char:"👩‍👧‍👦",fitzpatrick_scale:false,category:"people"},family_woman_boy_boy:{keywords:["home","parent","people","human","children"],char:"👩‍👦‍👦",fitzpatrick_scale:false,category:"people"},family_woman_girl_girl:{keywords:["home","parent","people","human","children"],char:"👩‍👧‍👧",fitzpatrick_scale:false,category:"people"},family_man_boy:{keywords:["home","parent","people","human","child"],char:"👨‍👦",fitzpatrick_scale:false,category:"people"},family_man_girl:{keywords:["home","parent","people","human","child"],char:"👨‍👧",fitzpatrick_scale:false,category:"people"},family_man_girl_boy:{keywords:["home","parent","people","human","children"],char:"👨‍👧‍👦",fitzpatrick_scale:false,category:"people"},family_man_boy_boy:{keywords:["home","parent","people","human","children"],char:"👨‍👦‍👦",fitzpatrick_scale:false,category:"people"},family_man_girl_girl:{keywords:["home","parent","people","human","children"],char:"👨‍👧‍👧",fitzpatrick_scale:false,category:"people"},yarn:{keywords:["ball","crochet","knit"],char:"🧶",fitzpatrick_scale:false,category:"people"},thread:{keywords:["needle","sewing","spool","string"],char:"🧵",fitzpatrick_scale:false,category:"people"},coat:{keywords:["jacket"],char:"🧥",fitzpatrick_scale:false,category:"people"},labcoat:{keywords:["doctor","experiment","scientist","chemist"],char:"🥼",fitzpatrick_scale:false,category:"people"},womans_clothes:{keywords:["fashion","shopping_bags","female"],char:"👚",fitzpatrick_scale:false,category:"people"},tshirt:{keywords:["fashion","cloth","casual","shirt","tee"],char:"👕",fitzpatrick_scale:false,category:"people"},jeans:{keywords:["fashion","shopping"],char:"👖",fitzpatrick_scale:false,category:"people"},necktie:{keywords:["shirt","suitup","formal","fashion","cloth","business"],char:"👔",fitzpatrick_scale:false,category:"people"},dress:{keywords:["clothes","fashion","shopping"],char:"👗",fitzpatrick_scale:false,category:"people"},bikini:{keywords:["swimming","female","woman","girl","fashion","beach","summer"],char:"👙",fitzpatrick_scale:false,category:"people"},kimono:{keywords:["dress","fashion","women","female","japanese"],char:"👘",fitzpatrick_scale:false,category:"people"},lipstick:{keywords:["female","girl","fashion","woman"],char:"💄",fitzpatrick_scale:false,category:"people"},kiss:{keywords:["face","lips","love","like","affection","valentines"],char:"💋",fitzpatrick_scale:false,category:"people"},footprints:{keywords:["feet","tracking","walking","beach"],char:"👣",fitzpatrick_scale:false,category:"people"},flat_shoe:{keywords:["ballet","slip-on","slipper"],char:"🥿",fitzpatrick_scale:false,category:"people"},high_heel:{keywords:["fashion","shoes","female","pumps","stiletto"],char:"👠",fitzpatrick_scale:false,category:"people"},sandal:{keywords:["shoes","fashion","flip flops"],char:"👡",fitzpatrick_scale:false,category:"people"},boot:{keywords:["shoes","fashion"],char:"👢",fitzpatrick_scale:false,category:"people"},mans_shoe:{keywords:["fashion","male"],char:"👞",fitzpatrick_scale:false,category:"people"},athletic_shoe:{keywords:["shoes","sports","sneakers"],char:"👟",fitzpatrick_scale:false,category:"people"},hiking_boot:{keywords:["backpacking","camping","hiking"],char:"🥾",fitzpatrick_scale:false,category:"people"},socks:{keywords:["stockings","clothes"],char:"🧦",fitzpatrick_scale:false,category:"people"},gloves:{keywords:["hands","winter","clothes"],char:"🧤",fitzpatrick_scale:false,category:"people"},scarf:{keywords:["neck","winter","clothes"],char:"🧣",fitzpatrick_scale:false,category:"people"},womans_hat:{keywords:["fashion","accessories","female","lady","spring"],char:"👒",fitzpatrick_scale:false,category:"people"},tophat:{keywords:["magic","gentleman","classy","circus"],char:"🎩",fitzpatrick_scale:false,category:"people"},billed_hat:{keywords:["cap","baseball"],char:"🧢",fitzpatrick_scale:false,category:"people"},rescue_worker_helmet:{keywords:["construction","build"],char:"⛑",fitzpatrick_scale:false,category:"people"},mortar_board:{keywords:["school","college","degree","university","graduation","cap","hat","legal","learn","education"],char:"🎓",fitzpatrick_scale:false,category:"people"},crown:{keywords:["king","kod","leader","royalty","lord"],char:"👑",fitzpatrick_scale:false,category:"people"},school_satchel:{keywords:["student","education","bag","backpack"],char:"🎒",fitzpatrick_scale:false,category:"people"},luggage:{keywords:["packing","travel"],char:"🧳",fitzpatrick_scale:false,category:"people"},pouch:{keywords:["bag","accessories","shopping"],char:"👝",fitzpatrick_scale:false,category:"people"},purse:{keywords:["fashion","accessories","money","sales","shopping"],char:"👛",fitzpatrick_scale:false,category:"people"},handbag:{keywords:["fashion","accessory","accessories","shopping"],char:"👜",fitzpatrick_scale:false,category:"people"},briefcase:{keywords:["business","documents","work","law","legal","job","career"],char:"💼",fitzpatrick_scale:false,category:"people"},eyeglasses:{keywords:["fashion","accessories","eyesight","nerdy","dork","geek"],char:"👓",fitzpatrick_scale:false,category:"people"},dark_sunglasses:{keywords:["face","cool","accessories"],char:"🕶",fitzpatrick_scale:false,category:"people"},goggles:{keywords:["eyes","protection","safety"],char:"🥽",fitzpatrick_scale:false,category:"people"},ring:{keywords:["wedding","propose","marriage","valentines","diamond","fashion","jewelry","gem","engagement"],char:"💍",fitzpatrick_scale:false,category:"people"},closed_umbrella:{keywords:["weather","rain","drizzle"],char:"🌂",fitzpatrick_scale:false,category:"people"},dog:{keywords:["animal","friend","nature","woof","puppy","pet","faithful"],char:"🐶",fitzpatrick_scale:false,category:"animals_and_nature"},cat:{keywords:["animal","meow","nature","pet","kitten"],char:"🐱",fitzpatrick_scale:false,category:"animals_and_nature"},mouse:{keywords:["animal","nature","cheese_wedge","rodent"],char:"🐭",fitzpatrick_scale:false,category:"animals_and_nature"},hamster:{keywords:["animal","nature"],char:"🐹",fitzpatrick_scale:false,category:"animals_and_nature"},rabbit:{keywords:["animal","nature","pet","spring","magic","bunny"],char:"🐰",fitzpatrick_scale:false,category:"animals_and_nature"},fox_face:{keywords:["animal","nature","face"],char:"🦊",fitzpatrick_scale:false,category:"animals_and_nature"},bear:{keywords:["animal","nature","wild"],char:"🐻",fitzpatrick_scale:false,category:"animals_and_nature"},panda_face:{keywords:["animal","nature","panda"],char:"🐼",fitzpatrick_scale:false,category:"animals_and_nature"},koala:{keywords:["animal","nature"],char:"🐨",fitzpatrick_scale:false,category:"animals_and_nature"},tiger:{keywords:["animal","cat","danger","wild","nature","roar"],char:"🐯",fitzpatrick_scale:false,category:"animals_and_nature"},lion:{keywords:["animal","nature"],char:"🦁",fitzpatrick_scale:false,category:"animals_and_nature"},cow:{keywords:["beef","ox","animal","nature","moo","milk"],char:"🐮",fitzpatrick_scale:false,category:"animals_and_nature"},pig:{keywords:["animal","oink","nature"],char:"🐷",fitzpatrick_scale:false,category:"animals_and_nature"},pig_nose:{keywords:["animal","oink"],char:"🐽",fitzpatrick_scale:false,category:"animals_and_nature"},frog:{keywords:["animal","nature","croak","toad"],char:"🐸",fitzpatrick_scale:false,category:"animals_and_nature"},squid:{keywords:["animal","nature","ocean","sea"],char:"🦑",fitzpatrick_scale:false,category:"animals_and_nature"},octopus:{keywords:["animal","creature","ocean","sea","nature","beach"],char:"🐙",fitzpatrick_scale:false,category:"animals_and_nature"},shrimp:{keywords:["animal","ocean","nature","seafood"],char:"🦐",fitzpatrick_scale:false,category:"animals_and_nature"},monkey_face:{keywords:["animal","nature","circus"],char:"🐵",fitzpatrick_scale:false,category:"animals_and_nature"},gorilla:{keywords:["animal","nature","circus"],char:"🦍",fitzpatrick_scale:false,category:"animals_and_nature"},see_no_evil:{keywords:["monkey","animal","nature","haha"],char:"🙈",fitzpatrick_scale:false,category:"animals_and_nature"},hear_no_evil:{keywords:["animal","monkey","nature"],char:"🙉",fitzpatrick_scale:false,category:"animals_and_nature"},speak_no_evil:{keywords:["monkey","animal","nature","omg"],char:"🙊",fitzpatrick_scale:false,category:"animals_and_nature"},monkey:{keywords:["animal","nature","banana","circus"],char:"🐒",fitzpatrick_scale:false,category:"animals_and_nature"},chicken:{keywords:["animal","cluck","nature","bird"],char:"🐔",fitzpatrick_scale:false,category:"animals_and_nature"},penguin:{keywords:["animal","nature"],char:"🐧",fitzpatrick_scale:false,category:"animals_and_nature"},bird:{keywords:["animal","nature","fly","tweet","spring"],char:"🐦",fitzpatrick_scale:false,category:"animals_and_nature"},baby_chick:{keywords:["animal","chicken","bird"],char:"🐤",fitzpatrick_scale:false,category:"animals_and_nature"},hatching_chick:{keywords:["animal","chicken","egg","born","baby","bird"],char:"🐣",fitzpatrick_scale:false,category:"animals_and_nature"},hatched_chick:{keywords:["animal","chicken","baby","bird"],char:"🐥",fitzpatrick_scale:false,category:"animals_and_nature"},duck:{keywords:["animal","nature","bird","mallard"],char:"🦆",fitzpatrick_scale:false,category:"animals_and_nature"},eagle:{keywords:["animal","nature","bird"],char:"🦅",fitzpatrick_scale:false,category:"animals_and_nature"},owl:{keywords:["animal","nature","bird","hoot"],char:"🦉",fitzpatrick_scale:false,category:"animals_and_nature"},bat:{keywords:["animal","nature","blind","vampire"],char:"🦇",fitzpatrick_scale:false,category:"animals_and_nature"},wolf:{keywords:["animal","nature","wild"],char:"🐺",fitzpatrick_scale:false,category:"animals_and_nature"},boar:{keywords:["animal","nature"],char:"🐗",fitzpatrick_scale:false,category:"animals_and_nature"},horse:{keywords:["animal","brown","nature"],char:"🐴",fitzpatrick_scale:false,category:"animals_and_nature"},unicorn:{keywords:["animal","nature","mystical"],char:"🦄",fitzpatrick_scale:false,category:"animals_and_nature"},honeybee:{keywords:["animal","insect","nature","bug","spring","honey"],char:"🐝",fitzpatrick_scale:false,category:"animals_and_nature"},bug:{keywords:["animal","insect","nature","worm"],char:"🐛",fitzpatrick_scale:false,category:"animals_and_nature"},butterfly:{keywords:["animal","insect","nature","caterpillar"],char:"🦋",fitzpatrick_scale:false,category:"animals_and_nature"},snail:{keywords:["slow","animal","shell"],char:"🐌",fitzpatrick_scale:false,category:"animals_and_nature"},beetle:{keywords:["animal","insect","nature","ladybug"],char:"🐞",fitzpatrick_scale:false,category:"animals_and_nature"},ant:{keywords:["animal","insect","nature","bug"],char:"🐜",fitzpatrick_scale:false,category:"animals_and_nature"},grasshopper:{keywords:["animal","cricket","chirp"],char:"🦗",fitzpatrick_scale:false,category:"animals_and_nature"},spider:{keywords:["animal","arachnid"],char:"🕷",fitzpatrick_scale:false,category:"animals_and_nature"},scorpion:{keywords:["animal","arachnid"],char:"🦂",fitzpatrick_scale:false,category:"animals_and_nature"},crab:{keywords:["animal","crustacean"],char:"🦀",fitzpatrick_scale:false,category:"animals_and_nature"},snake:{keywords:["animal","evil","nature","hiss","python"],char:"🐍",fitzpatrick_scale:false,category:"animals_and_nature"},lizard:{keywords:["animal","nature","reptile"],char:"🦎",fitzpatrick_scale:false,category:"animals_and_nature"},"t-rex":{keywords:["animal","nature","dinosaur","tyrannosaurus","extinct"],char:"🦖",fitzpatrick_scale:false,category:"animals_and_nature"},sauropod:{keywords:["animal","nature","dinosaur","brachiosaurus","brontosaurus","diplodocus","extinct"],char:"🦕",fitzpatrick_scale:false,category:"animals_and_nature"},turtle:{keywords:["animal","slow","nature","tortoise"],char:"🐢",fitzpatrick_scale:false,category:"animals_and_nature"},tropical_fish:{keywords:["animal","swim","ocean","beach","nemo"],char:"🐠",fitzpatrick_scale:false,category:"animals_and_nature"},fish:{keywords:["animal","food","nature"],char:"🐟",fitzpatrick_scale:false,category:"animals_and_nature"},blowfish:{keywords:["animal","nature","food","sea","ocean"],char:"🐡",fitzpatrick_scale:false,category:"animals_and_nature"},dolphin:{keywords:["animal","nature","fish","sea","ocean","flipper","fins","beach"],char:"🐬",fitzpatrick_scale:false,category:"animals_and_nature"},shark:{keywords:["animal","nature","fish","sea","ocean","jaws","fins","beach"],char:"🦈",fitzpatrick_scale:false,category:"animals_and_nature"},whale:{keywords:["animal","nature","sea","ocean"],char:"🐳",fitzpatrick_scale:false,category:"animals_and_nature"},whale2:{keywords:["animal","nature","sea","ocean"],char:"🐋",fitzpatrick_scale:false,category:"animals_and_nature"},crocodile:{keywords:["animal","nature","reptile","lizard","alligator"],char:"🐊",fitzpatrick_scale:false,category:"animals_and_nature"},leopard:{keywords:["animal","nature"],char:"🐆",fitzpatrick_scale:false,category:"animals_and_nature"},zebra:{keywords:["animal","nature","stripes","safari"],char:"🦓",fitzpatrick_scale:false,category:"animals_and_nature"},tiger2:{keywords:["animal","nature","roar"],char:"🐅",fitzpatrick_scale:false,category:"animals_and_nature"},water_buffalo:{keywords:["animal","nature","ox","cow"],char:"🐃",fitzpatrick_scale:false,category:"animals_and_nature"},ox:{keywords:["animal","cow","beef"],char:"🐂",fitzpatrick_scale:false,category:"animals_and_nature"},cow2:{keywords:["beef","ox","animal","nature","moo","milk"],char:"🐄",fitzpatrick_scale:false,category:"animals_and_nature"},deer:{keywords:["animal","nature","horns","venison"],char:"🦌",fitzpatrick_scale:false,category:"animals_and_nature"},dromedary_camel:{keywords:["animal","hot","desert","hump"],char:"🐪",fitzpatrick_scale:false,category:"animals_and_nature"},camel:{keywords:["animal","nature","hot","desert","hump"],char:"🐫",fitzpatrick_scale:false,category:"animals_and_nature"},giraffe:{keywords:["animal","nature","spots","safari"],char:"🦒",fitzpatrick_scale:false,category:"animals_and_nature"},elephant:{keywords:["animal","nature","nose","th","circus"],char:"🐘",fitzpatrick_scale:false,category:"animals_and_nature"},rhinoceros:{keywords:["animal","nature","horn"],char:"🦏",fitzpatrick_scale:false,category:"animals_and_nature"},goat:{keywords:["animal","nature"],char:"🐐",fitzpatrick_scale:false,category:"animals_and_nature"},ram:{keywords:["animal","sheep","nature"],char:"🐏",fitzpatrick_scale:false,category:"animals_and_nature"},sheep:{keywords:["animal","nature","wool","shipit"],char:"🐑",fitzpatrick_scale:false,category:"animals_and_nature"},racehorse:{keywords:["animal","gamble","luck"],char:"🐎",fitzpatrick_scale:false,category:"animals_and_nature"},pig2:{keywords:["animal","nature"],char:"🐖",fitzpatrick_scale:false,category:"animals_and_nature"},rat:{keywords:["animal","mouse","rodent"],char:"🐀",fitzpatrick_scale:false,category:"animals_and_nature"},mouse2:{keywords:["animal","nature","rodent"],char:"🐁",fitzpatrick_scale:false,category:"animals_and_nature"},rooster:{keywords:["animal","nature","chicken"],char:"🐓",fitzpatrick_scale:false,category:"animals_and_nature"},turkey:{keywords:["animal","bird"],char:"🦃",fitzpatrick_scale:false,category:"animals_and_nature"},dove:{keywords:["animal","bird"],char:"🕊",fitzpatrick_scale:false,category:"animals_and_nature"},dog2:{keywords:["animal","nature","friend","doge","pet","faithful"],char:"🐕",fitzpatrick_scale:false,category:"animals_and_nature"},poodle:{keywords:["dog","animal","101","nature","pet"],char:"🐩",fitzpatrick_scale:false,category:"animals_and_nature"},cat2:{keywords:["animal","meow","pet","cats"],char:"🐈",fitzpatrick_scale:false,category:"animals_and_nature"},rabbit2:{keywords:["animal","nature","pet","magic","spring"],char:"🐇",fitzpatrick_scale:false,category:"animals_and_nature"},chipmunk:{keywords:["animal","nature","rodent","squirrel"],char:"🐿",fitzpatrick_scale:false,category:"animals_and_nature"},hedgehog:{keywords:["animal","nature","spiny"],char:"🦔",fitzpatrick_scale:false,category:"animals_and_nature"},raccoon:{keywords:["animal","nature"],char:"🦝",fitzpatrick_scale:false,category:"animals_and_nature"},llama:{keywords:["animal","nature","alpaca"],char:"🦙",fitzpatrick_scale:false,category:"animals_and_nature"},hippopotamus:{keywords:["animal","nature"],char:"🦛",fitzpatrick_scale:false,category:"animals_and_nature"},kangaroo:{keywords:["animal","nature","australia","joey","hop","marsupial"],char:"🦘",fitzpatrick_scale:false,category:"animals_and_nature"},badger:{keywords:["animal","nature","honey"],char:"🦡",fitzpatrick_scale:false,category:"animals_and_nature"},swan:{keywords:["animal","nature","bird"],char:"🦢",fitzpatrick_scale:false,category:"animals_and_nature"},peacock:{keywords:["animal","nature","peahen","bird"],char:"🦚",fitzpatrick_scale:false,category:"animals_and_nature"},parrot:{keywords:["animal","nature","bird","pirate","talk"],char:"🦜",fitzpatrick_scale:false,category:"animals_and_nature"},lobster:{keywords:["animal","nature","bisque","claws","seafood"],char:"🦞",fitzpatrick_scale:false,category:"animals_and_nature"},mosquito:{keywords:["animal","nature","insect","malaria"],char:"🦟",fitzpatrick_scale:false,category:"animals_and_nature"},paw_prints:{keywords:["animal","tracking","footprints","dog","cat","pet","feet"],char:"🐾",fitzpatrick_scale:false,category:"animals_and_nature"},dragon:{keywords:["animal","myth","nature","chinese","green"],char:"🐉",fitzpatrick_scale:false,category:"animals_and_nature"},dragon_face:{keywords:["animal","myth","nature","chinese","green"],char:"🐲",fitzpatrick_scale:false,category:"animals_and_nature"},cactus:{keywords:["vegetable","plant","nature"],char:"🌵",fitzpatrick_scale:false,category:"animals_and_nature"},christmas_tree:{keywords:["festival","vacation","december","xmas","celebration"],char:"🎄",fitzpatrick_scale:false,category:"animals_and_nature"},evergreen_tree:{keywords:["plant","nature"],char:"🌲",fitzpatrick_scale:false,category:"animals_and_nature"},deciduous_tree:{keywords:["plant","nature"],char:"🌳",fitzpatrick_scale:false,category:"animals_and_nature"},palm_tree:{keywords:["plant","vegetable","nature","summer","beach","mojito","tropical"],char:"🌴",fitzpatrick_scale:false,category:"animals_and_nature"},seedling:{keywords:["plant","nature","grass","lawn","spring"],char:"🌱",fitzpatrick_scale:false,category:"animals_and_nature"},herb:{keywords:["vegetable","plant","medicine","weed","grass","lawn"],char:"🌿",fitzpatrick_scale:false,category:"animals_and_nature"},shamrock:{keywords:["vegetable","plant","nature","irish","clover"],char:"☘",fitzpatrick_scale:false,category:"animals_and_nature"},four_leaf_clover:{keywords:["vegetable","plant","nature","lucky","irish"],char:"🍀",fitzpatrick_scale:false,category:"animals_and_nature"},bamboo:{keywords:["plant","nature","vegetable","panda","pine_decoration"],char:"🎍",fitzpatrick_scale:false,category:"animals_and_nature"},tanabata_tree:{keywords:["plant","nature","branch","summer"],char:"🎋",fitzpatrick_scale:false,category:"animals_and_nature"},leaves:{keywords:["nature","plant","tree","vegetable","grass","lawn","spring"],char:"🍃",fitzpatrick_scale:false,category:"animals_and_nature"},fallen_leaf:{keywords:["nature","plant","vegetable","leaves"],char:"🍂",fitzpatrick_scale:false,category:"animals_and_nature"},maple_leaf:{keywords:["nature","plant","vegetable","ca","fall"],char:"🍁",fitzpatrick_scale:false,category:"animals_and_nature"},ear_of_rice:{keywords:["nature","plant"],char:"🌾",fitzpatrick_scale:false,category:"animals_and_nature"},hibiscus:{keywords:["plant","vegetable","flowers","beach"],char:"🌺",fitzpatrick_scale:false,category:"animals_and_nature"},sunflower:{keywords:["nature","plant","fall"],char:"🌻",fitzpatrick_scale:false,category:"animals_and_nature"},rose:{keywords:["flowers","valentines","love","spring"],char:"🌹",fitzpatrick_scale:false,category:"animals_and_nature"},wilted_flower:{keywords:["plant","nature","flower"],char:"🥀",fitzpatrick_scale:false,category:"animals_and_nature"},tulip:{keywords:["flowers","plant","nature","summer","spring"],char:"🌷",fitzpatrick_scale:false,category:"animals_and_nature"},blossom:{keywords:["nature","flowers","yellow"],char:"🌼",fitzpatrick_scale:false,category:"animals_and_nature"},cherry_blossom:{keywords:["nature","plant","spring","flower"],char:"🌸",fitzpatrick_scale:false,category:"animals_and_nature"},bouquet:{keywords:["flowers","nature","spring"],char:"💐",fitzpatrick_scale:false,category:"animals_and_nature"},mushroom:{keywords:["plant","vegetable"],char:"🍄",fitzpatrick_scale:false,category:"animals_and_nature"},chestnut:{keywords:["food","squirrel"],char:"🌰",fitzpatrick_scale:false,category:"animals_and_nature"},jack_o_lantern:{keywords:["halloween","light","pumpkin","creepy","fall"],char:"🎃",fitzpatrick_scale:false,category:"animals_and_nature"},shell:{keywords:["nature","sea","beach"],char:"🐚",fitzpatrick_scale:false,category:"animals_and_nature"},spider_web:{keywords:["animal","insect","arachnid","silk"],char:"🕸",fitzpatrick_scale:false,category:"animals_and_nature"},earth_americas:{keywords:["globe","world","USA","international"],char:"🌎",fitzpatrick_scale:false,category:"animals_and_nature"},earth_africa:{keywords:["globe","world","international"],char:"🌍",fitzpatrick_scale:false,category:"animals_and_nature"},earth_asia:{keywords:["globe","world","east","international"],char:"🌏",fitzpatrick_scale:false,category:"animals_and_nature"},full_moon:{keywords:["nature","yellow","twilight","planet","space","night","evening","sleep"],char:"🌕",fitzpatrick_scale:false,category:"animals_and_nature"},waning_gibbous_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep","waxing_gibbous_moon"],char:"🌖",fitzpatrick_scale:false,category:"animals_and_nature"},last_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"🌗",fitzpatrick_scale:false,category:"animals_and_nature"},waning_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"🌘",fitzpatrick_scale:false,category:"animals_and_nature"},new_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"🌑",fitzpatrick_scale:false,category:"animals_and_nature"},waxing_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"🌒",fitzpatrick_scale:false,category:"animals_and_nature"},first_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"🌓",fitzpatrick_scale:false,category:"animals_and_nature"},waxing_gibbous_moon:{keywords:["nature","night","sky","gray","twilight","planet","space","evening","sleep"],char:"🌔",fitzpatrick_scale:false,category:"animals_and_nature"},new_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"🌚",fitzpatrick_scale:false,category:"animals_and_nature"},full_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"🌝",fitzpatrick_scale:false,category:"animals_and_nature"},first_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"🌛",fitzpatrick_scale:false,category:"animals_and_nature"},last_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"🌜",fitzpatrick_scale:false,category:"animals_and_nature"},sun_with_face:{keywords:["nature","morning","sky"],char:"🌞",fitzpatrick_scale:false,category:"animals_and_nature"},crescent_moon:{keywords:["night","sleep","sky","evening","magic"],char:"🌙",fitzpatrick_scale:false,category:"animals_and_nature"},star:{keywords:["night","yellow"],char:"⭐",fitzpatrick_scale:false,category:"animals_and_nature"},star2:{keywords:["night","sparkle","awesome","good","magic"],char:"🌟",fitzpatrick_scale:false,category:"animals_and_nature"},dizzy:{keywords:["star","sparkle","shoot","magic"],char:"💫",fitzpatrick_scale:false,category:"animals_and_nature"},sparkles:{keywords:["stars","shine","shiny","cool","awesome","good","magic"],char:"✨",fitzpatrick_scale:false,category:"animals_and_nature"},comet:{keywords:["space"],char:"☄",fitzpatrick_scale:false,category:"animals_and_nature"},sunny:{keywords:["weather","nature","brightness","summer","beach","spring"],char:"☀️",fitzpatrick_scale:false,category:"animals_and_nature"},sun_behind_small_cloud:{keywords:["weather"],char:"🌤",fitzpatrick_scale:false,category:"animals_and_nature"},partly_sunny:{keywords:["weather","nature","cloudy","morning","fall","spring"],char:"⛅",fitzpatrick_scale:false,category:"animals_and_nature"},sun_behind_large_cloud:{keywords:["weather"],char:"🌥",fitzpatrick_scale:false,category:"animals_and_nature"},sun_behind_rain_cloud:{keywords:["weather"],char:"🌦",fitzpatrick_scale:false,category:"animals_and_nature"},cloud:{keywords:["weather","sky"],char:"☁️",fitzpatrick_scale:false,category:"animals_and_nature"},cloud_with_rain:{keywords:["weather"],char:"🌧",fitzpatrick_scale:false,category:"animals_and_nature"},cloud_with_lightning_and_rain:{keywords:["weather","lightning"],char:"⛈",fitzpatrick_scale:false,category:"animals_and_nature"},cloud_with_lightning:{keywords:["weather","thunder"],char:"🌩",fitzpatrick_scale:false,category:"animals_and_nature"},zap:{keywords:["thunder","weather","lightning bolt","fast"],char:"⚡",fitzpatrick_scale:false,category:"animals_and_nature"},fire:{keywords:["hot","cook","flame"],char:"🔥",fitzpatrick_scale:false,category:"animals_and_nature"},boom:{keywords:["bomb","explode","explosion","collision","blown"],char:"💥",fitzpatrick_scale:false,category:"animals_and_nature"},snowflake:{keywords:["winter","season","cold","weather","christmas","xmas"],char:"❄️",fitzpatrick_scale:false,category:"animals_and_nature"},cloud_with_snow:{keywords:["weather"],char:"🌨",fitzpatrick_scale:false,category:"animals_and_nature"},snowman:{keywords:["winter","season","cold","weather","christmas","xmas","frozen","without_snow"],char:"⛄",fitzpatrick_scale:false,category:"animals_and_nature"},snowman_with_snow:{keywords:["winter","season","cold","weather","christmas","xmas","frozen"],char:"☃",fitzpatrick_scale:false,category:"animals_and_nature"},wind_face:{keywords:["gust","air"],char:"🌬",fitzpatrick_scale:false,category:"animals_and_nature"},dash:{keywords:["wind","air","fast","shoo","fart","smoke","puff"],char:"💨",fitzpatrick_scale:false,category:"animals_and_nature"},tornado:{keywords:["weather","cyclone","twister"],char:"🌪",fitzpatrick_scale:false,category:"animals_and_nature"},fog:{keywords:["weather"],char:"🌫",fitzpatrick_scale:false,category:"animals_and_nature"},open_umbrella:{keywords:["weather","spring"],char:"☂",fitzpatrick_scale:false,category:"animals_and_nature"},umbrella:{keywords:["rainy","weather","spring"],char:"☔",fitzpatrick_scale:false,category:"animals_and_nature"},droplet:{keywords:["water","drip","faucet","spring"],char:"💧",fitzpatrick_scale:false,category:"animals_and_nature"},sweat_drops:{keywords:["water","drip","oops"],char:"💦",fitzpatrick_scale:false,category:"animals_and_nature"},ocean:{keywords:["sea","water","wave","nature","tsunami","disaster"],char:"🌊",fitzpatrick_scale:false,category:"animals_and_nature"},green_apple:{keywords:["fruit","nature"],char:"🍏",fitzpatrick_scale:false,category:"food_and_drink"},apple:{keywords:["fruit","mac","school"],char:"🍎",fitzpatrick_scale:false,category:"food_and_drink"},pear:{keywords:["fruit","nature","food"],char:"🍐",fitzpatrick_scale:false,category:"food_and_drink"},tangerine:{keywords:["food","fruit","nature","orange"],char:"🍊",fitzpatrick_scale:false,category:"food_and_drink"},lemon:{keywords:["fruit","nature"],char:"🍋",fitzpatrick_scale:false,category:"food_and_drink"},banana:{keywords:["fruit","food","monkey"],char:"🍌",fitzpatrick_scale:false,category:"food_and_drink"},watermelon:{keywords:["fruit","food","picnic","summer"],char:"🍉",fitzpatrick_scale:false,category:"food_and_drink"},grapes:{keywords:["fruit","food","wine"],char:"🍇",fitzpatrick_scale:false,category:"food_and_drink"},strawberry:{keywords:["fruit","food","nature"],char:"🍓",fitzpatrick_scale:false,category:"food_and_drink"},melon:{keywords:["fruit","nature","food"],char:"🍈",fitzpatrick_scale:false,category:"food_and_drink"},cherries:{keywords:["food","fruit"],char:"🍒",fitzpatrick_scale:false,category:"food_and_drink"},peach:{keywords:["fruit","nature","food"],char:"🍑",fitzpatrick_scale:false,category:"food_and_drink"},pineapple:{keywords:["fruit","nature","food"],char:"🍍",fitzpatrick_scale:false,category:"food_and_drink"},coconut:{keywords:["fruit","nature","food","palm"],char:"🥥",fitzpatrick_scale:false,category:"food_and_drink"},kiwi_fruit:{keywords:["fruit","food"],char:"🥝",fitzpatrick_scale:false,category:"food_and_drink"},mango:{keywords:["fruit","food","tropical"],char:"🥭",fitzpatrick_scale:false,category:"food_and_drink"},avocado:{keywords:["fruit","food"],char:"🥑",fitzpatrick_scale:false,category:"food_and_drink"},broccoli:{keywords:["fruit","food","vegetable"],char:"🥦",fitzpatrick_scale:false,category:"food_and_drink"},tomato:{keywords:["fruit","vegetable","nature","food"],char:"🍅",fitzpatrick_scale:false,category:"food_and_drink"},eggplant:{keywords:["vegetable","nature","food","aubergine"],char:"🍆",fitzpatrick_scale:false,category:"food_and_drink"},cucumber:{keywords:["fruit","food","pickle"],char:"🥒",fitzpatrick_scale:false,category:"food_and_drink"},carrot:{keywords:["vegetable","food","orange"],char:"🥕",fitzpatrick_scale:false,category:"food_and_drink"},hot_pepper:{keywords:["food","spicy","chilli","chili"],char:"🌶",fitzpatrick_scale:false,category:"food_and_drink"},potato:{keywords:["food","tuber","vegatable","starch"],char:"🥔",fitzpatrick_scale:false,category:"food_and_drink"},corn:{keywords:["food","vegetable","plant"],char:"🌽",fitzpatrick_scale:false,category:"food_and_drink"},leafy_greens:{keywords:["food","vegetable","plant","bok choy","cabbage","kale","lettuce"],char:"🥬",fitzpatrick_scale:false,category:"food_and_drink"},sweet_potato:{keywords:["food","nature"],char:"🍠",fitzpatrick_scale:false,category:"food_and_drink"},peanuts:{keywords:["food","nut"],char:"🥜",fitzpatrick_scale:false,category:"food_and_drink"},honey_pot:{keywords:["bees","sweet","kitchen"],char:"🍯",fitzpatrick_scale:false,category:"food_and_drink"},croissant:{keywords:["food","bread","french"],char:"🥐",fitzpatrick_scale:false,category:"food_and_drink"},bread:{keywords:["food","wheat","breakfast","toast"],char:"🍞",fitzpatrick_scale:false,category:"food_and_drink"},baguette_bread:{keywords:["food","bread","french"],char:"🥖",fitzpatrick_scale:false,category:"food_and_drink"},bagel:{keywords:["food","bread","bakery","schmear"],char:"🥯",fitzpatrick_scale:false,category:"food_and_drink"},pretzel:{keywords:["food","bread","twisted"],char:"🥨",fitzpatrick_scale:false,category:"food_and_drink"},cheese:{keywords:["food","chadder"],char:"🧀",fitzpatrick_scale:false,category:"food_and_drink"},egg:{keywords:["food","chicken","breakfast"],char:"🥚",fitzpatrick_scale:false,category:"food_and_drink"},bacon:{keywords:["food","breakfast","pork","pig","meat"],char:"🥓",fitzpatrick_scale:false,category:"food_and_drink"},steak:{keywords:["food","cow","meat","cut","chop","lambchop","porkchop"],char:"🥩",fitzpatrick_scale:false,category:"food_and_drink"},pancakes:{keywords:["food","breakfast","flapjacks","hotcakes"],char:"🥞",fitzpatrick_scale:false,category:"food_and_drink"},poultry_leg:{keywords:["food","meat","drumstick","bird","chicken","turkey"],char:"🍗",fitzpatrick_scale:false,category:"food_and_drink"},meat_on_bone:{keywords:["good","food","drumstick"],char:"🍖",fitzpatrick_scale:false,category:"food_and_drink"},bone:{keywords:["skeleton"],char:"🦴",fitzpatrick_scale:false,category:"food_and_drink"},fried_shrimp:{keywords:["food","animal","appetizer","summer"],char:"🍤",fitzpatrick_scale:false,category:"food_and_drink"},fried_egg:{keywords:["food","breakfast","kitchen","egg"],char:"🍳",fitzpatrick_scale:false,category:"food_and_drink"},hamburger:{keywords:["meat","fast food","beef","cheeseburger","mcdonalds","burger king"],char:"🍔",fitzpatrick_scale:false,category:"food_and_drink"},fries:{keywords:["chips","snack","fast food"],char:"🍟",fitzpatrick_scale:false,category:"food_and_drink"},stuffed_flatbread:{keywords:["food","flatbread","stuffed","gyro"],char:"🥙",fitzpatrick_scale:false,category:"food_and_drink"},hotdog:{keywords:["food","frankfurter"],char:"🌭",fitzpatrick_scale:false,category:"food_and_drink"},pizza:{keywords:["food","party"],char:"🍕",fitzpatrick_scale:false,category:"food_and_drink"},sandwich:{keywords:["food","lunch","bread"],char:"🥪",fitzpatrick_scale:false,category:"food_and_drink"},canned_food:{keywords:["food","soup"],char:"🥫",fitzpatrick_scale:false,category:"food_and_drink"},spaghetti:{keywords:["food","italian","noodle"],char:"🍝",fitzpatrick_scale:false,category:"food_and_drink"},taco:{keywords:["food","mexican"],char:"🌮",fitzpatrick_scale:false,category:"food_and_drink"},burrito:{keywords:["food","mexican"],char:"🌯",fitzpatrick_scale:false,category:"food_and_drink"},green_salad:{keywords:["food","healthy","lettuce"],char:"🥗",fitzpatrick_scale:false,category:"food_and_drink"},shallow_pan_of_food:{keywords:["food","cooking","casserole","paella"],char:"🥘",fitzpatrick_scale:false,category:"food_and_drink"},ramen:{keywords:["food","japanese","noodle","chopsticks"],char:"🍜",fitzpatrick_scale:false,category:"food_and_drink"},stew:{keywords:["food","meat","soup"],char:"🍲",fitzpatrick_scale:false,category:"food_and_drink"},fish_cake:{keywords:["food","japan","sea","beach","narutomaki","pink","swirl","kamaboko","surimi","ramen"],char:"🍥",fitzpatrick_scale:false,category:"food_and_drink"},fortune_cookie:{keywords:["food","prophecy"],char:"🥠",fitzpatrick_scale:false,category:"food_and_drink"},sushi:{keywords:["food","fish","japanese","rice"],char:"🍣",fitzpatrick_scale:false,category:"food_and_drink"},bento:{keywords:["food","japanese","box"],char:"🍱",fitzpatrick_scale:false,category:"food_and_drink"},curry:{keywords:["food","spicy","hot","indian"],char:"🍛",fitzpatrick_scale:false,category:"food_and_drink"},rice_ball:{keywords:["food","japanese"],char:"🍙",fitzpatrick_scale:false,category:"food_and_drink"},rice:{keywords:["food","china","asian"],char:"🍚",fitzpatrick_scale:false,category:"food_and_drink"},rice_cracker:{keywords:["food","japanese"],char:"🍘",fitzpatrick_scale:false,category:"food_and_drink"},oden:{keywords:["food","japanese"],char:"🍢",fitzpatrick_scale:false,category:"food_and_drink"},dango:{keywords:["food","dessert","sweet","japanese","barbecue","meat"],char:"🍡",fitzpatrick_scale:false,category:"food_and_drink"},shaved_ice:{keywords:["hot","dessert","summer"],char:"🍧",fitzpatrick_scale:false,category:"food_and_drink"},ice_cream:{keywords:["food","hot","dessert"],char:"🍨",fitzpatrick_scale:false,category:"food_and_drink"},icecream:{keywords:["food","hot","dessert","summer"],char:"🍦",fitzpatrick_scale:false,category:"food_and_drink"},pie:{keywords:["food","dessert","pastry"],char:"🥧",fitzpatrick_scale:false,category:"food_and_drink"},cake:{keywords:["food","dessert"],char:"🍰",fitzpatrick_scale:false,category:"food_and_drink"},cupcake:{keywords:["food","dessert","bakery","sweet"],char:"🧁",fitzpatrick_scale:false,category:"food_and_drink"},moon_cake:{keywords:["food","autumn"],char:"🥮",fitzpatrick_scale:false,category:"food_and_drink"},birthday:{keywords:["food","dessert","cake"],char:"🎂",fitzpatrick_scale:false,category:"food_and_drink"},custard:{keywords:["dessert","food"],char:"🍮",fitzpatrick_scale:false,category:"food_and_drink"},candy:{keywords:["snack","dessert","sweet","lolly"],char:"🍬",fitzpatrick_scale:false,category:"food_and_drink"},lollipop:{keywords:["food","snack","candy","sweet"],char:"🍭",fitzpatrick_scale:false,category:"food_and_drink"},chocolate_bar:{keywords:["food","snack","dessert","sweet"],char:"🍫",fitzpatrick_scale:false,category:"food_and_drink"},popcorn:{keywords:["food","movie theater","films","snack"],char:"🍿",fitzpatrick_scale:false,category:"food_and_drink"},dumpling:{keywords:["food","empanada","pierogi","potsticker"],char:"🥟",fitzpatrick_scale:false,category:"food_and_drink"},doughnut:{keywords:["food","dessert","snack","sweet","donut"],char:"🍩",fitzpatrick_scale:false,category:"food_and_drink"},cookie:{keywords:["food","snack","oreo","chocolate","sweet","dessert"],char:"🍪",fitzpatrick_scale:false,category:"food_and_drink"},milk_glass:{keywords:["beverage","drink","cow"],char:"🥛",fitzpatrick_scale:false,category:"food_and_drink"},beer:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:"🍺",fitzpatrick_scale:false,category:"food_and_drink"},beers:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:"🍻",fitzpatrick_scale:false,category:"food_and_drink"},clinking_glasses:{keywords:["beverage","drink","party","alcohol","celebrate","cheers","wine","champagne","toast"],char:"🥂",fitzpatrick_scale:false,category:"food_and_drink"},wine_glass:{keywords:["drink","beverage","drunk","alcohol","booze"],char:"🍷",fitzpatrick_scale:false,category:"food_and_drink"},tumbler_glass:{keywords:["drink","beverage","drunk","alcohol","liquor","booze","bourbon","scotch","whisky","glass","shot"],char:"🥃",fitzpatrick_scale:false,category:"food_and_drink"},cocktail:{keywords:["drink","drunk","alcohol","beverage","booze","mojito"],char:"🍸",fitzpatrick_scale:false,category:"food_and_drink"},tropical_drink:{keywords:["beverage","cocktail","summer","beach","alcohol","booze","mojito"],char:"🍹",fitzpatrick_scale:false,category:"food_and_drink"},champagne:{keywords:["drink","wine","bottle","celebration"],char:"🍾",fitzpatrick_scale:false,category:"food_and_drink"},sake:{keywords:["wine","drink","drunk","beverage","japanese","alcohol","booze"],char:"🍶",fitzpatrick_scale:false,category:"food_and_drink"},tea:{keywords:["drink","bowl","breakfast","green","british"],char:"🍵",fitzpatrick_scale:false,category:"food_and_drink"},cup_with_straw:{keywords:["drink","soda"],char:"🥤",fitzpatrick_scale:false,category:"food_and_drink"},coffee:{keywords:["beverage","caffeine","latte","espresso"],char:"☕",fitzpatrick_scale:false,category:"food_and_drink"},baby_bottle:{keywords:["food","container","milk"],char:"🍼",fitzpatrick_scale:false,category:"food_and_drink"},salt:{keywords:["condiment","shaker"],char:"🧂",fitzpatrick_scale:false,category:"food_and_drink"},spoon:{keywords:["cutlery","kitchen","tableware"],char:"🥄",fitzpatrick_scale:false,category:"food_and_drink"},fork_and_knife:{keywords:["cutlery","kitchen"],char:"🍴",fitzpatrick_scale:false,category:"food_and_drink"},plate_with_cutlery:{keywords:["food","eat","meal","lunch","dinner","restaurant"],char:"🍽",fitzpatrick_scale:false,category:"food_and_drink"},bowl_with_spoon:{keywords:["food","breakfast","cereal","oatmeal","porridge"],char:"🥣",fitzpatrick_scale:false,category:"food_and_drink"},takeout_box:{keywords:["food","leftovers"],char:"🥡",fitzpatrick_scale:false,category:"food_and_drink"},chopsticks:{keywords:["food"],char:"🥢",fitzpatrick_scale:false,category:"food_and_drink"},soccer:{keywords:["sports","football"],char:"⚽",fitzpatrick_scale:false,category:"activity"},basketball:{keywords:["sports","balls","NBA"],char:"🏀",fitzpatrick_scale:false,category:"activity"},football:{keywords:["sports","balls","NFL"],char:"🏈",fitzpatrick_scale:false,category:"activity"},baseball:{keywords:["sports","balls"],char:"⚾",fitzpatrick_scale:false,category:"activity"},softball:{keywords:["sports","balls"],char:"🥎",fitzpatrick_scale:false,category:"activity"},tennis:{keywords:["sports","balls","green"],char:"🎾",fitzpatrick_scale:false,category:"activity"},volleyball:{keywords:["sports","balls"],char:"🏐",fitzpatrick_scale:false,category:"activity"},rugby_football:{keywords:["sports","team"],char:"🏉",fitzpatrick_scale:false,category:"activity"},flying_disc:{keywords:["sports","frisbee","ultimate"],char:"🥏",fitzpatrick_scale:false,category:"activity"},"8ball":{keywords:["pool","hobby","game","luck","magic"],char:"🎱",fitzpatrick_scale:false,category:"activity"},golf:{keywords:["sports","business","flag","hole","summer"],char:"⛳",fitzpatrick_scale:false,category:"activity"},golfing_woman:{keywords:["sports","business","woman","female"],char:"🏌️‍♀️",fitzpatrick_scale:false,category:"activity"},golfing_man:{keywords:["sports","business"],char:"🏌",fitzpatrick_scale:true,category:"activity"},ping_pong:{keywords:["sports","pingpong"],char:"🏓",fitzpatrick_scale:false,category:"activity"},badminton:{keywords:["sports"],char:"🏸",fitzpatrick_scale:false,category:"activity"},goal_net:{keywords:["sports"],char:"🥅",fitzpatrick_scale:false,category:"activity"},ice_hockey:{keywords:["sports"],char:"🏒",fitzpatrick_scale:false,category:"activity"},field_hockey:{keywords:["sports"],char:"🏑",fitzpatrick_scale:false,category:"activity"},lacrosse:{keywords:["sports","ball","stick"],char:"🥍",fitzpatrick_scale:false,category:"activity"},cricket:{keywords:["sports"],char:"🏏",fitzpatrick_scale:false,category:"activity"},ski:{keywords:["sports","winter","cold","snow"],char:"🎿",fitzpatrick_scale:false,category:"activity"},skier:{keywords:["sports","winter","snow"],char:"⛷",fitzpatrick_scale:false,category:"activity"},snowboarder:{keywords:["sports","winter"],char:"🏂",fitzpatrick_scale:true,category:"activity"},person_fencing:{keywords:["sports","fencing","sword"],char:"🤺",fitzpatrick_scale:false,category:"activity"},women_wrestling:{keywords:["sports","wrestlers"],char:"🤼‍♀️",fitzpatrick_scale:false,category:"activity"},men_wrestling:{keywords:["sports","wrestlers"],char:"🤼‍♂️",fitzpatrick_scale:false,category:"activity"},woman_cartwheeling:{keywords:["gymnastics"],char:"🤸‍♀️",fitzpatrick_scale:true,category:"activity"},man_cartwheeling:{keywords:["gymnastics"],char:"🤸‍♂️",fitzpatrick_scale:true,category:"activity"},woman_playing_handball:{keywords:["sports"],char:"🤾‍♀️",fitzpatrick_scale:true,category:"activity"},man_playing_handball:{keywords:["sports"],char:"🤾‍♂️",fitzpatrick_scale:true,category:"activity"},ice_skate:{keywords:["sports"],char:"⛸",fitzpatrick_scale:false,category:"activity"},curling_stone:{keywords:["sports"],char:"🥌",fitzpatrick_scale:false,category:"activity"},skateboard:{keywords:["board"],char:"🛹",fitzpatrick_scale:false,category:"activity"},sled:{keywords:["sleigh","luge","toboggan"],char:"🛷",fitzpatrick_scale:false,category:"activity"},bow_and_arrow:{keywords:["sports"],char:"🏹",fitzpatrick_scale:false,category:"activity"},fishing_pole_and_fish:{keywords:["food","hobby","summer"],char:"🎣",fitzpatrick_scale:false,category:"activity"},boxing_glove:{keywords:["sports","fighting"],char:"🥊",fitzpatrick_scale:false,category:"activity"},martial_arts_uniform:{keywords:["judo","karate","taekwondo"],char:"🥋",fitzpatrick_scale:false,category:"activity"},rowing_woman:{keywords:["sports","hobby","water","ship","woman","female"],char:"🚣‍♀️",fitzpatrick_scale:true,category:"activity"},rowing_man:{keywords:["sports","hobby","water","ship"],char:"🚣",fitzpatrick_scale:true,category:"activity"},climbing_woman:{keywords:["sports","hobby","woman","female","rock"],char:"🧗‍♀️",fitzpatrick_scale:true,category:"activity"},climbing_man:{keywords:["sports","hobby","man","male","rock"],char:"🧗‍♂️",fitzpatrick_scale:true,category:"activity"},swimming_woman:{keywords:["sports","exercise","human","athlete","water","summer","woman","female"],char:"🏊‍♀️",fitzpatrick_scale:true,category:"activity"},swimming_man:{keywords:["sports","exercise","human","athlete","water","summer"],char:"🏊",fitzpatrick_scale:true,category:"activity"},woman_playing_water_polo:{keywords:["sports","pool"],char:"🤽‍♀️",fitzpatrick_scale:true,category:"activity"},man_playing_water_polo:{keywords:["sports","pool"],char:"🤽‍♂️",fitzpatrick_scale:true,category:"activity"},woman_in_lotus_position:{keywords:["woman","female","meditation","yoga","serenity","zen","mindfulness"],char:"🧘‍♀️",fitzpatrick_scale:true,category:"activity"},man_in_lotus_position:{keywords:["man","male","meditation","yoga","serenity","zen","mindfulness"],char:"🧘‍♂️",fitzpatrick_scale:true,category:"activity"},surfing_woman:{keywords:["sports","ocean","sea","summer","beach","woman","female"],char:"🏄‍♀️",fitzpatrick_scale:true,category:"activity"},surfing_man:{keywords:["sports","ocean","sea","summer","beach"],char:"🏄",fitzpatrick_scale:true,category:"activity"},bath:{keywords:["clean","shower","bathroom"],char:"🛀",fitzpatrick_scale:true,category:"activity"},basketball_woman:{keywords:["sports","human","woman","female"],char:"⛹️‍♀️",fitzpatrick_scale:true,category:"activity"},basketball_man:{keywords:["sports","human"],char:"⛹",fitzpatrick_scale:true,category:"activity"},weight_lifting_woman:{keywords:["sports","training","exercise","woman","female"],char:"🏋️‍♀️",fitzpatrick_scale:true,category:"activity"},weight_lifting_man:{keywords:["sports","training","exercise"],char:"🏋",fitzpatrick_scale:true,category:"activity"},biking_woman:{keywords:["sports","bike","exercise","hipster","woman","female"],char:"🚴‍♀️",fitzpatrick_scale:true,category:"activity"},biking_man:{keywords:["sports","bike","exercise","hipster"],char:"🚴",fitzpatrick_scale:true,category:"activity"},mountain_biking_woman:{keywords:["transportation","sports","human","race","bike","woman","female"],char:"🚵‍♀️",fitzpatrick_scale:true,category:"activity"},mountain_biking_man:{keywords:["transportation","sports","human","race","bike"],char:"🚵",fitzpatrick_scale:true,category:"activity"},horse_racing:{keywords:["animal","betting","competition","gambling","luck"],char:"🏇",fitzpatrick_scale:true,category:"activity"},business_suit_levitating:{keywords:["suit","business","levitate","hover","jump"],char:"🕴",fitzpatrick_scale:true,category:"activity"},trophy:{keywords:["win","award","contest","place","ftw","ceremony"],char:"🏆",fitzpatrick_scale:false,category:"activity"},running_shirt_with_sash:{keywords:["play","pageant"],char:"🎽",fitzpatrick_scale:false,category:"activity"},medal_sports:{keywords:["award","winning"],char:"🏅",fitzpatrick_scale:false,category:"activity"},medal_military:{keywords:["award","winning","army"],char:"🎖",fitzpatrick_scale:false,category:"activity"},"1st_place_medal":{keywords:["award","winning","first"],char:"🥇",fitzpatrick_scale:false,category:"activity"},"2nd_place_medal":{keywords:["award","second"],char:"🥈",fitzpatrick_scale:false,category:"activity"},"3rd_place_medal":{keywords:["award","third"],char:"🥉",fitzpatrick_scale:false,category:"activity"},reminder_ribbon:{keywords:["sports","cause","support","awareness"],char:"🎗",fitzpatrick_scale:false,category:"activity"},rosette:{keywords:["flower","decoration","military"],char:"🏵",fitzpatrick_scale:false,category:"activity"},ticket:{keywords:["event","concert","pass"],char:"🎫",fitzpatrick_scale:false,category:"activity"},tickets:{keywords:["sports","concert","entrance"],char:"🎟",fitzpatrick_scale:false,category:"activity"},performing_arts:{keywords:["acting","theater","drama"],char:"🎭",fitzpatrick_scale:false,category:"activity"},art:{keywords:["design","paint","draw","colors"],char:"🎨",fitzpatrick_scale:false,category:"activity"},circus_tent:{keywords:["festival","carnival","party"],char:"🎪",fitzpatrick_scale:false,category:"activity"},woman_juggling:{keywords:["juggle","balance","skill","multitask"],char:"🤹‍♀️",fitzpatrick_scale:true,category:"activity"},man_juggling:{keywords:["juggle","balance","skill","multitask"],char:"🤹‍♂️",fitzpatrick_scale:true,category:"activity"},microphone:{keywords:["sound","music","PA","sing","talkshow"],char:"🎤",fitzpatrick_scale:false,category:"activity"},headphones:{keywords:["music","score","gadgets"],char:"🎧",fitzpatrick_scale:false,category:"activity"},musical_score:{keywords:["treble","clef","compose"],char:"🎼",fitzpatrick_scale:false,category:"activity"},musical_keyboard:{keywords:["piano","instrument","compose"],char:"🎹",fitzpatrick_scale:false,category:"activity"},drum:{keywords:["music","instrument","drumsticks","snare"],char:"🥁",fitzpatrick_scale:false,category:"activity"},saxophone:{keywords:["music","instrument","jazz","blues"],char:"🎷",fitzpatrick_scale:false,category:"activity"},trumpet:{keywords:["music","brass"],char:"🎺",fitzpatrick_scale:false,category:"activity"},guitar:{keywords:["music","instrument"],char:"🎸",fitzpatrick_scale:false,category:"activity"},violin:{keywords:["music","instrument","orchestra","symphony"],char:"🎻",fitzpatrick_scale:false,category:"activity"},clapper:{keywords:["movie","film","record"],char:"🎬",fitzpatrick_scale:false,category:"activity"},video_game:{keywords:["play","console","PS4","controller"],char:"🎮",fitzpatrick_scale:false,category:"activity"},space_invader:{keywords:["game","arcade","play"],char:"👾",fitzpatrick_scale:false,category:"activity"},dart:{keywords:["game","play","bar","target","bullseye"],char:"🎯",fitzpatrick_scale:false,category:"activity"},game_die:{keywords:["dice","random","tabletop","play","luck"],char:"🎲",fitzpatrick_scale:false,category:"activity"},chess_pawn:{keywords:["expendable"],char:"♟",fitzpatrick_scale:false,category:"activity"},slot_machine:{keywords:["bet","gamble","vegas","fruit machine","luck","casino"],char:"🎰",fitzpatrick_scale:false,category:"activity"},jigsaw:{keywords:["interlocking","puzzle","piece"],char:"🧩",fitzpatrick_scale:false,category:"activity"},bowling:{keywords:["sports","fun","play"],char:"🎳",fitzpatrick_scale:false,category:"activity"},red_car:{keywords:["red","transportation","vehicle"],char:"🚗",fitzpatrick_scale:false,category:"travel_and_places"},taxi:{keywords:["uber","vehicle","cars","transportation"],char:"🚕",fitzpatrick_scale:false,category:"travel_and_places"},blue_car:{keywords:["transportation","vehicle"],char:"🚙",fitzpatrick_scale:false,category:"travel_and_places"},bus:{keywords:["car","vehicle","transportation"],char:"🚌",fitzpatrick_scale:false,category:"travel_and_places"},trolleybus:{keywords:["bart","transportation","vehicle"],char:"🚎",fitzpatrick_scale:false,category:"travel_and_places"},racing_car:{keywords:["sports","race","fast","formula","f1"],char:"🏎",fitzpatrick_scale:false,category:"travel_and_places"},police_car:{keywords:["vehicle","cars","transportation","law","legal","enforcement"],char:"🚓",fitzpatrick_scale:false,category:"travel_and_places"},ambulance:{keywords:["health","911","hospital"],char:"🚑",fitzpatrick_scale:false,category:"travel_and_places"},fire_engine:{keywords:["transportation","cars","vehicle"],char:"🚒",fitzpatrick_scale:false,category:"travel_and_places"},minibus:{keywords:["vehicle","car","transportation"],char:"🚐",fitzpatrick_scale:false,category:"travel_and_places"},truck:{keywords:["cars","transportation"],char:"🚚",fitzpatrick_scale:false,category:"travel_and_places"},articulated_lorry:{keywords:["vehicle","cars","transportation","express"],char:"🚛",fitzpatrick_scale:false,category:"travel_and_places"},tractor:{keywords:["vehicle","car","farming","agriculture"],char:"🚜",fitzpatrick_scale:false,category:"travel_and_places"},kick_scooter:{keywords:["vehicle","kick","razor"],char:"🛴",fitzpatrick_scale:false,category:"travel_and_places"},motorcycle:{keywords:["race","sports","fast"],char:"🏍",fitzpatrick_scale:false,category:"travel_and_places"},bike:{keywords:["sports","bicycle","exercise","hipster"],char:"🚲",fitzpatrick_scale:false,category:"travel_and_places"},motor_scooter:{keywords:["vehicle","vespa","sasha"],char:"🛵",fitzpatrick_scale:false,category:"travel_and_places"},rotating_light:{keywords:["police","ambulance","911","emergency","alert","error","pinged","law","legal"],char:"🚨",fitzpatrick_scale:false,category:"travel_and_places"},oncoming_police_car:{keywords:["vehicle","law","legal","enforcement","911"],char:"🚔",fitzpatrick_scale:false,category:"travel_and_places"},oncoming_bus:{keywords:["vehicle","transportation"],char:"🚍",fitzpatrick_scale:false,category:"travel_and_places"},oncoming_automobile:{keywords:["car","vehicle","transportation"],char:"🚘",fitzpatrick_scale:false,category:"travel_and_places"},oncoming_taxi:{keywords:["vehicle","cars","uber"],char:"🚖",fitzpatrick_scale:false,category:"travel_and_places"},aerial_tramway:{keywords:["transportation","vehicle","ski"],char:"🚡",fitzpatrick_scale:false,category:"travel_and_places"},mountain_cableway:{keywords:["transportation","vehicle","ski"],char:"🚠",fitzpatrick_scale:false,category:"travel_and_places"},suspension_railway:{keywords:["vehicle","transportation"],char:"🚟",fitzpatrick_scale:false,category:"travel_and_places"},railway_car:{keywords:["transportation","vehicle"],char:"🚃",fitzpatrick_scale:false,category:"travel_and_places"},train:{keywords:["transportation","vehicle","carriage","public","travel"],char:"🚋",fitzpatrick_scale:false,category:"travel_and_places"},monorail:{keywords:["transportation","vehicle"],char:"🚝",fitzpatrick_scale:false,category:"travel_and_places"},bullettrain_side:{keywords:["transportation","vehicle"],char:"🚄",fitzpatrick_scale:false,category:"travel_and_places"},bullettrain_front:{keywords:["transportation","vehicle","speed","fast","public","travel"],char:"🚅",fitzpatrick_scale:false,category:"travel_and_places"},light_rail:{keywords:["transportation","vehicle"],char:"🚈",fitzpatrick_scale:false,category:"travel_and_places"},mountain_railway:{keywords:["transportation","vehicle"],char:"🚞",fitzpatrick_scale:false,category:"travel_and_places"},steam_locomotive:{keywords:["transportation","vehicle","train"],char:"🚂",fitzpatrick_scale:false,category:"travel_and_places"},train2:{keywords:["transportation","vehicle"],char:"🚆",fitzpatrick_scale:false,category:"travel_and_places"},metro:{keywords:["transportation","blue-square","mrt","underground","tube"],char:"🚇",fitzpatrick_scale:false,category:"travel_and_places"},tram:{keywords:["transportation","vehicle"],char:"🚊",fitzpatrick_scale:false,category:"travel_and_places"},station:{keywords:["transportation","vehicle","public"],char:"🚉",fitzpatrick_scale:false,category:"travel_and_places"},flying_saucer:{keywords:["transportation","vehicle","ufo"],char:"🛸",fitzpatrick_scale:false,category:"travel_and_places"},helicopter:{keywords:["transportation","vehicle","fly"],char:"🚁",fitzpatrick_scale:false,category:"travel_and_places"},small_airplane:{keywords:["flight","transportation","fly","vehicle"],char:"🛩",fitzpatrick_scale:false,category:"travel_and_places"},airplane:{keywords:["vehicle","transportation","flight","fly"],char:"✈️",fitzpatrick_scale:false,category:"travel_and_places"},flight_departure:{keywords:["airport","flight","landing"],char:"🛫",fitzpatrick_scale:false,category:"travel_and_places"},flight_arrival:{keywords:["airport","flight","boarding"],char:"🛬",fitzpatrick_scale:false,category:"travel_and_places"},sailboat:{keywords:["ship","summer","transportation","water","sailing"],char:"⛵",fitzpatrick_scale:false,category:"travel_and_places"},motor_boat:{keywords:["ship"],char:"🛥",fitzpatrick_scale:false,category:"travel_and_places"},speedboat:{keywords:["ship","transportation","vehicle","summer"],char:"🚤",fitzpatrick_scale:false,category:"travel_and_places"},ferry:{keywords:["boat","ship","yacht"],char:"⛴",fitzpatrick_scale:false,category:"travel_and_places"},passenger_ship:{keywords:["yacht","cruise","ferry"],char:"🛳",fitzpatrick_scale:false,category:"travel_and_places"},rocket:{keywords:["launch","ship","staffmode","NASA","outer space","outer_space","fly"],char:"🚀",fitzpatrick_scale:false,category:"travel_and_places"},artificial_satellite:{keywords:["communication","gps","orbit","spaceflight","NASA","ISS"],char:"🛰",fitzpatrick_scale:false,category:"travel_and_places"},seat:{keywords:["sit","airplane","transport","bus","flight","fly"],char:"💺",fitzpatrick_scale:false,category:"travel_and_places"},canoe:{keywords:["boat","paddle","water","ship"],char:"🛶",fitzpatrick_scale:false,category:"travel_and_places"},anchor:{keywords:["ship","ferry","sea","boat"],char:"⚓",fitzpatrick_scale:false,category:"travel_and_places"},construction:{keywords:["wip","progress","caution","warning"],char:"🚧",fitzpatrick_scale:false,category:"travel_and_places"},fuelpump:{keywords:["gas station","petroleum"],char:"⛽",fitzpatrick_scale:false,category:"travel_and_places"},busstop:{keywords:["transportation","wait"],char:"🚏",fitzpatrick_scale:false,category:"travel_and_places"},vertical_traffic_light:{keywords:["transportation","driving"],char:"🚦",fitzpatrick_scale:false,category:"travel_and_places"},traffic_light:{keywords:["transportation","signal"],char:"🚥",fitzpatrick_scale:false,category:"travel_and_places"},checkered_flag:{keywords:["contest","finishline","race","gokart"],char:"🏁",fitzpatrick_scale:false,category:"travel_and_places"},ship:{keywords:["transportation","titanic","deploy"],char:"🚢",fitzpatrick_scale:false,category:"travel_and_places"},ferris_wheel:{keywords:["photo","carnival","londoneye"],char:"🎡",fitzpatrick_scale:false,category:"travel_and_places"},roller_coaster:{keywords:["carnival","playground","photo","fun"],char:"🎢",fitzpatrick_scale:false,category:"travel_and_places"},carousel_horse:{keywords:["photo","carnival"],char:"🎠",fitzpatrick_scale:false,category:"travel_and_places"},building_construction:{keywords:["wip","working","progress"],char:"🏗",fitzpatrick_scale:false,category:"travel_and_places"},foggy:{keywords:["photo","mountain"],char:"🌁",fitzpatrick_scale:false,category:"travel_and_places"},tokyo_tower:{keywords:["photo","japanese"],char:"🗼",fitzpatrick_scale:false,category:"travel_and_places"},factory:{keywords:["building","industry","pollution","smoke"],char:"🏭",fitzpatrick_scale:false,category:"travel_and_places"},fountain:{keywords:["photo","summer","water","fresh"],char:"⛲",fitzpatrick_scale:false,category:"travel_and_places"},rice_scene:{keywords:["photo","japan","asia","tsukimi"],char:"🎑",fitzpatrick_scale:false,category:"travel_and_places"},mountain:{keywords:["photo","nature","environment"],char:"⛰",fitzpatrick_scale:false,category:"travel_and_places"},mountain_snow:{keywords:["photo","nature","environment","winter","cold"],char:"🏔",fitzpatrick_scale:false,category:"travel_and_places"},mount_fuji:{keywords:["photo","mountain","nature","japanese"],char:"🗻",fitzpatrick_scale:false,category:"travel_and_places"},volcano:{keywords:["photo","nature","disaster"],char:"🌋",fitzpatrick_scale:false,category:"travel_and_places"},japan:{keywords:["nation","country","japanese","asia"],char:"🗾",fitzpatrick_scale:false,category:"travel_and_places"},camping:{keywords:["photo","outdoors","tent"],char:"🏕",fitzpatrick_scale:false,category:"travel_and_places"},tent:{keywords:["photo","camping","outdoors"],char:"⛺",fitzpatrick_scale:false,category:"travel_and_places"},national_park:{keywords:["photo","environment","nature"],char:"🏞",fitzpatrick_scale:false,category:"travel_and_places"},motorway:{keywords:["road","cupertino","interstate","highway"],char:"🛣",fitzpatrick_scale:false,category:"travel_and_places"},railway_track:{keywords:["train","transportation"],char:"🛤",fitzpatrick_scale:false,category:"travel_and_places"},sunrise:{keywords:["morning","view","vacation","photo"],char:"🌅",fitzpatrick_scale:false,category:"travel_and_places"},sunrise_over_mountains:{keywords:["view","vacation","photo"],char:"🌄",fitzpatrick_scale:false,category:"travel_and_places"},desert:{keywords:["photo","warm","saharah"],char:"🏜",fitzpatrick_scale:false,category:"travel_and_places"},beach_umbrella:{keywords:["weather","summer","sunny","sand","mojito"],char:"🏖",fitzpatrick_scale:false,category:"travel_and_places"},desert_island:{keywords:["photo","tropical","mojito"],char:"🏝",fitzpatrick_scale:false,category:"travel_and_places"},city_sunrise:{keywords:["photo","good morning","dawn"],char:"🌇",fitzpatrick_scale:false,category:"travel_and_places"},city_sunset:{keywords:["photo","evening","sky","buildings"],char:"🌆",fitzpatrick_scale:false,category:"travel_and_places"},cityscape:{keywords:["photo","night life","urban"],char:"🏙",fitzpatrick_scale:false,category:"travel_and_places"},night_with_stars:{keywords:["evening","city","downtown"],char:"🌃",fitzpatrick_scale:false,category:"travel_and_places"},bridge_at_night:{keywords:["photo","sanfrancisco"],char:"🌉",fitzpatrick_scale:false,category:"travel_and_places"},milky_way:{keywords:["photo","space","stars"],char:"🌌",fitzpatrick_scale:false,category:"travel_and_places"},stars:{keywords:["night","photo"],char:"🌠",fitzpatrick_scale:false,category:"travel_and_places"},sparkler:{keywords:["stars","night","shine"],char:"🎇",fitzpatrick_scale:false,category:"travel_and_places"},fireworks:{keywords:["photo","festival","carnival","congratulations"],char:"🎆",fitzpatrick_scale:false,category:"travel_and_places"},rainbow:{keywords:["nature","happy","unicorn_face","photo","sky","spring"],char:"🌈",fitzpatrick_scale:false,category:"travel_and_places"},houses:{keywords:["buildings","photo"],char:"🏘",fitzpatrick_scale:false,category:"travel_and_places"},european_castle:{keywords:["building","royalty","history"],char:"🏰",fitzpatrick_scale:false,category:"travel_and_places"},japanese_castle:{keywords:["photo","building"],char:"🏯",fitzpatrick_scale:false,category:"travel_and_places"},stadium:{keywords:["photo","place","sports","concert","venue"],char:"🏟",fitzpatrick_scale:false,category:"travel_and_places"},statue_of_liberty:{keywords:["american","newyork"],char:"🗽",fitzpatrick_scale:false,category:"travel_and_places"},house:{keywords:["building","home"],char:"🏠",fitzpatrick_scale:false,category:"travel_and_places"},house_with_garden:{keywords:["home","plant","nature"],char:"🏡",fitzpatrick_scale:false,category:"travel_and_places"},derelict_house:{keywords:["abandon","evict","broken","building"],char:"🏚",fitzpatrick_scale:false,category:"travel_and_places"},office:{keywords:["building","bureau","work"],char:"🏢",fitzpatrick_scale:false,category:"travel_and_places"},department_store:{keywords:["building","shopping","mall"],char:"🏬",fitzpatrick_scale:false,category:"travel_and_places"},post_office:{keywords:["building","envelope","communication"],char:"🏣",fitzpatrick_scale:false,category:"travel_and_places"},european_post_office:{keywords:["building","email"],char:"🏤",fitzpatrick_scale:false,category:"travel_and_places"},hospital:{keywords:["building","health","surgery","doctor"],char:"🏥",fitzpatrick_scale:false,category:"travel_and_places"},bank:{keywords:["building","money","sales","cash","business","enterprise"],char:"🏦",fitzpatrick_scale:false,category:"travel_and_places"},hotel:{keywords:["building","accomodation","checkin"],char:"🏨",fitzpatrick_scale:false,category:"travel_and_places"},convenience_store:{keywords:["building","shopping","groceries"],char:"🏪",fitzpatrick_scale:false,category:"travel_and_places"},school:{keywords:["building","student","education","learn","teach"],char:"🏫",fitzpatrick_scale:false,category:"travel_and_places"},love_hotel:{keywords:["like","affection","dating"],char:"🏩",fitzpatrick_scale:false,category:"travel_and_places"},wedding:{keywords:["love","like","affection","couple","marriage","bride","groom"],char:"💒",fitzpatrick_scale:false,category:"travel_and_places"},classical_building:{keywords:["art","culture","history"],char:"🏛",fitzpatrick_scale:false,category:"travel_and_places"},church:{keywords:["building","religion","christ"],char:"⛪",fitzpatrick_scale:false,category:"travel_and_places"},mosque:{keywords:["islam","worship","minaret"],char:"🕌",fitzpatrick_scale:false,category:"travel_and_places"},synagogue:{keywords:["judaism","worship","temple","jewish"],char:"🕍",fitzpatrick_scale:false,category:"travel_and_places"},kaaba:{keywords:["mecca","mosque","islam"],char:"🕋",fitzpatrick_scale:false,category:"travel_and_places"},shinto_shrine:{keywords:["temple","japan","kyoto"],char:"⛩",fitzpatrick_scale:false,category:"travel_and_places"},watch:{keywords:["time","accessories"],char:"⌚",fitzpatrick_scale:false,category:"objects"},iphone:{keywords:["technology","apple","gadgets","dial"],char:"📱",fitzpatrick_scale:false,category:"objects"},calling:{keywords:["iphone","incoming"],char:"📲",fitzpatrick_scale:false,category:"objects"},computer:{keywords:["technology","laptop","screen","display","monitor"],char:"💻",fitzpatrick_scale:false,category:"objects"},keyboard:{keywords:["technology","computer","type","input","text"],char:"⌨",fitzpatrick_scale:false,category:"objects"},desktop_computer:{keywords:["technology","computing","screen"],char:"🖥",fitzpatrick_scale:false,category:"objects"},printer:{keywords:["paper","ink"],char:"🖨",fitzpatrick_scale:false,category:"objects"},computer_mouse:{keywords:["click"],char:"🖱",fitzpatrick_scale:false,category:"objects"},trackball:{keywords:["technology","trackpad"],char:"🖲",fitzpatrick_scale:false,category:"objects"},joystick:{keywords:["game","play"],char:"🕹",fitzpatrick_scale:false,category:"objects"},clamp:{keywords:["tool"],char:"🗜",fitzpatrick_scale:false,category:"objects"},minidisc:{keywords:["technology","record","data","disk","90s"],char:"💽",fitzpatrick_scale:false,category:"objects"},floppy_disk:{keywords:["oldschool","technology","save","90s","80s"],char:"💾",fitzpatrick_scale:false,category:"objects"},cd:{keywords:["technology","dvd","disk","disc","90s"],char:"💿",fitzpatrick_scale:false,category:"objects"},dvd:{keywords:["cd","disk","disc"],char:"📀",fitzpatrick_scale:false,category:"objects"},vhs:{keywords:["record","video","oldschool","90s","80s"],char:"📼",fitzpatrick_scale:false,category:"objects"},camera:{keywords:["gadgets","photography"],char:"📷",fitzpatrick_scale:false,category:"objects"},camera_flash:{keywords:["photography","gadgets"],char:"📸",fitzpatrick_scale:false,category:"objects"},video_camera:{keywords:["film","record"],char:"📹",fitzpatrick_scale:false,category:"objects"},movie_camera:{keywords:["film","record"],char:"🎥",fitzpatrick_scale:false,category:"objects"},film_projector:{keywords:["video","tape","record","movie"],char:"📽",fitzpatrick_scale:false,category:"objects"},film_strip:{keywords:["movie"],char:"🎞",fitzpatrick_scale:false,category:"objects"},telephone_receiver:{keywords:["technology","communication","dial"],char:"📞",fitzpatrick_scale:false,category:"objects"},phone:{keywords:["technology","communication","dial","telephone"],char:"☎️",fitzpatrick_scale:false,category:"objects"},pager:{keywords:["bbcall","oldschool","90s"],char:"📟",fitzpatrick_scale:false,category:"objects"},fax:{keywords:["communication","technology"],char:"📠",fitzpatrick_scale:false,category:"objects"},tv:{keywords:["technology","program","oldschool","show","television"],char:"📺",fitzpatrick_scale:false,category:"objects"},radio:{keywords:["communication","music","podcast","program"],char:"📻",fitzpatrick_scale:false,category:"objects"},studio_microphone:{keywords:["sing","recording","artist","talkshow"],char:"🎙",fitzpatrick_scale:false,category:"objects"},level_slider:{keywords:["scale"],char:"🎚",fitzpatrick_scale:false,category:"objects"},control_knobs:{keywords:["dial"],char:"🎛",fitzpatrick_scale:false,category:"objects"},compass:{keywords:["magnetic","navigation","orienteering"],char:"🧭",fitzpatrick_scale:false,category:"objects"},stopwatch:{keywords:["time","deadline"],char:"⏱",fitzpatrick_scale:false,category:"objects"},timer_clock:{keywords:["alarm"],char:"⏲",fitzpatrick_scale:false,category:"objects"},alarm_clock:{keywords:["time","wake"],char:"⏰",fitzpatrick_scale:false,category:"objects"},mantelpiece_clock:{keywords:["time"],char:"🕰",fitzpatrick_scale:false,category:"objects"},hourglass_flowing_sand:{keywords:["oldschool","time","countdown"],char:"⏳",fitzpatrick_scale:false,category:"objects"},hourglass:{keywords:["time","clock","oldschool","limit","exam","quiz","test"],char:"⌛",fitzpatrick_scale:false,category:"objects"},satellite:{keywords:["communication","future","radio","space"],char:"📡",fitzpatrick_scale:false,category:"objects"},battery:{keywords:["power","energy","sustain"],char:"🔋",fitzpatrick_scale:false,category:"objects"},electric_plug:{keywords:["charger","power"],char:"🔌",fitzpatrick_scale:false,category:"objects"},bulb:{keywords:["light","electricity","idea"],char:"💡",fitzpatrick_scale:false,category:"objects"},flashlight:{keywords:["dark","camping","sight","night"],char:"🔦",fitzpatrick_scale:false,category:"objects"},candle:{keywords:["fire","wax"],char:"🕯",fitzpatrick_scale:false,category:"objects"},fire_extinguisher:{keywords:["quench"],char:"🧯",fitzpatrick_scale:false,category:"objects"},wastebasket:{keywords:["bin","trash","rubbish","garbage","toss"],char:"🗑",fitzpatrick_scale:false,category:"objects"},oil_drum:{keywords:["barrell"],char:"🛢",fitzpatrick_scale:false,category:"objects"},money_with_wings:{keywords:["dollar","bills","payment","sale"],char:"💸",fitzpatrick_scale:false,category:"objects"},dollar:{keywords:["money","sales","bill","currency"],char:"💵",fitzpatrick_scale:false,category:"objects"},yen:{keywords:["money","sales","japanese","dollar","currency"],char:"💴",fitzpatrick_scale:false,category:"objects"},euro:{keywords:["money","sales","dollar","currency"],char:"💶",fitzpatrick_scale:false,category:"objects"},pound:{keywords:["british","sterling","money","sales","bills","uk","england","currency"],char:"💷",fitzpatrick_scale:false,category:"objects"},moneybag:{keywords:["dollar","payment","coins","sale"],char:"💰",fitzpatrick_scale:false,category:"objects"},credit_card:{keywords:["money","sales","dollar","bill","payment","shopping"],char:"💳",fitzpatrick_scale:false,category:"objects"},gem:{keywords:["blue","ruby","diamond","jewelry"],char:"💎",fitzpatrick_scale:false,category:"objects"},balance_scale:{keywords:["law","fairness","weight"],char:"⚖",fitzpatrick_scale:false,category:"objects"},toolbox:{keywords:["tools","diy","fix","maintainer","mechanic"],char:"🧰",fitzpatrick_scale:false,category:"objects"},wrench:{keywords:["tools","diy","ikea","fix","maintainer"],char:"🔧",fitzpatrick_scale:false,category:"objects"},hammer:{keywords:["tools","build","create"],char:"🔨",fitzpatrick_scale:false,category:"objects"},hammer_and_pick:{keywords:["tools","build","create"],char:"⚒",fitzpatrick_scale:false,category:"objects"},hammer_and_wrench:{keywords:["tools","build","create"],char:"🛠",fitzpatrick_scale:false,category:"objects"},pick:{keywords:["tools","dig"],char:"⛏",fitzpatrick_scale:false,category:"objects"},nut_and_bolt:{keywords:["handy","tools","fix"],char:"🔩",fitzpatrick_scale:false,category:"objects"},gear:{keywords:["cog"],char:"⚙",fitzpatrick_scale:false,category:"objects"},brick:{keywords:["bricks"],char:"🧱",fitzpatrick_scale:false,category:"objects"},chains:{keywords:["lock","arrest"],char:"⛓",fitzpatrick_scale:false,category:"objects"},magnet:{keywords:["attraction","magnetic"],char:"🧲",fitzpatrick_scale:false,category:"objects"},gun:{keywords:["violence","weapon","pistol","revolver"],char:"🔫",fitzpatrick_scale:false,category:"objects"},bomb:{keywords:["boom","explode","explosion","terrorism"],char:"💣",fitzpatrick_scale:false,category:"objects"},firecracker:{keywords:["dynamite","boom","explode","explosion","explosive"],char:"🧨",fitzpatrick_scale:false,category:"objects"},hocho:{keywords:["knife","blade","cutlery","kitchen","weapon"],char:"🔪",fitzpatrick_scale:false,category:"objects"},dagger:{keywords:["weapon"],char:"🗡",fitzpatrick_scale:false,category:"objects"},crossed_swords:{keywords:["weapon"],char:"⚔",fitzpatrick_scale:false,category:"objects"},shield:{keywords:["protection","security"],char:"🛡",fitzpatrick_scale:false,category:"objects"},smoking:{keywords:["kills","tobacco","cigarette","joint","smoke"],char:"🚬",fitzpatrick_scale:false,category:"objects"},skull_and_crossbones:{keywords:["poison","danger","deadly","scary","death","pirate","evil"],char:"☠",fitzpatrick_scale:false,category:"objects"},coffin:{keywords:["vampire","dead","die","death","rip","graveyard","cemetery","casket","funeral","box"],char:"⚰",fitzpatrick_scale:false,category:"objects"},funeral_urn:{keywords:["dead","die","death","rip","ashes"],char:"⚱",fitzpatrick_scale:false,category:"objects"},amphora:{keywords:["vase","jar"],char:"🏺",fitzpatrick_scale:false,category:"objects"},crystal_ball:{keywords:["disco","party","magic","circus","fortune_teller"],char:"🔮",fitzpatrick_scale:false,category:"objects"},prayer_beads:{keywords:["dhikr","religious"],char:"📿",fitzpatrick_scale:false,category:"objects"},nazar_amulet:{keywords:["bead","charm"],char:"🧿",fitzpatrick_scale:false,category:"objects"},barber:{keywords:["hair","salon","style"],char:"💈",fitzpatrick_scale:false,category:"objects"},alembic:{keywords:["distilling","science","experiment","chemistry"],char:"⚗",fitzpatrick_scale:false,category:"objects"},telescope:{keywords:["stars","space","zoom","science","astronomy"],char:"🔭",fitzpatrick_scale:false,category:"objects"},microscope:{keywords:["laboratory","experiment","zoomin","science","study"],char:"🔬",fitzpatrick_scale:false,category:"objects"},hole:{keywords:["embarrassing"],char:"🕳",fitzpatrick_scale:false,category:"objects"},pill:{keywords:["health","medicine","doctor","pharmacy","drug"],char:"💊",fitzpatrick_scale:false,category:"objects"},syringe:{keywords:["health","hospital","drugs","blood","medicine","needle","doctor","nurse"],char:"💉",fitzpatrick_scale:false,category:"objects"},dna:{keywords:["biologist","genetics","life"],char:"🧬",fitzpatrick_scale:false,category:"objects"},microbe:{keywords:["amoeba","bacteria","germs"],char:"🦠",fitzpatrick_scale:false,category:"objects"},petri_dish:{keywords:["bacteria","biology","culture","lab"],char:"🧫",fitzpatrick_scale:false,category:"objects"},test_tube:{keywords:["chemistry","experiment","lab","science"],char:"🧪",fitzpatrick_scale:false,category:"objects"},thermometer:{keywords:["weather","temperature","hot","cold"],char:"🌡",fitzpatrick_scale:false,category:"objects"},broom:{keywords:["cleaning","sweeping","witch"],char:"🧹",fitzpatrick_scale:false,category:"objects"},basket:{keywords:["laundry"],char:"🧺",fitzpatrick_scale:false,category:"objects"},toilet_paper:{keywords:["roll"],char:"🧻",fitzpatrick_scale:false,category:"objects"},label:{keywords:["sale","tag"],char:"🏷",fitzpatrick_scale:false,category:"objects"},bookmark:{keywords:["favorite","label","save"],char:"🔖",fitzpatrick_scale:false,category:"objects"},toilet:{keywords:["restroom","wc","washroom","bathroom","potty"],char:"🚽",fitzpatrick_scale:false,category:"objects"},shower:{keywords:["clean","water","bathroom"],char:"🚿",fitzpatrick_scale:false,category:"objects"},bathtub:{keywords:["clean","shower","bathroom"],char:"🛁",fitzpatrick_scale:false,category:"objects"},soap:{keywords:["bar","bathing","cleaning","lather"],char:"🧼",fitzpatrick_scale:false,category:"objects"},sponge:{keywords:["absorbing","cleaning","porous"],char:"🧽",fitzpatrick_scale:false,category:"objects"},lotion_bottle:{keywords:["moisturizer","sunscreen"],char:"🧴",fitzpatrick_scale:false,category:"objects"},key:{keywords:["lock","door","password"],char:"🔑",fitzpatrick_scale:false,category:"objects"},old_key:{keywords:["lock","door","password"],char:"🗝",fitzpatrick_scale:false,category:"objects"},couch_and_lamp:{keywords:["read","chill"],char:"🛋",fitzpatrick_scale:false,category:"objects"},sleeping_bed:{keywords:["bed","rest"],char:"🛌",fitzpatrick_scale:true,category:"objects"},bed:{keywords:["sleep","rest"],char:"🛏",fitzpatrick_scale:false,category:"objects"},door:{keywords:["house","entry","exit"],char:"🚪",fitzpatrick_scale:false,category:"objects"},bellhop_bell:{keywords:["service"],char:"🛎",fitzpatrick_scale:false,category:"objects"},teddy_bear:{keywords:["plush","stuffed"],char:"🧸",fitzpatrick_scale:false,category:"objects"},framed_picture:{keywords:["photography"],char:"🖼",fitzpatrick_scale:false,category:"objects"},world_map:{keywords:["location","direction"],char:"🗺",fitzpatrick_scale:false,category:"objects"},parasol_on_ground:{keywords:["weather","summer"],char:"⛱",fitzpatrick_scale:false,category:"objects"},moyai:{keywords:["rock","easter island","moai"],char:"🗿",fitzpatrick_scale:false,category:"objects"},shopping:{keywords:["mall","buy","purchase"],char:"🛍",fitzpatrick_scale:false,category:"objects"},shopping_cart:{keywords:["trolley"],char:"🛒",fitzpatrick_scale:false,category:"objects"},balloon:{keywords:["party","celebration","birthday","circus"],char:"🎈",fitzpatrick_scale:false,category:"objects"},flags:{keywords:["fish","japanese","koinobori","carp","banner"],char:"🎏",fitzpatrick_scale:false,category:"objects"},ribbon:{keywords:["decoration","pink","girl","bowtie"],char:"🎀",fitzpatrick_scale:false,category:"objects"},gift:{keywords:["present","birthday","christmas","xmas"],char:"🎁",fitzpatrick_scale:false,category:"objects"},confetti_ball:{keywords:["festival","party","birthday","circus"],char:"🎊",fitzpatrick_scale:false,category:"objects"},tada:{keywords:["party","congratulations","birthday","magic","circus","celebration"],char:"🎉",fitzpatrick_scale:false,category:"objects"},dolls:{keywords:["japanese","toy","kimono"],char:"🎎",fitzpatrick_scale:false,category:"objects"},wind_chime:{keywords:["nature","ding","spring","bell"],char:"🎐",fitzpatrick_scale:false,category:"objects"},crossed_flags:{keywords:["japanese","nation","country","border"],char:"🎌",fitzpatrick_scale:false,category:"objects"},izakaya_lantern:{keywords:["light","paper","halloween","spooky"],char:"🏮",fitzpatrick_scale:false,category:"objects"},red_envelope:{keywords:["gift"],char:"🧧",fitzpatrick_scale:false,category:"objects"},email:{keywords:["letter","postal","inbox","communication"],char:"✉️",fitzpatrick_scale:false,category:"objects"},envelope_with_arrow:{keywords:["email","communication"],char:"📩",fitzpatrick_scale:false,category:"objects"},incoming_envelope:{keywords:["email","inbox"],char:"📨",fitzpatrick_scale:false,category:"objects"},"e-mail":{keywords:["communication","inbox"],char:"📧",fitzpatrick_scale:false,category:"objects"},love_letter:{keywords:["email","like","affection","envelope","valentines"],char:"💌",fitzpatrick_scale:false,category:"objects"},postbox:{keywords:["email","letter","envelope"],char:"📮",fitzpatrick_scale:false,category:"objects"},mailbox_closed:{keywords:["email","communication","inbox"],char:"📪",fitzpatrick_scale:false,category:"objects"},mailbox:{keywords:["email","inbox","communication"],char:"📫",fitzpatrick_scale:false,category:"objects"},mailbox_with_mail:{keywords:["email","inbox","communication"],char:"📬",fitzpatrick_scale:false,category:"objects"},mailbox_with_no_mail:{keywords:["email","inbox"],char:"📭",fitzpatrick_scale:false,category:"objects"},package:{keywords:["mail","gift","cardboard","box","moving"],char:"📦",fitzpatrick_scale:false,category:"objects"},postal_horn:{keywords:["instrument","music"],char:"📯",fitzpatrick_scale:false,category:"objects"},inbox_tray:{keywords:["email","documents"],char:"📥",fitzpatrick_scale:false,category:"objects"},outbox_tray:{keywords:["inbox","email"],char:"📤",fitzpatrick_scale:false,category:"objects"},scroll:{keywords:["documents","ancient","history","paper"],char:"📜",fitzpatrick_scale:false,category:"objects"},page_with_curl:{keywords:["documents","office","paper"],char:"📃",fitzpatrick_scale:false,category:"objects"},bookmark_tabs:{keywords:["favorite","save","order","tidy"],char:"📑",fitzpatrick_scale:false,category:"objects"},receipt:{keywords:["accounting","expenses"],char:"🧾",fitzpatrick_scale:false,category:"objects"},bar_chart:{keywords:["graph","presentation","stats"],char:"📊",fitzpatrick_scale:false,category:"objects"},chart_with_upwards_trend:{keywords:["graph","presentation","stats","recovery","business","economics","money","sales","good","success"],char:"📈",fitzpatrick_scale:false,category:"objects"},chart_with_downwards_trend:{keywords:["graph","presentation","stats","recession","business","economics","money","sales","bad","failure"],char:"📉",fitzpatrick_scale:false,category:"objects"},page_facing_up:{keywords:["documents","office","paper","information"],char:"📄",fitzpatrick_scale:false,category:"objects"},date:{keywords:["calendar","schedule"],char:"📅",fitzpatrick_scale:false,category:"objects"},calendar:{keywords:["schedule","date","planning"],char:"📆",fitzpatrick_scale:false,category:"objects"},spiral_calendar:{keywords:["date","schedule","planning"],char:"🗓",fitzpatrick_scale:false,category:"objects"},card_index:{keywords:["business","stationery"],char:"📇",fitzpatrick_scale:false,category:"objects"},card_file_box:{keywords:["business","stationery"],char:"🗃",fitzpatrick_scale:false,category:"objects"},ballot_box:{keywords:["election","vote"],char:"🗳",fitzpatrick_scale:false,category:"objects"},file_cabinet:{keywords:["filing","organizing"],char:"🗄",fitzpatrick_scale:false,category:"objects"},clipboard:{keywords:["stationery","documents"],char:"📋",fitzpatrick_scale:false,category:"objects"},spiral_notepad:{keywords:["memo","stationery"],char:"🗒",fitzpatrick_scale:false,category:"objects"},file_folder:{keywords:["documents","business","office"],char:"📁",fitzpatrick_scale:false,category:"objects"},open_file_folder:{keywords:["documents","load"],char:"📂",fitzpatrick_scale:false,category:"objects"},card_index_dividers:{keywords:["organizing","business","stationery"],char:"🗂",fitzpatrick_scale:false,category:"objects"},newspaper_roll:{keywords:["press","headline"],char:"🗞",fitzpatrick_scale:false,category:"objects"},newspaper:{keywords:["press","headline"],char:"📰",fitzpatrick_scale:false,category:"objects"},notebook:{keywords:["stationery","record","notes","paper","study"],char:"📓",fitzpatrick_scale:false,category:"objects"},closed_book:{keywords:["read","library","knowledge","textbook","learn"],char:"📕",fitzpatrick_scale:false,category:"objects"},green_book:{keywords:["read","library","knowledge","study"],char:"📗",fitzpatrick_scale:false,category:"objects"},blue_book:{keywords:["read","library","knowledge","learn","study"],char:"📘",fitzpatrick_scale:false,category:"objects"},orange_book:{keywords:["read","library","knowledge","textbook","study"],char:"📙",fitzpatrick_scale:false,category:"objects"},notebook_with_decorative_cover:{keywords:["classroom","notes","record","paper","study"],char:"📔",fitzpatrick_scale:false,category:"objects"},ledger:{keywords:["notes","paper"],char:"📒",fitzpatrick_scale:false,category:"objects"},books:{keywords:["literature","library","study"],char:"📚",fitzpatrick_scale:false,category:"objects"},open_book:{keywords:["book","read","library","knowledge","literature","learn","study"],char:"📖",fitzpatrick_scale:false,category:"objects"},safety_pin:{keywords:["diaper"],char:"🧷",fitzpatrick_scale:false,category:"objects"},link:{keywords:["rings","url"],char:"🔗",fitzpatrick_scale:false,category:"objects"},paperclip:{keywords:["documents","stationery"],char:"📎",fitzpatrick_scale:false,category:"objects"},paperclips:{keywords:["documents","stationery"],char:"🖇",fitzpatrick_scale:false,category:"objects"},scissors:{keywords:["stationery","cut"],char:"✂️",fitzpatrick_scale:false,category:"objects"},triangular_ruler:{keywords:["stationery","math","architect","sketch"],char:"📐",fitzpatrick_scale:false,category:"objects"},straight_ruler:{keywords:["stationery","calculate","length","math","school","drawing","architect","sketch"],char:"📏",fitzpatrick_scale:false,category:"objects"},abacus:{keywords:["calculation"],char:"🧮",fitzpatrick_scale:false,category:"objects"},pushpin:{keywords:["stationery","mark","here"],char:"📌",fitzpatrick_scale:false,category:"objects"},round_pushpin:{keywords:["stationery","location","map","here"],char:"📍",fitzpatrick_scale:false,category:"objects"},triangular_flag_on_post:{keywords:["mark","milestone","place"],char:"🚩",fitzpatrick_scale:false,category:"objects"},white_flag:{keywords:["losing","loser","lost","surrender","give up","fail"],char:"🏳",fitzpatrick_scale:false,category:"objects"},black_flag:{keywords:["pirate"],char:"🏴",fitzpatrick_scale:false,category:"objects"},rainbow_flag:{keywords:["flag","rainbow","pride","gay","lgbt","glbt","queer","homosexual","lesbian","bisexual","transgender"],char:"🏳️‍🌈",fitzpatrick_scale:false,category:"objects"},closed_lock_with_key:{keywords:["security","privacy"],char:"🔐",fitzpatrick_scale:false,category:"objects"},lock:{keywords:["security","password","padlock"],char:"🔒",fitzpatrick_scale:false,category:"objects"},unlock:{keywords:["privacy","security"],char:"🔓",fitzpatrick_scale:false,category:"objects"},lock_with_ink_pen:{keywords:["security","secret"],char:"🔏",fitzpatrick_scale:false,category:"objects"},pen:{keywords:["stationery","writing","write"],char:"🖊",fitzpatrick_scale:false,category:"objects"},fountain_pen:{keywords:["stationery","writing","write"],char:"🖋",fitzpatrick_scale:false,category:"objects"},black_nib:{keywords:["pen","stationery","writing","write"],char:"✒️",fitzpatrick_scale:false,category:"objects"},memo:{keywords:["write","documents","stationery","pencil","paper","writing","legal","exam","quiz","test","study","compose"],char:"📝",fitzpatrick_scale:false,category:"objects"},pencil2:{keywords:["stationery","write","paper","writing","school","study"],char:"✏️",fitzpatrick_scale:false,category:"objects"},crayon:{keywords:["drawing","creativity"],char:"🖍",fitzpatrick_scale:false,category:"objects"},paintbrush:{keywords:["drawing","creativity","art"],char:"🖌",fitzpatrick_scale:false,category:"objects"},mag:{keywords:["search","zoom","find","detective"],char:"🔍",fitzpatrick_scale:false,category:"objects"},mag_right:{keywords:["search","zoom","find","detective"],char:"🔎",fitzpatrick_scale:false,category:"objects"},heart:{keywords:["love","like","valentines"],char:"❤️",fitzpatrick_scale:false,category:"symbols"},orange_heart:{keywords:["love","like","affection","valentines"],char:"🧡",fitzpatrick_scale:false,category:"symbols"},yellow_heart:{keywords:["love","like","affection","valentines"],char:"💛",fitzpatrick_scale:false,category:"symbols"},green_heart:{keywords:["love","like","affection","valentines"],char:"💚",fitzpatrick_scale:false,category:"symbols"},blue_heart:{keywords:["love","like","affection","valentines"],char:"💙",fitzpatrick_scale:false,category:"symbols"},purple_heart:{keywords:["love","like","affection","valentines"],char:"💜",fitzpatrick_scale:false,category:"symbols"},black_heart:{keywords:["evil"],char:"🖤",fitzpatrick_scale:false,category:"symbols"},broken_heart:{keywords:["sad","sorry","break","heart","heartbreak"],char:"💔",fitzpatrick_scale:false,category:"symbols"},heavy_heart_exclamation:{keywords:["decoration","love"],char:"❣",fitzpatrick_scale:false,category:"symbols"},two_hearts:{keywords:["love","like","affection","valentines","heart"],char:"💕",fitzpatrick_scale:false,category:"symbols"},revolving_hearts:{keywords:["love","like","affection","valentines"],char:"💞",fitzpatrick_scale:false,category:"symbols"},heartbeat:{keywords:["love","like","affection","valentines","pink","heart"],char:"💓",fitzpatrick_scale:false,category:"symbols"},heartpulse:{keywords:["like","love","affection","valentines","pink"],char:"💗",fitzpatrick_scale:false,category:"symbols"},sparkling_heart:{keywords:["love","like","affection","valentines"],char:"💖",fitzpatrick_scale:false,category:"symbols"},cupid:{keywords:["love","like","heart","affection","valentines"],char:"💘",fitzpatrick_scale:false,category:"symbols"},gift_heart:{keywords:["love","valentines"],char:"💝",fitzpatrick_scale:false,category:"symbols"},heart_decoration:{keywords:["purple-square","love","like"],char:"💟",fitzpatrick_scale:false,category:"symbols"},peace_symbol:{keywords:["hippie"],char:"☮",fitzpatrick_scale:false,category:"symbols"},latin_cross:{keywords:["christianity"],char:"✝",fitzpatrick_scale:false,category:"symbols"},star_and_crescent:{keywords:["islam"],char:"☪",fitzpatrick_scale:false,category:"symbols"},om:{keywords:["hinduism","buddhism","sikhism","jainism"],char:"🕉",fitzpatrick_scale:false,category:"symbols"},wheel_of_dharma:{keywords:["hinduism","buddhism","sikhism","jainism"],char:"☸",fitzpatrick_scale:false,category:"symbols"},star_of_david:{keywords:["judaism"],char:"✡",fitzpatrick_scale:false,category:"symbols"},six_pointed_star:{keywords:["purple-square","religion","jewish","hexagram"],char:"🔯",fitzpatrick_scale:false,category:"symbols"},menorah:{keywords:["hanukkah","candles","jewish"],char:"🕎",fitzpatrick_scale:false,category:"symbols"},yin_yang:{keywords:["balance"],char:"☯",fitzpatrick_scale:false,category:"symbols"},orthodox_cross:{keywords:["suppedaneum","religion"],char:"☦",fitzpatrick_scale:false,category:"symbols"},place_of_worship:{keywords:["religion","church","temple","prayer"],char:"🛐",fitzpatrick_scale:false,category:"symbols"},ophiuchus:{keywords:["sign","purple-square","constellation","astrology"],char:"⛎",fitzpatrick_scale:false,category:"symbols"},aries:{keywords:["sign","purple-square","zodiac","astrology"],char:"♈",fitzpatrick_scale:false,category:"symbols"},taurus:{keywords:["purple-square","sign","zodiac","astrology"],char:"♉",fitzpatrick_scale:false,category:"symbols"},gemini:{keywords:["sign","zodiac","purple-square","astrology"],char:"♊",fitzpatrick_scale:false,category:"symbols"},cancer:{keywords:["sign","zodiac","purple-square","astrology"],char:"♋",fitzpatrick_scale:false,category:"symbols"},leo:{keywords:["sign","purple-square","zodiac","astrology"],char:"♌",fitzpatrick_scale:false,category:"symbols"},virgo:{keywords:["sign","zodiac","purple-square","astrology"],char:"♍",fitzpatrick_scale:false,category:"symbols"},libra:{keywords:["sign","purple-square","zodiac","astrology"],char:"♎",fitzpatrick_scale:false,category:"symbols"},scorpius:{keywords:["sign","zodiac","purple-square","astrology","scorpio"],char:"♏",fitzpatrick_scale:false,category:"symbols"},sagittarius:{keywords:["sign","zodiac","purple-square","astrology"],char:"♐",fitzpatrick_scale:false,category:"symbols"},capricorn:{keywords:["sign","zodiac","purple-square","astrology"],char:"♑",fitzpatrick_scale:false,category:"symbols"},aquarius:{keywords:["sign","purple-square","zodiac","astrology"],char:"♒",fitzpatrick_scale:false,category:"symbols"},pisces:{keywords:["purple-square","sign","zodiac","astrology"],char:"♓",fitzpatrick_scale:false,category:"symbols"},id:{keywords:["purple-square","words"],char:"🆔",fitzpatrick_scale:false,category:"symbols"},atom_symbol:{keywords:["science","physics","chemistry"],char:"⚛",fitzpatrick_scale:false,category:"symbols"},u7a7a:{keywords:["kanji","japanese","chinese","empty","sky","blue-square"],char:"🈳",fitzpatrick_scale:false,category:"symbols"},u5272:{keywords:["cut","divide","chinese","kanji","pink-square"],char:"🈹",fitzpatrick_scale:false,category:"symbols"},radioactive:{keywords:["nuclear","danger"],char:"☢",fitzpatrick_scale:false,category:"symbols"},biohazard:{keywords:["danger"],char:"☣",fitzpatrick_scale:false,category:"symbols"},mobile_phone_off:{keywords:["mute","orange-square","silence","quiet"],char:"📴",fitzpatrick_scale:false,category:"symbols"},vibration_mode:{keywords:["orange-square","phone"],char:"📳",fitzpatrick_scale:false,category:"symbols"},u6709:{keywords:["orange-square","chinese","have","kanji"],char:"🈶",fitzpatrick_scale:false,category:"symbols"},u7121:{keywords:["nothing","chinese","kanji","japanese","orange-square"],char:"🈚",fitzpatrick_scale:false,category:"symbols"},u7533:{keywords:["chinese","japanese","kanji","orange-square"],char:"🈸",fitzpatrick_scale:false,category:"symbols"},u55b6:{keywords:["japanese","opening hours","orange-square"],char:"🈺",fitzpatrick_scale:false,category:"symbols"},u6708:{keywords:["chinese","month","moon","japanese","orange-square","kanji"],char:"🈷️",fitzpatrick_scale:false,category:"symbols"},eight_pointed_black_star:{keywords:["orange-square","shape","polygon"],char:"✴️",fitzpatrick_scale:false,category:"symbols"},vs:{keywords:["words","orange-square"],char:"🆚",fitzpatrick_scale:false,category:"symbols"},accept:{keywords:["ok","good","chinese","kanji","agree","yes","orange-circle"],char:"🉑",fitzpatrick_scale:false,category:"symbols"},white_flower:{keywords:["japanese","spring"],char:"💮",fitzpatrick_scale:false,category:"symbols"},ideograph_advantage:{keywords:["chinese","kanji","obtain","get","circle"],char:"🉐",fitzpatrick_scale:false,category:"symbols"},secret:{keywords:["privacy","chinese","sshh","kanji","red-circle"],char:"㊙️",fitzpatrick_scale:false,category:"symbols"},congratulations:{keywords:["chinese","kanji","japanese","red-circle"],char:"㊗️",fitzpatrick_scale:false,category:"symbols"},u5408:{keywords:["japanese","chinese","join","kanji","red-square"],char:"🈴",fitzpatrick_scale:false,category:"symbols"},u6e80:{keywords:["full","chinese","japanese","red-square","kanji"],char:"🈵",fitzpatrick_scale:false,category:"symbols"},u7981:{keywords:["kanji","japanese","chinese","forbidden","limit","restricted","red-square"],char:"🈲",fitzpatrick_scale:false,category:"symbols"},a:{keywords:["red-square","alphabet","letter"],char:"🅰️",fitzpatrick_scale:false,category:"symbols"},b:{keywords:["red-square","alphabet","letter"],char:"🅱️",fitzpatrick_scale:false,category:"symbols"},ab:{keywords:["red-square","alphabet"],char:"🆎",fitzpatrick_scale:false,category:"symbols"},cl:{keywords:["alphabet","words","red-square"],char:"🆑",fitzpatrick_scale:false,category:"symbols"},o2:{keywords:["alphabet","red-square","letter"],char:"🅾️",fitzpatrick_scale:false,category:"symbols"},sos:{keywords:["help","red-square","words","emergency","911"],char:"🆘",fitzpatrick_scale:false,category:"symbols"},no_entry:{keywords:["limit","security","privacy","bad","denied","stop","circle"],char:"⛔",fitzpatrick_scale:false,category:"symbols"},name_badge:{keywords:["fire","forbid"],char:"📛",fitzpatrick_scale:false,category:"symbols"},no_entry_sign:{keywords:["forbid","stop","limit","denied","disallow","circle"],char:"🚫",fitzpatrick_scale:false,category:"symbols"},x:{keywords:["no","delete","remove","cancel","red"],char:"❌",fitzpatrick_scale:false,category:"symbols"},o:{keywords:["circle","round"],char:"⭕",fitzpatrick_scale:false,category:"symbols"},stop_sign:{keywords:["stop"],char:"🛑",fitzpatrick_scale:false,category:"symbols"},anger:{keywords:["angry","mad"],char:"💢",fitzpatrick_scale:false,category:"symbols"},hotsprings:{keywords:["bath","warm","relax"],char:"♨️",fitzpatrick_scale:false,category:"symbols"},no_pedestrians:{keywords:["rules","crossing","walking","circle"],char:"🚷",fitzpatrick_scale:false,category:"symbols"},do_not_litter:{keywords:["trash","bin","garbage","circle"],char:"🚯",fitzpatrick_scale:false,category:"symbols"},no_bicycles:{keywords:["cyclist","prohibited","circle"],char:"🚳",fitzpatrick_scale:false,category:"symbols"},"non-potable_water":{keywords:["drink","faucet","tap","circle"],char:"🚱",fitzpatrick_scale:false,category:"symbols"},underage:{keywords:["18","drink","pub","night","minor","circle"],char:"🔞",fitzpatrick_scale:false,category:"symbols"},no_mobile_phones:{keywords:["iphone","mute","circle"],char:"📵",fitzpatrick_scale:false,category:"symbols"},exclamation:{keywords:["heavy_exclamation_mark","danger","surprise","punctuation","wow","warning"],char:"❗",fitzpatrick_scale:false,category:"symbols"},grey_exclamation:{keywords:["surprise","punctuation","gray","wow","warning"],char:"❕",fitzpatrick_scale:false,category:"symbols"},question:{keywords:["doubt","confused"],char:"❓",fitzpatrick_scale:false,category:"symbols"},grey_question:{keywords:["doubts","gray","huh","confused"],char:"❔",fitzpatrick_scale:false,category:"symbols"},bangbang:{keywords:["exclamation","surprise"],char:"‼️",fitzpatrick_scale:false,category:"symbols"},interrobang:{keywords:["wat","punctuation","surprise"],char:"⁉️",fitzpatrick_scale:false,category:"symbols"},100:{keywords:["score","perfect","numbers","century","exam","quiz","test","pass","hundred"],char:"💯",fitzpatrick_scale:false,category:"symbols"},low_brightness:{keywords:["sun","afternoon","warm","summer"],char:"🔅",fitzpatrick_scale:false,category:"symbols"},high_brightness:{keywords:["sun","light"],char:"🔆",fitzpatrick_scale:false,category:"symbols"},trident:{keywords:["weapon","spear"],char:"🔱",fitzpatrick_scale:false,category:"symbols"},fleur_de_lis:{keywords:["decorative","scout"],char:"⚜",fitzpatrick_scale:false,category:"symbols"},part_alternation_mark:{keywords:["graph","presentation","stats","business","economics","bad"],char:"〽️",fitzpatrick_scale:false,category:"symbols"},warning:{keywords:["exclamation","wip","alert","error","problem","issue"],char:"⚠️",fitzpatrick_scale:false,category:"symbols"},children_crossing:{keywords:["school","warning","danger","sign","driving","yellow-diamond"],char:"🚸",fitzpatrick_scale:false,category:"symbols"},beginner:{keywords:["badge","shield"],char:"🔰",fitzpatrick_scale:false,category:"symbols"},recycle:{keywords:["arrow","environment","garbage","trash"],char:"♻️",fitzpatrick_scale:false,category:"symbols"},u6307:{keywords:["chinese","point","green-square","kanji"],char:"🈯",fitzpatrick_scale:false,category:"symbols"},chart:{keywords:["green-square","graph","presentation","stats"],char:"💹",fitzpatrick_scale:false,category:"symbols"},sparkle:{keywords:["stars","green-square","awesome","good","fireworks"],char:"❇️",fitzpatrick_scale:false,category:"symbols"},eight_spoked_asterisk:{keywords:["star","sparkle","green-square"],char:"✳️",fitzpatrick_scale:false,category:"symbols"},negative_squared_cross_mark:{keywords:["x","green-square","no","deny"],char:"❎",fitzpatrick_scale:false,category:"symbols"},white_check_mark:{keywords:["green-square","ok","agree","vote","election","answer","tick"],char:"✅",fitzpatrick_scale:false,category:"symbols"},diamond_shape_with_a_dot_inside:{keywords:["jewel","blue","gem","crystal","fancy"],char:"💠",fitzpatrick_scale:false,category:"symbols"},cyclone:{keywords:["weather","swirl","blue","cloud","vortex","spiral","whirlpool","spin","tornado","hurricane","typhoon"],char:"🌀",fitzpatrick_scale:false,category:"symbols"},loop:{keywords:["tape","cassette"],char:"➿",fitzpatrick_scale:false,category:"symbols"},globe_with_meridians:{keywords:["earth","international","world","internet","interweb","i18n"],char:"🌐",fitzpatrick_scale:false,category:"symbols"},m:{keywords:["alphabet","blue-circle","letter"],char:"Ⓜ️",fitzpatrick_scale:false,category:"symbols"},atm:{keywords:["money","sales","cash","blue-square","payment","bank"],char:"🏧",fitzpatrick_scale:false,category:"symbols"},sa:{keywords:["japanese","blue-square","katakana"],char:"🈂️",fitzpatrick_scale:false,category:"symbols"},passport_control:{keywords:["custom","blue-square"],char:"🛂",fitzpatrick_scale:false,category:"symbols"},customs:{keywords:["passport","border","blue-square"],char:"🛃",fitzpatrick_scale:false,category:"symbols"},baggage_claim:{keywords:["blue-square","airport","transport"],char:"🛄",fitzpatrick_scale:false,category:"symbols"},left_luggage:{keywords:["blue-square","travel"],char:"🛅",fitzpatrick_scale:false,category:"symbols"},wheelchair:{keywords:["blue-square","disabled","a11y","accessibility"],char:"♿",fitzpatrick_scale:false,category:"symbols"},no_smoking:{keywords:["cigarette","blue-square","smell","smoke"],char:"🚭",fitzpatrick_scale:false,category:"symbols"},wc:{keywords:["toilet","restroom","blue-square"],char:"🚾",fitzpatrick_scale:false,category:"symbols"},parking:{keywords:["cars","blue-square","alphabet","letter"],char:"🅿️",fitzpatrick_scale:false,category:"symbols"},potable_water:{keywords:["blue-square","liquid","restroom","cleaning","faucet"],char:"🚰",fitzpatrick_scale:false,category:"symbols"},mens:{keywords:["toilet","restroom","wc","blue-square","gender","male"],char:"🚹",fitzpatrick_scale:false,category:"symbols"},womens:{keywords:["purple-square","woman","female","toilet","loo","restroom","gender"],char:"🚺",fitzpatrick_scale:false,category:"symbols"},baby_symbol:{keywords:["orange-square","child"],char:"🚼",fitzpatrick_scale:false,category:"symbols"},restroom:{keywords:["blue-square","toilet","refresh","wc","gender"],char:"🚻",fitzpatrick_scale:false,category:"symbols"},put_litter_in_its_place:{keywords:["blue-square","sign","human","info"],char:"🚮",fitzpatrick_scale:false,category:"symbols"},cinema:{keywords:["blue-square","record","film","movie","curtain","stage","theater"],char:"🎦",fitzpatrick_scale:false,category:"symbols"},signal_strength:{keywords:["blue-square","reception","phone","internet","connection","wifi","bluetooth","bars"],char:"📶",fitzpatrick_scale:false,category:"symbols"},koko:{keywords:["blue-square","here","katakana","japanese","destination"],char:"🈁",fitzpatrick_scale:false,category:"symbols"},ng:{keywords:["blue-square","words","shape","icon"],char:"🆖",fitzpatrick_scale:false,category:"symbols"},ok:{keywords:["good","agree","yes","blue-square"],char:"🆗",fitzpatrick_scale:false,category:"symbols"},up:{keywords:["blue-square","above","high"],char:"🆙",fitzpatrick_scale:false,category:"symbols"},cool:{keywords:["words","blue-square"],char:"🆒",fitzpatrick_scale:false,category:"symbols"},new:{keywords:["blue-square","words","start"],char:"🆕",fitzpatrick_scale:false,category:"symbols"},free:{keywords:["blue-square","words"],char:"🆓",fitzpatrick_scale:false,category:"symbols"},zero:{keywords:["0","numbers","blue-square","null"],char:"0️⃣",fitzpatrick_scale:false,category:"symbols"},one:{keywords:["blue-square","numbers","1"],char:"1️⃣",fitzpatrick_scale:false,category:"symbols"},two:{keywords:["numbers","2","prime","blue-square"],char:"2️⃣",fitzpatrick_scale:false,category:"symbols"},three:{keywords:["3","numbers","prime","blue-square"],char:"3️⃣",fitzpatrick_scale:false,category:"symbols"},four:{keywords:["4","numbers","blue-square"],char:"4️⃣",fitzpatrick_scale:false,category:"symbols"},five:{keywords:["5","numbers","blue-square","prime"],char:"5️⃣",fitzpatrick_scale:false,category:"symbols"},six:{keywords:["6","numbers","blue-square"],char:"6️⃣",fitzpatrick_scale:false,category:"symbols"},seven:{keywords:["7","numbers","blue-square","prime"],char:"7️⃣",fitzpatrick_scale:false,category:"symbols"},eight:{keywords:["8","blue-square","numbers"],char:"8️⃣",fitzpatrick_scale:false,category:"symbols"},nine:{keywords:["blue-square","numbers","9"],char:"9️⃣",fitzpatrick_scale:false,category:"symbols"},keycap_ten:{keywords:["numbers","10","blue-square"],char:"🔟",fitzpatrick_scale:false,category:"symbols"},asterisk:{keywords:["star","keycap"],char:"*⃣",fitzpatrick_scale:false,category:"symbols"},1234:{keywords:["numbers","blue-square"],char:"🔢",fitzpatrick_scale:false,category:"symbols"},eject_button:{keywords:["blue-square"],char:"⏏️",fitzpatrick_scale:false,category:"symbols"},arrow_forward:{keywords:["blue-square","right","direction","play"],char:"▶️",fitzpatrick_scale:false,category:"symbols"},pause_button:{keywords:["pause","blue-square"],char:"⏸",fitzpatrick_scale:false,category:"symbols"},next_track_button:{keywords:["forward","next","blue-square"],char:"⏭",fitzpatrick_scale:false,category:"symbols"},stop_button:{keywords:["blue-square"],char:"⏹",fitzpatrick_scale:false,category:"symbols"},record_button:{keywords:["blue-square"],char:"⏺",fitzpatrick_scale:false,category:"symbols"},play_or_pause_button:{keywords:["blue-square","play","pause"],char:"⏯",fitzpatrick_scale:false,category:"symbols"},previous_track_button:{keywords:["backward"],char:"⏮",fitzpatrick_scale:false,category:"symbols"},fast_forward:{keywords:["blue-square","play","speed","continue"],char:"⏩",fitzpatrick_scale:false,category:"symbols"},rewind:{keywords:["play","blue-square"],char:"⏪",fitzpatrick_scale:false,category:"symbols"},twisted_rightwards_arrows:{keywords:["blue-square","shuffle","music","random"],char:"🔀",fitzpatrick_scale:false,category:"symbols"},repeat:{keywords:["loop","record"],char:"🔁",fitzpatrick_scale:false,category:"symbols"},repeat_one:{keywords:["blue-square","loop"],char:"🔂",fitzpatrick_scale:false,category:"symbols"},arrow_backward:{keywords:["blue-square","left","direction"],char:"◀️",fitzpatrick_scale:false,category:"symbols"},arrow_up_small:{keywords:["blue-square","triangle","direction","point","forward","top"],char:"🔼",fitzpatrick_scale:false,category:"symbols"},arrow_down_small:{keywords:["blue-square","direction","bottom"],char:"🔽",fitzpatrick_scale:false,category:"symbols"},arrow_double_up:{keywords:["blue-square","direction","top"],char:"⏫",fitzpatrick_scale:false,category:"symbols"},arrow_double_down:{keywords:["blue-square","direction","bottom"],char:"⏬",fitzpatrick_scale:false,category:"symbols"},arrow_right:{keywords:["blue-square","next"],char:"➡️",fitzpatrick_scale:false,category:"symbols"},arrow_left:{keywords:["blue-square","previous","back"],char:"⬅️",fitzpatrick_scale:false,category:"symbols"},arrow_up:{keywords:["blue-square","continue","top","direction"],char:"⬆️",fitzpatrick_scale:false,category:"symbols"},arrow_down:{keywords:["blue-square","direction","bottom"],char:"⬇️",fitzpatrick_scale:false,category:"symbols"},arrow_upper_right:{keywords:["blue-square","point","direction","diagonal","northeast"],char:"↗️",fitzpatrick_scale:false,category:"symbols"},arrow_lower_right:{keywords:["blue-square","direction","diagonal","southeast"],char:"↘️",fitzpatrick_scale:false,category:"symbols"},arrow_lower_left:{keywords:["blue-square","direction","diagonal","southwest"],char:"↙️",fitzpatrick_scale:false,category:"symbols"},arrow_upper_left:{keywords:["blue-square","point","direction","diagonal","northwest"],char:"↖️",fitzpatrick_scale:false,category:"symbols"},arrow_up_down:{keywords:["blue-square","direction","way","vertical"],char:"↕️",fitzpatrick_scale:false,category:"symbols"},left_right_arrow:{keywords:["shape","direction","horizontal","sideways"],char:"↔️",fitzpatrick_scale:false,category:"symbols"},arrows_counterclockwise:{keywords:["blue-square","sync","cycle"],char:"🔄",fitzpatrick_scale:false,category:"symbols"},arrow_right_hook:{keywords:["blue-square","return","rotate","direction"],char:"↪️",fitzpatrick_scale:false,category:"symbols"},leftwards_arrow_with_hook:{keywords:["back","return","blue-square","undo","enter"],char:"↩️",fitzpatrick_scale:false,category:"symbols"},arrow_heading_up:{keywords:["blue-square","direction","top"],char:"⤴️",fitzpatrick_scale:false,category:"symbols"},arrow_heading_down:{keywords:["blue-square","direction","bottom"],char:"⤵️",fitzpatrick_scale:false,category:"symbols"},hash:{keywords:["symbol","blue-square","twitter"],char:"#️⃣",fitzpatrick_scale:false,category:"symbols"},information_source:{keywords:["blue-square","alphabet","letter"],char:"ℹ️",fitzpatrick_scale:false,category:"symbols"},abc:{keywords:["blue-square","alphabet"],char:"🔤",fitzpatrick_scale:false,category:"symbols"},abcd:{keywords:["blue-square","alphabet"],char:"🔡",fitzpatrick_scale:false,category:"symbols"},capital_abcd:{keywords:["alphabet","words","blue-square"],char:"🔠",fitzpatrick_scale:false,category:"symbols"},symbols:{keywords:["blue-square","music","note","ampersand","percent","glyphs","characters"],char:"🔣",fitzpatrick_scale:false,category:"symbols"},musical_note:{keywords:["score","tone","sound"],char:"🎵",fitzpatrick_scale:false,category:"symbols"},notes:{keywords:["music","score"],char:"🎶",fitzpatrick_scale:false,category:"symbols"},wavy_dash:{keywords:["draw","line","moustache","mustache","squiggle","scribble"],char:"〰️",fitzpatrick_scale:false,category:"symbols"},curly_loop:{keywords:["scribble","draw","shape","squiggle"],char:"➰",fitzpatrick_scale:false,category:"symbols"},heavy_check_mark:{keywords:["ok","nike","answer","yes","tick"],char:"✔️",fitzpatrick_scale:false,category:"symbols"},arrows_clockwise:{keywords:["sync","cycle","round","repeat"],char:"🔃",fitzpatrick_scale:false,category:"symbols"},heavy_plus_sign:{keywords:["math","calculation","addition","more","increase"],char:"➕",fitzpatrick_scale:false,category:"symbols"},heavy_minus_sign:{keywords:["math","calculation","subtract","less"],char:"➖",fitzpatrick_scale:false,category:"symbols"},heavy_division_sign:{keywords:["divide","math","calculation"],char:"➗",fitzpatrick_scale:false,category:"symbols"},heavy_multiplication_x:{keywords:["math","calculation"],char:"✖️",fitzpatrick_scale:false,category:"symbols"},infinity:{keywords:["forever"],char:"♾",fitzpatrick_scale:false,category:"symbols"},heavy_dollar_sign:{keywords:["money","sales","payment","currency","buck"],char:"💲",fitzpatrick_scale:false,category:"symbols"},currency_exchange:{keywords:["money","sales","dollar","travel"],char:"💱",fitzpatrick_scale:false,category:"symbols"},copyright:{keywords:["ip","license","circle","law","legal"],char:"©️",fitzpatrick_scale:false,category:"symbols"},registered:{keywords:["alphabet","circle"],char:"®️",fitzpatrick_scale:false,category:"symbols"},tm:{keywords:["trademark","brand","law","legal"],char:"™️",fitzpatrick_scale:false,category:"symbols"},end:{keywords:["words","arrow"],char:"🔚",fitzpatrick_scale:false,category:"symbols"},back:{keywords:["arrow","words","return"],char:"🔙",fitzpatrick_scale:false,category:"symbols"},on:{keywords:["arrow","words"],char:"🔛",fitzpatrick_scale:false,category:"symbols"},top:{keywords:["words","blue-square"],char:"🔝",fitzpatrick_scale:false,category:"symbols"},soon:{keywords:["arrow","words"],char:"🔜",fitzpatrick_scale:false,category:"symbols"},ballot_box_with_check:{keywords:["ok","agree","confirm","black-square","vote","election","yes","tick"],char:"☑️",fitzpatrick_scale:false,category:"symbols"},radio_button:{keywords:["input","old","music","circle"],char:"🔘",fitzpatrick_scale:false,category:"symbols"},white_circle:{keywords:["shape","round"],char:"⚪",fitzpatrick_scale:false,category:"symbols"},black_circle:{keywords:["shape","button","round"],char:"⚫",fitzpatrick_scale:false,category:"symbols"},red_circle:{keywords:["shape","error","danger"],char:"🔴",fitzpatrick_scale:false,category:"symbols"},large_blue_circle:{keywords:["shape","icon","button"],char:"🔵",fitzpatrick_scale:false,category:"symbols"},small_orange_diamond:{keywords:["shape","jewel","gem"],char:"🔸",fitzpatrick_scale:false,category:"symbols"},small_blue_diamond:{keywords:["shape","jewel","gem"],char:"🔹",fitzpatrick_scale:false,category:"symbols"},large_orange_diamond:{keywords:["shape","jewel","gem"],char:"🔶",fitzpatrick_scale:false,category:"symbols"},large_blue_diamond:{keywords:["shape","jewel","gem"],char:"🔷",fitzpatrick_scale:false,category:"symbols"},small_red_triangle:{keywords:["shape","direction","up","top"],char:"🔺",fitzpatrick_scale:false,category:"symbols"},black_small_square:{keywords:["shape","icon"],char:"▪️",fitzpatrick_scale:false,category:"symbols"},white_small_square:{keywords:["shape","icon"],char:"▫️",fitzpatrick_scale:false,category:"symbols"},black_large_square:{keywords:["shape","icon","button"],char:"⬛",fitzpatrick_scale:false,category:"symbols"},white_large_square:{keywords:["shape","icon","stone","button"],char:"⬜",fitzpatrick_scale:false,category:"symbols"},small_red_triangle_down:{keywords:["shape","direction","bottom"],char:"🔻",fitzpatrick_scale:false,category:"symbols"},black_medium_square:{keywords:["shape","button","icon"],char:"◼️",fitzpatrick_scale:false,category:"symbols"},white_medium_square:{keywords:["shape","stone","icon"],char:"◻️",fitzpatrick_scale:false,category:"symbols"},black_medium_small_square:{keywords:["icon","shape","button"],char:"◾",fitzpatrick_scale:false,category:"symbols"},white_medium_small_square:{keywords:["shape","stone","icon","button"],char:"◽",fitzpatrick_scale:false,category:"symbols"},black_square_button:{keywords:["shape","input","frame"],char:"🔲",fitzpatrick_scale:false,category:"symbols"},white_square_button:{keywords:["shape","input"],char:"🔳",fitzpatrick_scale:false,category:"symbols"},speaker:{keywords:["sound","volume","silence","broadcast"],char:"🔈",fitzpatrick_scale:false,category:"symbols"},sound:{keywords:["volume","speaker","broadcast"],char:"🔉",fitzpatrick_scale:false,category:"symbols"},loud_sound:{keywords:["volume","noise","noisy","speaker","broadcast"],char:"🔊",fitzpatrick_scale:false,category:"symbols"},mute:{keywords:["sound","volume","silence","quiet"],char:"🔇",fitzpatrick_scale:false,category:"symbols"},mega:{keywords:["sound","speaker","volume"],char:"📣",fitzpatrick_scale:false,category:"symbols"},loudspeaker:{keywords:["volume","sound"],char:"📢",fitzpatrick_scale:false,category:"symbols"},bell:{keywords:["sound","notification","christmas","xmas","chime"],char:"🔔",fitzpatrick_scale:false,category:"symbols"},no_bell:{keywords:["sound","volume","mute","quiet","silent"],char:"🔕",fitzpatrick_scale:false,category:"symbols"},black_joker:{keywords:["poker","cards","game","play","magic"],char:"🃏",fitzpatrick_scale:false,category:"symbols"},mahjong:{keywords:["game","play","chinese","kanji"],char:"🀄",fitzpatrick_scale:false,category:"symbols"},spades:{keywords:["poker","cards","suits","magic"],char:"♠️",fitzpatrick_scale:false,category:"symbols"},clubs:{keywords:["poker","cards","magic","suits"],char:"♣️",fitzpatrick_scale:false,category:"symbols"},hearts:{keywords:["poker","cards","magic","suits"],char:"♥️",fitzpatrick_scale:false,category:"symbols"},diamonds:{keywords:["poker","cards","magic","suits"],char:"♦️",fitzpatrick_scale:false,category:"symbols"},flower_playing_cards:{keywords:["game","sunset","red"],char:"🎴",fitzpatrick_scale:false,category:"symbols"},thought_balloon:{keywords:["bubble","cloud","speech","thinking","dream"],char:"💭",fitzpatrick_scale:false,category:"symbols"},right_anger_bubble:{keywords:["caption","speech","thinking","mad"],char:"🗯",fitzpatrick_scale:false,category:"symbols"},speech_balloon:{keywords:["bubble","words","message","talk","chatting"],char:"💬",fitzpatrick_scale:false,category:"symbols"},left_speech_bubble:{keywords:["words","message","talk","chatting"],char:"🗨",fitzpatrick_scale:false,category:"symbols"},clock1:{keywords:["time","late","early","schedule"],char:"🕐",fitzpatrick_scale:false,category:"symbols"},clock2:{keywords:["time","late","early","schedule"],char:"🕑",fitzpatrick_scale:false,category:"symbols"},clock3:{keywords:["time","late","early","schedule"],char:"🕒",fitzpatrick_scale:false,category:"symbols"},clock4:{keywords:["time","late","early","schedule"],char:"🕓",fitzpatrick_scale:false,category:"symbols"},clock5:{keywords:["time","late","early","schedule"],char:"🕔",fitzpatrick_scale:false,category:"symbols"},clock6:{keywords:["time","late","early","schedule","dawn","dusk"],char:"🕕",fitzpatrick_scale:false,category:"symbols"},clock7:{keywords:["time","late","early","schedule"],char:"🕖",fitzpatrick_scale:false,category:"symbols"},clock8:{keywords:["time","late","early","schedule"],char:"🕗",fitzpatrick_scale:false,category:"symbols"},clock9:{keywords:["time","late","early","schedule"],char:"🕘",fitzpatrick_scale:false,category:"symbols"},clock10:{keywords:["time","late","early","schedule"],char:"🕙",fitzpatrick_scale:false,category:"symbols"},clock11:{keywords:["time","late","early","schedule"],char:"🕚",fitzpatrick_scale:false,category:"symbols"},clock12:{keywords:["time","noon","midnight","midday","late","early","schedule"],char:"🕛",fitzpatrick_scale:false,category:"symbols"},clock130:{keywords:["time","late","early","schedule"],char:"🕜",fitzpatrick_scale:false,category:"symbols"},clock230:{keywords:["time","late","early","schedule"],char:"🕝",fitzpatrick_scale:false,category:"symbols"},clock330:{keywords:["time","late","early","schedule"],char:"🕞",fitzpatrick_scale:false,category:"symbols"},clock430:{keywords:["time","late","early","schedule"],char:"🕟",fitzpatrick_scale:false,category:"symbols"},clock530:{keywords:["time","late","early","schedule"],char:"🕠",fitzpatrick_scale:false,category:"symbols"},clock630:{keywords:["time","late","early","schedule"],char:"🕡",fitzpatrick_scale:false,category:"symbols"},clock730:{keywords:["time","late","early","schedule"],char:"🕢",fitzpatrick_scale:false,category:"symbols"},clock830:{keywords:["time","late","early","schedule"],char:"🕣",fitzpatrick_scale:false,category:"symbols"},clock930:{keywords:["time","late","early","schedule"],char:"🕤",fitzpatrick_scale:false,category:"symbols"},clock1030:{keywords:["time","late","early","schedule"],char:"🕥",fitzpatrick_scale:false,category:"symbols"},clock1130:{keywords:["time","late","early","schedule"],char:"🕦",fitzpatrick_scale:false,category:"symbols"},clock1230:{keywords:["time","late","early","schedule"],char:"🕧",fitzpatrick_scale:false,category:"symbols"},afghanistan:{keywords:["af","flag","nation","country","banner"],char:"🇦🇫",fitzpatrick_scale:false,category:"flags"},aland_islands:{keywords:["Åland","islands","flag","nation","country","banner"],char:"🇦🇽",fitzpatrick_scale:false,category:"flags"},albania:{keywords:["al","flag","nation","country","banner"],char:"🇦🇱",fitzpatrick_scale:false,category:"flags"},algeria:{keywords:["dz","flag","nation","country","banner"],char:"🇩🇿",fitzpatrick_scale:false,category:"flags"},american_samoa:{keywords:["american","ws","flag","nation","country","banner"],char:"🇦🇸",fitzpatrick_scale:false,category:"flags"},andorra:{keywords:["ad","flag","nation","country","banner"],char:"🇦🇩",fitzpatrick_scale:false,category:"flags"},angola:{keywords:["ao","flag","nation","country","banner"],char:"🇦🇴",fitzpatrick_scale:false,category:"flags"},anguilla:{keywords:["ai","flag","nation","country","banner"],char:"🇦🇮",fitzpatrick_scale:false,category:"flags"},antarctica:{keywords:["aq","flag","nation","country","banner"],char:"🇦🇶",fitzpatrick_scale:false,category:"flags"},antigua_barbuda:{keywords:["antigua","barbuda","flag","nation","country","banner"],char:"🇦🇬",fitzpatrick_scale:false,category:"flags"},argentina:{keywords:["ar","flag","nation","country","banner"],char:"🇦🇷",fitzpatrick_scale:false,category:"flags"},armenia:{keywords:["am","flag","nation","country","banner"],char:"🇦🇲",fitzpatrick_scale:false,category:"flags"},aruba:{keywords:["aw","flag","nation","country","banner"],char:"🇦🇼",fitzpatrick_scale:false,category:"flags"},australia:{keywords:["au","flag","nation","country","banner"],char:"🇦🇺",fitzpatrick_scale:false,category:"flags"},austria:{keywords:["at","flag","nation","country","banner"],char:"🇦🇹",fitzpatrick_scale:false,category:"flags"},azerbaijan:{keywords:["az","flag","nation","country","banner"],char:"🇦🇿",fitzpatrick_scale:false,category:"flags"},bahamas:{keywords:["bs","flag","nation","country","banner"],char:"🇧🇸",fitzpatrick_scale:false,category:"flags"},bahrain:{keywords:["bh","flag","nation","country","banner"],char:"🇧🇭",fitzpatrick_scale:false,category:"flags"},bangladesh:{keywords:["bd","flag","nation","country","banner"],char:"🇧🇩",fitzpatrick_scale:false,category:"flags"},barbados:{keywords:["bb","flag","nation","country","banner"],char:"🇧🇧",fitzpatrick_scale:false,category:"flags"},belarus:{keywords:["by","flag","nation","country","banner"],char:"🇧🇾",fitzpatrick_scale:false,category:"flags"},belgium:{keywords:["be","flag","nation","country","banner"],char:"🇧🇪",fitzpatrick_scale:false,category:"flags"},belize:{keywords:["bz","flag","nation","country","banner"],char:"🇧🇿",fitzpatrick_scale:false,category:"flags"},benin:{keywords:["bj","flag","nation","country","banner"],char:"🇧🇯",fitzpatrick_scale:false,category:"flags"},bermuda:{keywords:["bm","flag","nation","country","banner"],char:"🇧🇲",fitzpatrick_scale:false,category:"flags"},bhutan:{keywords:["bt","flag","nation","country","banner"],char:"🇧🇹",fitzpatrick_scale:false,category:"flags"},bolivia:{keywords:["bo","flag","nation","country","banner"],char:"🇧🇴",fitzpatrick_scale:false,category:"flags"},caribbean_netherlands:{keywords:["bonaire","flag","nation","country","banner"],char:"🇧🇶",fitzpatrick_scale:false,category:"flags"},bosnia_herzegovina:{keywords:["bosnia","herzegovina","flag","nation","country","banner"],char:"🇧🇦",fitzpatrick_scale:false,category:"flags"},botswana:{keywords:["bw","flag","nation","country","banner"],char:"🇧🇼",fitzpatrick_scale:false,category:"flags"},brazil:{keywords:["br","flag","nation","country","banner"],char:"🇧🇷",fitzpatrick_scale:false,category:"flags"},british_indian_ocean_territory:{keywords:["british","indian","ocean","territory","flag","nation","country","banner"],char:"🇮🇴",fitzpatrick_scale:false,category:"flags"},british_virgin_islands:{keywords:["british","virgin","islands","bvi","flag","nation","country","banner"],char:"🇻🇬",fitzpatrick_scale:false,category:"flags"},brunei:{keywords:["bn","darussalam","flag","nation","country","banner"],char:"🇧🇳",fitzpatrick_scale:false,category:"flags"},bulgaria:{keywords:["bg","flag","nation","country","banner"],char:"🇧🇬",fitzpatrick_scale:false,category:"flags"},burkina_faso:{keywords:["burkina","faso","flag","nation","country","banner"],char:"🇧🇫",fitzpatrick_scale:false,category:"flags"},burundi:{keywords:["bi","flag","nation","country","banner"],char:"🇧🇮",fitzpatrick_scale:false,category:"flags"},cape_verde:{keywords:["cabo","verde","flag","nation","country","banner"],char:"🇨🇻",fitzpatrick_scale:false,category:"flags"},cambodia:{keywords:["kh","flag","nation","country","banner"],char:"🇰🇭",fitzpatrick_scale:false,category:"flags"},cameroon:{keywords:["cm","flag","nation","country","banner"],char:"🇨🇲",fitzpatrick_scale:false,category:"flags"},canada:{keywords:["ca","flag","nation","country","banner"],char:"🇨🇦",fitzpatrick_scale:false,category:"flags"},canary_islands:{keywords:["canary","islands","flag","nation","country","banner"],char:"🇮🇨",fitzpatrick_scale:false,category:"flags"},cayman_islands:{keywords:["cayman","islands","flag","nation","country","banner"],char:"🇰🇾",fitzpatrick_scale:false,category:"flags"},central_african_republic:{keywords:["central","african","republic","flag","nation","country","banner"],char:"🇨🇫",fitzpatrick_scale:false,category:"flags"},chad:{keywords:["td","flag","nation","country","banner"],char:"🇹🇩",fitzpatrick_scale:false,category:"flags"},chile:{keywords:["flag","nation","country","banner"],char:"🇨🇱",fitzpatrick_scale:false,category:"flags"},cn:{keywords:["china","chinese","prc","flag","country","nation","banner"],char:"🇨🇳",fitzpatrick_scale:false,category:"flags"},christmas_island:{keywords:["christmas","island","flag","nation","country","banner"],char:"🇨🇽",fitzpatrick_scale:false,category:"flags"},cocos_islands:{keywords:["cocos","keeling","islands","flag","nation","country","banner"],char:"🇨🇨",fitzpatrick_scale:false,category:"flags"},colombia:{keywords:["co","flag","nation","country","banner"],char:"🇨🇴",fitzpatrick_scale:false,category:"flags"},comoros:{keywords:["km","flag","nation","country","banner"],char:"🇰🇲",fitzpatrick_scale:false,category:"flags"},congo_brazzaville:{keywords:["congo","flag","nation","country","banner"],char:"🇨🇬",fitzpatrick_scale:false,category:"flags"},congo_kinshasa:{keywords:["congo","democratic","republic","flag","nation","country","banner"],char:"🇨🇩",fitzpatrick_scale:false,category:"flags"},cook_islands:{keywords:["cook","islands","flag","nation","country","banner"],char:"🇨🇰",fitzpatrick_scale:false,category:"flags"},costa_rica:{keywords:["costa","rica","flag","nation","country","banner"],char:"🇨🇷",fitzpatrick_scale:false,category:"flags"},croatia:{keywords:["hr","flag","nation","country","banner"],char:"🇭🇷",fitzpatrick_scale:false,category:"flags"},cuba:{keywords:["cu","flag","nation","country","banner"],char:"🇨🇺",fitzpatrick_scale:false,category:"flags"},curacao:{keywords:["curaçao","flag","nation","country","banner"],char:"🇨🇼",fitzpatrick_scale:false,category:"flags"},cyprus:{keywords:["cy","flag","nation","country","banner"],char:"🇨🇾",fitzpatrick_scale:false,category:"flags"},czech_republic:{keywords:["cz","flag","nation","country","banner"],char:"🇨🇿",fitzpatrick_scale:false,category:"flags"},denmark:{keywords:["dk","flag","nation","country","banner"],char:"🇩🇰",fitzpatrick_scale:false,category:"flags"},djibouti:{keywords:["dj","flag","nation","country","banner"],char:"🇩🇯",fitzpatrick_scale:false,category:"flags"},dominica:{keywords:["dm","flag","nation","country","banner"],char:"🇩🇲",fitzpatrick_scale:false,category:"flags"},dominican_republic:{keywords:["dominican","republic","flag","nation","country","banner"],char:"🇩🇴",fitzpatrick_scale:false,category:"flags"},ecuador:{keywords:["ec","flag","nation","country","banner"],char:"🇪🇨",fitzpatrick_scale:false,category:"flags"},egypt:{keywords:["eg","flag","nation","country","banner"],char:"🇪🇬",fitzpatrick_scale:false,category:"flags"},el_salvador:{keywords:["el","salvador","flag","nation","country","banner"],char:"🇸🇻",fitzpatrick_scale:false,category:"flags"},equatorial_guinea:{keywords:["equatorial","gn","flag","nation","country","banner"],char:"🇬🇶",fitzpatrick_scale:false,category:"flags"},eritrea:{keywords:["er","flag","nation","country","banner"],char:"🇪🇷",fitzpatrick_scale:false,category:"flags"},estonia:{keywords:["ee","flag","nation","country","banner"],char:"🇪🇪",fitzpatrick_scale:false,category:"flags"},ethiopia:{keywords:["et","flag","nation","country","banner"],char:"🇪🇹",fitzpatrick_scale:false,category:"flags"},eu:{keywords:["european","union","flag","banner"],char:"🇪🇺",fitzpatrick_scale:false,category:"flags"},falkland_islands:{keywords:["falkland","islands","malvinas","flag","nation","country","banner"],char:"🇫🇰",fitzpatrick_scale:false,category:"flags"},faroe_islands:{keywords:["faroe","islands","flag","nation","country","banner"],char:"🇫🇴",fitzpatrick_scale:false,category:"flags"},fiji:{keywords:["fj","flag","nation","country","banner"],char:"🇫🇯",fitzpatrick_scale:false,category:"flags"},finland:{keywords:["fi","flag","nation","country","banner"],char:"🇫🇮",fitzpatrick_scale:false,category:"flags"},fr:{keywords:["banner","flag","nation","france","french","country"],char:"🇫🇷",fitzpatrick_scale:false,category:"flags"},french_guiana:{keywords:["french","guiana","flag","nation","country","banner"],char:"🇬🇫",fitzpatrick_scale:false,category:"flags"},french_polynesia:{keywords:["french","polynesia","flag","nation","country","banner"],char:"🇵🇫",fitzpatrick_scale:false,category:"flags"},french_southern_territories:{keywords:["french","southern","territories","flag","nation","country","banner"],char:"🇹🇫",fitzpatrick_scale:false,category:"flags"},gabon:{keywords:["ga","flag","nation","country","banner"],char:"🇬🇦",fitzpatrick_scale:false,category:"flags"},gambia:{keywords:["gm","flag","nation","country","banner"],char:"🇬🇲",fitzpatrick_scale:false,category:"flags"},georgia:{keywords:["ge","flag","nation","country","banner"],char:"🇬🇪",fitzpatrick_scale:false,category:"flags"},de:{keywords:["german","nation","flag","country","banner"],char:"🇩🇪",fitzpatrick_scale:false,category:"flags"},ghana:{keywords:["gh","flag","nation","country","banner"],char:"🇬🇭",fitzpatrick_scale:false,category:"flags"},gibraltar:{keywords:["gi","flag","nation","country","banner"],char:"🇬🇮",fitzpatrick_scale:false,category:"flags"},greece:{keywords:["gr","flag","nation","country","banner"],char:"🇬🇷",fitzpatrick_scale:false,category:"flags"},greenland:{keywords:["gl","flag","nation","country","banner"],char:"🇬🇱",fitzpatrick_scale:false,category:"flags"},grenada:{keywords:["gd","flag","nation","country","banner"],char:"🇬🇩",fitzpatrick_scale:false,category:"flags"},guadeloupe:{keywords:["gp","flag","nation","country","banner"],char:"🇬🇵",fitzpatrick_scale:false,category:"flags"},guam:{keywords:["gu","flag","nation","country","banner"],char:"🇬🇺",fitzpatrick_scale:false,category:"flags"},guatemala:{keywords:["gt","flag","nation","country","banner"],char:"🇬🇹",fitzpatrick_scale:false,category:"flags"},guernsey:{keywords:["gg","flag","nation","country","banner"],char:"🇬🇬",fitzpatrick_scale:false,category:"flags"},guinea:{keywords:["gn","flag","nation","country","banner"],char:"🇬🇳",fitzpatrick_scale:false,category:"flags"},guinea_bissau:{keywords:["gw","bissau","flag","nation","country","banner"],char:"🇬🇼",fitzpatrick_scale:false,category:"flags"},guyana:{keywords:["gy","flag","nation","country","banner"],char:"🇬🇾",fitzpatrick_scale:false,category:"flags"},haiti:{keywords:["ht","flag","nation","country","banner"],char:"🇭🇹",fitzpatrick_scale:false,category:"flags"},honduras:{keywords:["hn","flag","nation","country","banner"],char:"🇭🇳",fitzpatrick_scale:false,category:"flags"},hong_kong:{keywords:["hong","kong","flag","nation","country","banner"],char:"🇭🇰",fitzpatrick_scale:false,category:"flags"},hungary:{keywords:["hu","flag","nation","country","banner"],char:"🇭🇺",fitzpatrick_scale:false,category:"flags"},iceland:{keywords:["is","flag","nation","country","banner"],char:"🇮🇸",fitzpatrick_scale:false,category:"flags"},india:{keywords:["in","flag","nation","country","banner"],char:"🇮🇳",fitzpatrick_scale:false,category:"flags"},indonesia:{keywords:["flag","nation","country","banner"],char:"🇮🇩",fitzpatrick_scale:false,category:"flags"},iran:{keywords:["iran,","islamic","republic","flag","nation","country","banner"],char:"🇮🇷",fitzpatrick_scale:false,category:"flags"},iraq:{keywords:["iq","flag","nation","country","banner"],char:"🇮🇶",fitzpatrick_scale:false,category:"flags"},ireland:{keywords:["ie","flag","nation","country","banner"],char:"🇮🇪",fitzpatrick_scale:false,category:"flags"},isle_of_man:{keywords:["isle","man","flag","nation","country","banner"],char:"🇮🇲",fitzpatrick_scale:false,category:"flags"},israel:{keywords:["il","flag","nation","country","banner"],char:"🇮🇱",fitzpatrick_scale:false,category:"flags"},it:{keywords:["italy","flag","nation","country","banner"],char:"🇮🇹",fitzpatrick_scale:false,category:"flags"},cote_divoire:{keywords:["ivory","coast","flag","nation","country","banner"],char:"🇨🇮",fitzpatrick_scale:false,category:"flags"},jamaica:{keywords:["jm","flag","nation","country","banner"],char:"🇯🇲",fitzpatrick_scale:false,category:"flags"},jp:{keywords:["japanese","nation","flag","country","banner"],char:"🇯🇵",fitzpatrick_scale:false,category:"flags"},jersey:{keywords:["je","flag","nation","country","banner"],char:"🇯🇪",fitzpatrick_scale:false,category:"flags"},jordan:{keywords:["jo","flag","nation","country","banner"],char:"🇯🇴",fitzpatrick_scale:false,category:"flags"},kazakhstan:{keywords:["kz","flag","nation","country","banner"],char:"🇰🇿",fitzpatrick_scale:false,category:"flags"},kenya:{keywords:["ke","flag","nation","country","banner"],char:"🇰🇪",fitzpatrick_scale:false,category:"flags"},kiribati:{keywords:["ki","flag","nation","country","banner"],char:"🇰🇮",fitzpatrick_scale:false,category:"flags"},kosovo:{keywords:["xk","flag","nation","country","banner"],char:"🇽🇰",fitzpatrick_scale:false,category:"flags"},kuwait:{keywords:["kw","flag","nation","country","banner"],char:"🇰🇼",fitzpatrick_scale:false,category:"flags"},kyrgyzstan:{keywords:["kg","flag","nation","country","banner"],char:"🇰🇬",fitzpatrick_scale:false,category:"flags"},laos:{keywords:["lao","democratic","republic","flag","nation","country","banner"],char:"🇱🇦",fitzpatrick_scale:false,category:"flags"},latvia:{keywords:["lv","flag","nation","country","banner"],char:"🇱🇻",fitzpatrick_scale:false,category:"flags"},lebanon:{keywords:["lb","flag","nation","country","banner"],char:"🇱🇧",fitzpatrick_scale:false,category:"flags"},lesotho:{keywords:["ls","flag","nation","country","banner"],char:"🇱🇸",fitzpatrick_scale:false,category:"flags"},liberia:{keywords:["lr","flag","nation","country","banner"],char:"🇱🇷",fitzpatrick_scale:false,category:"flags"},libya:{keywords:["ly","flag","nation","country","banner"],char:"🇱🇾",fitzpatrick_scale:false,category:"flags"},liechtenstein:{keywords:["li","flag","nation","country","banner"],char:"🇱🇮",fitzpatrick_scale:false,category:"flags"},lithuania:{keywords:["lt","flag","nation","country","banner"],char:"🇱🇹",fitzpatrick_scale:false,category:"flags"},luxembourg:{keywords:["lu","flag","nation","country","banner"],char:"🇱🇺",fitzpatrick_scale:false,category:"flags"},macau:{keywords:["macao","flag","nation","country","banner"],char:"🇲🇴",fitzpatrick_scale:false,category:"flags"},macedonia:{keywords:["macedonia,","flag","nation","country","banner"],char:"🇲🇰",fitzpatrick_scale:false,category:"flags"},madagascar:{keywords:["mg","flag","nation","country","banner"],char:"🇲🇬",fitzpatrick_scale:false,category:"flags"},malawi:{keywords:["mw","flag","nation","country","banner"],char:"🇲🇼",fitzpatrick_scale:false,category:"flags"},malaysia:{keywords:["my","flag","nation","country","banner"],char:"🇲🇾",fitzpatrick_scale:false,category:"flags"},maldives:{keywords:["mv","flag","nation","country","banner"],char:"🇲🇻",fitzpatrick_scale:false,category:"flags"},mali:{keywords:["ml","flag","nation","country","banner"],char:"🇲🇱",fitzpatrick_scale:false,category:"flags"},malta:{keywords:["mt","flag","nation","country","banner"],char:"🇲🇹",fitzpatrick_scale:false,category:"flags"},marshall_islands:{keywords:["marshall","islands","flag","nation","country","banner"],char:"🇲🇭",fitzpatrick_scale:false,category:"flags"},martinique:{keywords:["mq","flag","nation","country","banner"],char:"🇲🇶",fitzpatrick_scale:false,category:"flags"},mauritania:{keywords:["mr","flag","nation","country","banner"],char:"🇲🇷",fitzpatrick_scale:false,category:"flags"},mauritius:{keywords:["mu","flag","nation","country","banner"],char:"🇲🇺",fitzpatrick_scale:false,category:"flags"},mayotte:{keywords:["yt","flag","nation","country","banner"],char:"🇾🇹",fitzpatrick_scale:false,category:"flags"},mexico:{keywords:["mx","flag","nation","country","banner"],char:"🇲🇽",fitzpatrick_scale:false,category:"flags"},micronesia:{keywords:["micronesia,","federated","states","flag","nation","country","banner"],char:"🇫🇲",fitzpatrick_scale:false,category:"flags"},moldova:{keywords:["moldova,","republic","flag","nation","country","banner"],char:"🇲🇩",fitzpatrick_scale:false,category:"flags"},monaco:{keywords:["mc","flag","nation","country","banner"],char:"🇲🇨",fitzpatrick_scale:false,category:"flags"},mongolia:{keywords:["mn","flag","nation","country","banner"],char:"🇲🇳",fitzpatrick_scale:false,category:"flags"},montenegro:{keywords:["me","flag","nation","country","banner"],char:"🇲🇪",fitzpatrick_scale:false,category:"flags"},montserrat:{keywords:["ms","flag","nation","country","banner"],char:"🇲🇸",fitzpatrick_scale:false,category:"flags"},morocco:{keywords:["ma","flag","nation","country","banner"],char:"🇲🇦",fitzpatrick_scale:false,category:"flags"},mozambique:{keywords:["mz","flag","nation","country","banner"],char:"🇲🇿",fitzpatrick_scale:false,category:"flags"},myanmar:{keywords:["mm","flag","nation","country","banner"],char:"🇲🇲",fitzpatrick_scale:false,category:"flags"},namibia:{keywords:["na","flag","nation","country","banner"],char:"🇳🇦",fitzpatrick_scale:false,category:"flags"},nauru:{keywords:["nr","flag","nation","country","banner"],char:"🇳🇷",fitzpatrick_scale:false,category:"flags"},nepal:{keywords:["np","flag","nation","country","banner"],char:"🇳🇵",fitzpatrick_scale:false,category:"flags"},netherlands:{keywords:["nl","flag","nation","country","banner"],char:"🇳🇱",fitzpatrick_scale:false,category:"flags"},new_caledonia:{keywords:["new","caledonia","flag","nation","country","banner"],char:"🇳🇨",fitzpatrick_scale:false,category:"flags"},new_zealand:{keywords:["new","zealand","flag","nation","country","banner"],char:"🇳🇿",fitzpatrick_scale:false,category:"flags"},nicaragua:{keywords:["ni","flag","nation","country","banner"],char:"🇳🇮",fitzpatrick_scale:false,category:"flags"},niger:{keywords:["ne","flag","nation","country","banner"],char:"🇳🇪",fitzpatrick_scale:false,category:"flags"},nigeria:{keywords:["flag","nation","country","banner"],char:"🇳🇬",fitzpatrick_scale:false,category:"flags"},niue:{keywords:["nu","flag","nation","country","banner"],char:"🇳🇺",fitzpatrick_scale:false,category:"flags"},norfolk_island:{keywords:["norfolk","island","flag","nation","country","banner"],char:"🇳🇫",fitzpatrick_scale:false,category:"flags"},northern_mariana_islands:{keywords:["northern","mariana","islands","flag","nation","country","banner"],char:"🇲🇵",fitzpatrick_scale:false,category:"flags"},north_korea:{keywords:["north","korea","nation","flag","country","banner"],char:"🇰🇵",fitzpatrick_scale:false,category:"flags"},norway:{keywords:["no","flag","nation","country","banner"],char:"🇳🇴",fitzpatrick_scale:false,category:"flags"},oman:{keywords:["om_symbol","flag","nation","country","banner"],char:"🇴🇲",fitzpatrick_scale:false,category:"flags"},pakistan:{keywords:["pk","flag","nation","country","banner"],char:"🇵🇰",fitzpatrick_scale:false,category:"flags"},palau:{keywords:["pw","flag","nation","country","banner"],char:"🇵🇼",fitzpatrick_scale:false,category:"flags"},palestinian_territories:{keywords:["palestine","palestinian","territories","flag","nation","country","banner"],char:"🇵🇸",fitzpatrick_scale:false,category:"flags"},panama:{keywords:["pa","flag","nation","country","banner"],char:"🇵🇦",fitzpatrick_scale:false,category:"flags"},papua_new_guinea:{keywords:["papua","new","guinea","flag","nation","country","banner"],char:"🇵🇬",fitzpatrick_scale:false,category:"flags"},paraguay:{keywords:["py","flag","nation","country","banner"],char:"🇵🇾",fitzpatrick_scale:false,category:"flags"},peru:{keywords:["pe","flag","nation","country","banner"],char:"🇵🇪",fitzpatrick_scale:false,category:"flags"},philippines:{keywords:["ph","flag","nation","country","banner"],char:"🇵🇭",fitzpatrick_scale:false,category:"flags"},pitcairn_islands:{keywords:["pitcairn","flag","nation","country","banner"],char:"🇵🇳",fitzpatrick_scale:false,category:"flags"},poland:{keywords:["pl","flag","nation","country","banner"],char:"🇵🇱",fitzpatrick_scale:false,category:"flags"},portugal:{keywords:["pt","flag","nation","country","banner"],char:"🇵🇹",fitzpatrick_scale:false,category:"flags"},puerto_rico:{keywords:["puerto","rico","flag","nation","country","banner"],char:"🇵🇷",fitzpatrick_scale:false,category:"flags"},qatar:{keywords:["qa","flag","nation","country","banner"],char:"🇶🇦",fitzpatrick_scale:false,category:"flags"},reunion:{keywords:["réunion","flag","nation","country","banner"],char:"🇷🇪",fitzpatrick_scale:false,category:"flags"},romania:{keywords:["ro","flag","nation","country","banner"],char:"🇷🇴",fitzpatrick_scale:false,category:"flags"},ru:{keywords:["russian","federation","flag","nation","country","banner"],char:"🇷🇺",fitzpatrick_scale:false,category:"flags"},rwanda:{keywords:["rw","flag","nation","country","banner"],char:"🇷🇼",fitzpatrick_scale:false,category:"flags"},st_barthelemy:{keywords:["saint","barthélemy","flag","nation","country","banner"],char:"🇧🇱",fitzpatrick_scale:false,category:"flags"},st_helena:{keywords:["saint","helena","ascension","tristan","cunha","flag","nation","country","banner"],char:"🇸🇭",fitzpatrick_scale:false,category:"flags"},st_kitts_nevis:{keywords:["saint","kitts","nevis","flag","nation","country","banner"],char:"🇰🇳",fitzpatrick_scale:false,category:"flags"},st_lucia:{keywords:["saint","lucia","flag","nation","country","banner"],char:"🇱🇨",fitzpatrick_scale:false,category:"flags"},st_pierre_miquelon:{keywords:["saint","pierre","miquelon","flag","nation","country","banner"],char:"🇵🇲",fitzpatrick_scale:false,category:"flags"},st_vincent_grenadines:{keywords:["saint","vincent","grenadines","flag","nation","country","banner"],char:"🇻🇨",fitzpatrick_scale:false,category:"flags"},samoa:{keywords:["ws","flag","nation","country","banner"],char:"🇼🇸",fitzpatrick_scale:false,category:"flags"},san_marino:{keywords:["san","marino","flag","nation","country","banner"],char:"🇸🇲",fitzpatrick_scale:false,category:"flags"},sao_tome_principe:{keywords:["sao","tome","principe","flag","nation","country","banner"],char:"🇸🇹",fitzpatrick_scale:false,category:"flags"},saudi_arabia:{keywords:["flag","nation","country","banner"],char:"🇸🇦",fitzpatrick_scale:false,category:"flags"},senegal:{keywords:["sn","flag","nation","country","banner"],char:"🇸🇳",fitzpatrick_scale:false,category:"flags"},serbia:{keywords:["rs","flag","nation","country","banner"],char:"🇷🇸",fitzpatrick_scale:false,category:"flags"},seychelles:{keywords:["sc","flag","nation","country","banner"],char:"🇸🇨",fitzpatrick_scale:false,category:"flags"},sierra_leone:{keywords:["sierra","leone","flag","nation","country","banner"],char:"🇸🇱",fitzpatrick_scale:false,category:"flags"},singapore:{keywords:["sg","flag","nation","country","banner"],char:"🇸🇬",fitzpatrick_scale:false,category:"flags"},sint_maarten:{keywords:["sint","maarten","dutch","flag","nation","country","banner"],char:"🇸🇽",fitzpatrick_scale:false,category:"flags"},slovakia:{keywords:["sk","flag","nation","country","banner"],char:"🇸🇰",fitzpatrick_scale:false,category:"flags"},slovenia:{keywords:["si","flag","nation","country","banner"],char:"🇸🇮",fitzpatrick_scale:false,category:"flags"},solomon_islands:{keywords:["solomon","islands","flag","nation","country","banner"],char:"🇸🇧",fitzpatrick_scale:false,category:"flags"},somalia:{keywords:["so","flag","nation","country","banner"],char:"🇸🇴",fitzpatrick_scale:false,category:"flags"},south_africa:{keywords:["south","africa","flag","nation","country","banner"],char:"🇿🇦",fitzpatrick_scale:false,category:"flags"},south_georgia_south_sandwich_islands:{keywords:["south","georgia","sandwich","islands","flag","nation","country","banner"],char:"🇬🇸",fitzpatrick_scale:false,category:"flags"},kr:{keywords:["south","korea","nation","flag","country","banner"],char:"🇰🇷",fitzpatrick_scale:false,category:"flags"},south_sudan:{keywords:["south","sd","flag","nation","country","banner"],char:"🇸🇸",fitzpatrick_scale:false,category:"flags"},es:{keywords:["spain","flag","nation","country","banner"],char:"🇪🇸",fitzpatrick_scale:false,category:"flags"},sri_lanka:{keywords:["sri","lanka","flag","nation","country","banner"],char:"🇱🇰",fitzpatrick_scale:false,category:"flags"},sudan:{keywords:["sd","flag","nation","country","banner"],char:"🇸🇩",fitzpatrick_scale:false,category:"flags"},suriname:{keywords:["sr","flag","nation","country","banner"],char:"🇸🇷",fitzpatrick_scale:false,category:"flags"},swaziland:{keywords:["sz","flag","nation","country","banner"],char:"🇸🇿",fitzpatrick_scale:false,category:"flags"},sweden:{keywords:["se","flag","nation","country","banner"],char:"🇸🇪",fitzpatrick_scale:false,category:"flags"},switzerland:{keywords:["ch","flag","nation","country","banner"],char:"🇨🇭",fitzpatrick_scale:false,category:"flags"},syria:{keywords:["syrian","arab","republic","flag","nation","country","banner"],char:"🇸🇾",fitzpatrick_scale:false,category:"flags"},taiwan:{keywords:["tw","flag","nation","country","banner"],char:"🇹🇼",fitzpatrick_scale:false,category:"flags"},tajikistan:{keywords:["tj","flag","nation","country","banner"],char:"🇹🇯",fitzpatrick_scale:false,category:"flags"},tanzania:{keywords:["tanzania,","united","republic","flag","nation","country","banner"],char:"🇹🇿",fitzpatrick_scale:false,category:"flags"},thailand:{keywords:["th","flag","nation","country","banner"],char:"🇹🇭",fitzpatrick_scale:false,category:"flags"},timor_leste:{keywords:["timor","leste","flag","nation","country","banner"],char:"🇹🇱",fitzpatrick_scale:false,category:"flags"},togo:{keywords:["tg","flag","nation","country","banner"],char:"🇹🇬",fitzpatrick_scale:false,category:"flags"},tokelau:{keywords:["tk","flag","nation","country","banner"],char:"🇹🇰",fitzpatrick_scale:false,category:"flags"},tonga:{keywords:["to","flag","nation","country","banner"],char:"🇹🇴",fitzpatrick_scale:false,category:"flags"},trinidad_tobago:{keywords:["trinidad","tobago","flag","nation","country","banner"],char:"🇹🇹",fitzpatrick_scale:false,category:"flags"},tunisia:{keywords:["tn","flag","nation","country","banner"],char:"🇹🇳",fitzpatrick_scale:false,category:"flags"},tr:{keywords:["turkey","flag","nation","country","banner"],char:"🇹🇷",fitzpatrick_scale:false,category:"flags"},turkmenistan:{keywords:["flag","nation","country","banner"],char:"🇹🇲",fitzpatrick_scale:false,category:"flags"},turks_caicos_islands:{keywords:["turks","caicos","islands","flag","nation","country","banner"],char:"🇹🇨",fitzpatrick_scale:false,category:"flags"},tuvalu:{keywords:["flag","nation","country","banner"],char:"🇹🇻",fitzpatrick_scale:false,category:"flags"},uganda:{keywords:["ug","flag","nation","country","banner"],char:"🇺🇬",fitzpatrick_scale:false,category:"flags"},ukraine:{keywords:["ua","flag","nation","country","banner"],char:"🇺🇦",fitzpatrick_scale:false,category:"flags"},united_arab_emirates:{keywords:["united","arab","emirates","flag","nation","country","banner"],char:"🇦🇪",fitzpatrick_scale:false,category:"flags"},uk:{keywords:["united","kingdom","great","britain","northern","ireland","flag","nation","country","banner","british","UK","english","england","union jack"],char:"🇬🇧",fitzpatrick_scale:false,category:"flags"},england:{keywords:["flag","english"],char:"🏴󠁧󠁢󠁥󠁮󠁧󠁿",fitzpatrick_scale:false,category:"flags"},scotland:{keywords:["flag","scottish"],char:"🏴󠁧󠁢󠁳󠁣󠁴󠁿",fitzpatrick_scale:false,category:"flags"},wales:{keywords:["flag","welsh"],char:"🏴󠁧󠁢󠁷󠁬󠁳󠁿",fitzpatrick_scale:false,category:"flags"},us:{keywords:["united","states","america","flag","nation","country","banner"],char:"🇺🇸",fitzpatrick_scale:false,category:"flags"},us_virgin_islands:{keywords:["virgin","islands","us","flag","nation","country","banner"],char:"🇻🇮",fitzpatrick_scale:false,category:"flags"},uruguay:{keywords:["uy","flag","nation","country","banner"],char:"🇺🇾",fitzpatrick_scale:false,category:"flags"},uzbekistan:{keywords:["uz","flag","nation","country","banner"],char:"🇺🇿",fitzpatrick_scale:false,category:"flags"},vanuatu:{keywords:["vu","flag","nation","country","banner"],char:"🇻🇺",fitzpatrick_scale:false,category:"flags"},vatican_city:{keywords:["vatican","city","flag","nation","country","banner"],char:"🇻🇦",fitzpatrick_scale:false,category:"flags"},venezuela:{keywords:["ve","bolivarian","republic","flag","nation","country","banner"],char:"🇻🇪",fitzpatrick_scale:false,category:"flags"},vietnam:{keywords:["viet","nam","flag","nation","country","banner"],char:"🇻🇳",fitzpatrick_scale:false,category:"flags"},wallis_futuna:{keywords:["wallis","futuna","flag","nation","country","banner"],char:"🇼🇫",fitzpatrick_scale:false,category:"flags"},western_sahara:{keywords:["western","sahara","flag","nation","country","banner"],char:"🇪🇭",fitzpatrick_scale:false,category:"flags"},yemen:{keywords:["ye","flag","nation","country","banner"],char:"🇾🇪",fitzpatrick_scale:false,category:"flags"},zambia:{keywords:["zm","flag","nation","country","banner"],char:"🇿🇲",fitzpatrick_scale:false,category:"flags"},zimbabwe:{keywords:["zw","flag","nation","country","banner"],char:"🇿🇼",fitzpatrick_scale:false,category:"flags"},united_nations:{keywords:["un","flag","banner"],char:"🇺🇳",fitzpatrick_scale:false,category:"flags"},pirate_flag:{keywords:["skull","crossbones","flag","banner"],char:"🏴‍☠️",fitzpatrick_scale:false,category:"flags"}}); \ No newline at end of file diff --git a/static/js/tinymce/plugins/emoticons/js/emojis.min.js b/static/js/tinymce/plugins/emoticons/js/emojis.min.js new file mode 100644 index 0000000..5a1c491 --- /dev/null +++ b/static/js/tinymce/plugins/emoticons/js/emojis.min.js @@ -0,0 +1,2 @@ +// Source: npm package: emojilib, file:emojis.json +window.tinymce.Resource.add("tinymce.plugins.emoticons",{grinning:{keywords:["face","smile","happy","joy",":D","grin"],char:"\u{1f600}",fitzpatrick_scale:!1,category:"people"},grimacing:{keywords:["face","grimace","teeth"],char:"\u{1f62c}",fitzpatrick_scale:!1,category:"people"},grin:{keywords:["face","happy","smile","joy","kawaii"],char:"\u{1f601}",fitzpatrick_scale:!1,category:"people"},joy:{keywords:["face","cry","tears","weep","happy","happytears","haha"],char:"\u{1f602}",fitzpatrick_scale:!1,category:"people"},rofl:{keywords:["face","rolling","floor","laughing","lol","haha"],char:"\u{1f923}",fitzpatrick_scale:!1,category:"people"},partying:{keywords:["face","celebration","woohoo"],char:"\u{1f973}",fitzpatrick_scale:!1,category:"people"},smiley:{keywords:["face","happy","joy","haha",":D",":)","smile","funny"],char:"\u{1f603}",fitzpatrick_scale:!1,category:"people"},smile:{keywords:["face","happy","joy","funny","haha","laugh","like",":D",":)"],char:"\u{1f604}",fitzpatrick_scale:!1,category:"people"},sweat_smile:{keywords:["face","hot","happy","laugh","sweat","smile","relief"],char:"\u{1f605}",fitzpatrick_scale:!1,category:"people"},laughing:{keywords:["happy","joy","lol","satisfied","haha","face","glad","XD","laugh"],char:"\u{1f606}",fitzpatrick_scale:!1,category:"people"},innocent:{keywords:["face","angel","heaven","halo"],char:"\u{1f607}",fitzpatrick_scale:!1,category:"people"},wink:{keywords:["face","happy","mischievous","secret",";)","smile","eye"],char:"\u{1f609}",fitzpatrick_scale:!1,category:"people"},blush:{keywords:["face","smile","happy","flushed","crush","embarrassed","shy","joy"],char:"\u{1f60a}",fitzpatrick_scale:!1,category:"people"},slightly_smiling_face:{keywords:["face","smile"],char:"\u{1f642}",fitzpatrick_scale:!1,category:"people"},upside_down_face:{keywords:["face","flipped","silly","smile"],char:"\u{1f643}",fitzpatrick_scale:!1,category:"people"},relaxed:{keywords:["face","blush","massage","happiness"],char:"\u263a\ufe0f",fitzpatrick_scale:!1,category:"people"},yum:{keywords:["happy","joy","tongue","smile","face","silly","yummy","nom","delicious","savouring"],char:"\u{1f60b}",fitzpatrick_scale:!1,category:"people"},relieved:{keywords:["face","relaxed","phew","massage","happiness"],char:"\u{1f60c}",fitzpatrick_scale:!1,category:"people"},heart_eyes:{keywords:["face","love","like","affection","valentines","infatuation","crush","heart"],char:"\u{1f60d}",fitzpatrick_scale:!1,category:"people"},smiling_face_with_three_hearts:{keywords:["face","love","like","affection","valentines","infatuation","crush","hearts","adore"],char:"\u{1f970}",fitzpatrick_scale:!1,category:"people"},kissing_heart:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:"\u{1f618}",fitzpatrick_scale:!1,category:"people"},kissing:{keywords:["love","like","face","3","valentines","infatuation","kiss"],char:"\u{1f617}",fitzpatrick_scale:!1,category:"people"},kissing_smiling_eyes:{keywords:["face","affection","valentines","infatuation","kiss"],char:"\u{1f619}",fitzpatrick_scale:!1,category:"people"},kissing_closed_eyes:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:"\u{1f61a}",fitzpatrick_scale:!1,category:"people"},stuck_out_tongue_winking_eye:{keywords:["face","prank","childish","playful","mischievous","smile","wink","tongue"],char:"\u{1f61c}",fitzpatrick_scale:!1,category:"people"},zany:{keywords:["face","goofy","crazy"],char:"\u{1f92a}",fitzpatrick_scale:!1,category:"people"},raised_eyebrow:{keywords:["face","distrust","scepticism","disapproval","disbelief","surprise"],char:"\u{1f928}",fitzpatrick_scale:!1,category:"people"},monocle:{keywords:["face","stuffy","wealthy"],char:"\u{1f9d0}",fitzpatrick_scale:!1,category:"people"},stuck_out_tongue_closed_eyes:{keywords:["face","prank","playful","mischievous","smile","tongue"],char:"\u{1f61d}",fitzpatrick_scale:!1,category:"people"},stuck_out_tongue:{keywords:["face","prank","childish","playful","mischievous","smile","tongue"],char:"\u{1f61b}",fitzpatrick_scale:!1,category:"people"},money_mouth_face:{keywords:["face","rich","dollar","money"],char:"\u{1f911}",fitzpatrick_scale:!1,category:"people"},nerd_face:{keywords:["face","nerdy","geek","dork"],char:"\u{1f913}",fitzpatrick_scale:!1,category:"people"},sunglasses:{keywords:["face","cool","smile","summer","beach","sunglass"],char:"\u{1f60e}",fitzpatrick_scale:!1,category:"people"},star_struck:{keywords:["face","smile","starry","eyes","grinning"],char:"\u{1f929}",fitzpatrick_scale:!1,category:"people"},clown_face:{keywords:["face"],char:"\u{1f921}",fitzpatrick_scale:!1,category:"people"},cowboy_hat_face:{keywords:["face","cowgirl","hat"],char:"\u{1f920}",fitzpatrick_scale:!1,category:"people"},hugs:{keywords:["face","smile","hug"],char:"\u{1f917}",fitzpatrick_scale:!1,category:"people"},smirk:{keywords:["face","smile","mean","prank","smug","sarcasm"],char:"\u{1f60f}",fitzpatrick_scale:!1,category:"people"},no_mouth:{keywords:["face","hellokitty"],char:"\u{1f636}",fitzpatrick_scale:!1,category:"people"},neutral_face:{keywords:["indifference","meh",":|","neutral"],char:"\u{1f610}",fitzpatrick_scale:!1,category:"people"},expressionless:{keywords:["face","indifferent","-_-","meh","deadpan"],char:"\u{1f611}",fitzpatrick_scale:!1,category:"people"},unamused:{keywords:["indifference","bored","straight face","serious","sarcasm","unimpressed","skeptical","dubious","side_eye"],char:"\u{1f612}",fitzpatrick_scale:!1,category:"people"},roll_eyes:{keywords:["face","eyeroll","frustrated"],char:"\u{1f644}",fitzpatrick_scale:!1,category:"people"},thinking:{keywords:["face","hmmm","think","consider"],char:"\u{1f914}",fitzpatrick_scale:!1,category:"people"},lying_face:{keywords:["face","lie","pinocchio"],char:"\u{1f925}",fitzpatrick_scale:!1,category:"people"},hand_over_mouth:{keywords:["face","whoops","shock","surprise"],char:"\u{1f92d}",fitzpatrick_scale:!1,category:"people"},shushing:{keywords:["face","quiet","shhh"],char:"\u{1f92b}",fitzpatrick_scale:!1,category:"people"},symbols_over_mouth:{keywords:["face","swearing","cursing","cussing","profanity","expletive"],char:"\u{1f92c}",fitzpatrick_scale:!1,category:"people"},exploding_head:{keywords:["face","shocked","mind","blown"],char:"\u{1f92f}",fitzpatrick_scale:!1,category:"people"},flushed:{keywords:["face","blush","shy","flattered"],char:"\u{1f633}",fitzpatrick_scale:!1,category:"people"},disappointed:{keywords:["face","sad","upset","depressed",":("],char:"\u{1f61e}",fitzpatrick_scale:!1,category:"people"},worried:{keywords:["face","concern","nervous",":("],char:"\u{1f61f}",fitzpatrick_scale:!1,category:"people"},angry:{keywords:["mad","face","annoyed","frustrated"],char:"\u{1f620}",fitzpatrick_scale:!1,category:"people"},rage:{keywords:["angry","mad","hate","despise"],char:"\u{1f621}",fitzpatrick_scale:!1,category:"people"},pensive:{keywords:["face","sad","depressed","upset"],char:"\u{1f614}",fitzpatrick_scale:!1,category:"people"},confused:{keywords:["face","indifference","huh","weird","hmmm",":/"],char:"\u{1f615}",fitzpatrick_scale:!1,category:"people"},slightly_frowning_face:{keywords:["face","frowning","disappointed","sad","upset"],char:"\u{1f641}",fitzpatrick_scale:!1,category:"people"},frowning_face:{keywords:["face","sad","upset","frown"],char:"\u2639",fitzpatrick_scale:!1,category:"people"},persevere:{keywords:["face","sick","no","upset","oops"],char:"\u{1f623}",fitzpatrick_scale:!1,category:"people"},confounded:{keywords:["face","confused","sick","unwell","oops",":S"],char:"\u{1f616}",fitzpatrick_scale:!1,category:"people"},tired_face:{keywords:["sick","whine","upset","frustrated"],char:"\u{1f62b}",fitzpatrick_scale:!1,category:"people"},weary:{keywords:["face","tired","sleepy","sad","frustrated","upset"],char:"\u{1f629}",fitzpatrick_scale:!1,category:"people"},pleading:{keywords:["face","begging","mercy"],char:"\u{1f97a}",fitzpatrick_scale:!1,category:"people"},triumph:{keywords:["face","gas","phew","proud","pride"],char:"\u{1f624}",fitzpatrick_scale:!1,category:"people"},open_mouth:{keywords:["face","surprise","impressed","wow","whoa",":O"],char:"\u{1f62e}",fitzpatrick_scale:!1,category:"people"},scream:{keywords:["face","munch","scared","omg"],char:"\u{1f631}",fitzpatrick_scale:!1,category:"people"},fearful:{keywords:["face","scared","terrified","nervous","oops","huh"],char:"\u{1f628}",fitzpatrick_scale:!1,category:"people"},cold_sweat:{keywords:["face","nervous","sweat"],char:"\u{1f630}",fitzpatrick_scale:!1,category:"people"},hushed:{keywords:["face","woo","shh"],char:"\u{1f62f}",fitzpatrick_scale:!1,category:"people"},frowning:{keywords:["face","aw","what"],char:"\u{1f626}",fitzpatrick_scale:!1,category:"people"},anguished:{keywords:["face","stunned","nervous"],char:"\u{1f627}",fitzpatrick_scale:!1,category:"people"},cry:{keywords:["face","tears","sad","depressed","upset",":'("],char:"\u{1f622}",fitzpatrick_scale:!1,category:"people"},disappointed_relieved:{keywords:["face","phew","sweat","nervous"],char:"\u{1f625}",fitzpatrick_scale:!1,category:"people"},drooling_face:{keywords:["face"],char:"\u{1f924}",fitzpatrick_scale:!1,category:"people"},sleepy:{keywords:["face","tired","rest","nap"],char:"\u{1f62a}",fitzpatrick_scale:!1,category:"people"},sweat:{keywords:["face","hot","sad","tired","exercise"],char:"\u{1f613}",fitzpatrick_scale:!1,category:"people"},hot:{keywords:["face","feverish","heat","red","sweating"],char:"\u{1f975}",fitzpatrick_scale:!1,category:"people"},cold:{keywords:["face","blue","freezing","frozen","frostbite","icicles"],char:"\u{1f976}",fitzpatrick_scale:!1,category:"people"},sob:{keywords:["face","cry","tears","sad","upset","depressed"],char:"\u{1f62d}",fitzpatrick_scale:!1,category:"people"},dizzy_face:{keywords:["spent","unconscious","xox","dizzy"],char:"\u{1f635}",fitzpatrick_scale:!1,category:"people"},astonished:{keywords:["face","xox","surprised","poisoned"],char:"\u{1f632}",fitzpatrick_scale:!1,category:"people"},zipper_mouth_face:{keywords:["face","sealed","zipper","secret"],char:"\u{1f910}",fitzpatrick_scale:!1,category:"people"},nauseated_face:{keywords:["face","vomit","gross","green","sick","throw up","ill"],char:"\u{1f922}",fitzpatrick_scale:!1,category:"people"},sneezing_face:{keywords:["face","gesundheit","sneeze","sick","allergy"],char:"\u{1f927}",fitzpatrick_scale:!1,category:"people"},vomiting:{keywords:["face","sick"],char:"\u{1f92e}",fitzpatrick_scale:!1,category:"people"},mask:{keywords:["face","sick","ill","disease"],char:"\u{1f637}",fitzpatrick_scale:!1,category:"people"},face_with_thermometer:{keywords:["sick","temperature","thermometer","cold","fever"],char:"\u{1f912}",fitzpatrick_scale:!1,category:"people"},face_with_head_bandage:{keywords:["injured","clumsy","bandage","hurt"],char:"\u{1f915}",fitzpatrick_scale:!1,category:"people"},woozy:{keywords:["face","dizzy","intoxicated","tipsy","wavy"],char:"\u{1f974}",fitzpatrick_scale:!1,category:"people"},sleeping:{keywords:["face","tired","sleepy","night","zzz"],char:"\u{1f634}",fitzpatrick_scale:!1,category:"people"},zzz:{keywords:["sleepy","tired","dream"],char:"\u{1f4a4}",fitzpatrick_scale:!1,category:"people"},poop:{keywords:["hankey","shitface","fail","turd","shit"],char:"\u{1f4a9}",fitzpatrick_scale:!1,category:"people"},smiling_imp:{keywords:["devil","horns"],char:"\u{1f608}",fitzpatrick_scale:!1,category:"people"},imp:{keywords:["devil","angry","horns"],char:"\u{1f47f}",fitzpatrick_scale:!1,category:"people"},japanese_ogre:{keywords:["monster","red","mask","halloween","scary","creepy","devil","demon","japanese","ogre"],char:"\u{1f479}",fitzpatrick_scale:!1,category:"people"},japanese_goblin:{keywords:["red","evil","mask","monster","scary","creepy","japanese","goblin"],char:"\u{1f47a}",fitzpatrick_scale:!1,category:"people"},skull:{keywords:["dead","skeleton","creepy","death"],char:"\u{1f480}",fitzpatrick_scale:!1,category:"people"},ghost:{keywords:["halloween","spooky","scary"],char:"\u{1f47b}",fitzpatrick_scale:!1,category:"people"},alien:{keywords:["UFO","paul","weird","outer_space"],char:"\u{1f47d}",fitzpatrick_scale:!1,category:"people"},robot:{keywords:["computer","machine","bot"],char:"\u{1f916}",fitzpatrick_scale:!1,category:"people"},smiley_cat:{keywords:["animal","cats","happy","smile"],char:"\u{1f63a}",fitzpatrick_scale:!1,category:"people"},smile_cat:{keywords:["animal","cats","smile"],char:"\u{1f638}",fitzpatrick_scale:!1,category:"people"},joy_cat:{keywords:["animal","cats","haha","happy","tears"],char:"\u{1f639}",fitzpatrick_scale:!1,category:"people"},heart_eyes_cat:{keywords:["animal","love","like","affection","cats","valentines","heart"],char:"\u{1f63b}",fitzpatrick_scale:!1,category:"people"},smirk_cat:{keywords:["animal","cats","smirk"],char:"\u{1f63c}",fitzpatrick_scale:!1,category:"people"},kissing_cat:{keywords:["animal","cats","kiss"],char:"\u{1f63d}",fitzpatrick_scale:!1,category:"people"},scream_cat:{keywords:["animal","cats","munch","scared","scream"],char:"\u{1f640}",fitzpatrick_scale:!1,category:"people"},crying_cat_face:{keywords:["animal","tears","weep","sad","cats","upset","cry"],char:"\u{1f63f}",fitzpatrick_scale:!1,category:"people"},pouting_cat:{keywords:["animal","cats"],char:"\u{1f63e}",fitzpatrick_scale:!1,category:"people"},palms_up:{keywords:["hands","gesture","cupped","prayer"],char:"\u{1f932}",fitzpatrick_scale:!0,category:"people"},raised_hands:{keywords:["gesture","hooray","yea","celebration","hands"],char:"\u{1f64c}",fitzpatrick_scale:!0,category:"people"},clap:{keywords:["hands","praise","applause","congrats","yay"],char:"\u{1f44f}",fitzpatrick_scale:!0,category:"people"},wave:{keywords:["hands","gesture","goodbye","solong","farewell","hello","hi","palm"],char:"\u{1f44b}",fitzpatrick_scale:!0,category:"people"},call_me_hand:{keywords:["hands","gesture"],char:"\u{1f919}",fitzpatrick_scale:!0,category:"people"},"+1":{keywords:["thumbsup","yes","awesome","good","agree","accept","cool","hand","like"],char:"\u{1f44d}",fitzpatrick_scale:!0,category:"people"},"-1":{keywords:["thumbsdown","no","dislike","hand"],char:"\u{1f44e}",fitzpatrick_scale:!0,category:"people"},facepunch:{keywords:["angry","violence","fist","hit","attack","hand"],char:"\u{1f44a}",fitzpatrick_scale:!0,category:"people"},fist:{keywords:["fingers","hand","grasp"],char:"\u270a",fitzpatrick_scale:!0,category:"people"},fist_left:{keywords:["hand","fistbump"],char:"\u{1f91b}",fitzpatrick_scale:!0,category:"people"},fist_right:{keywords:["hand","fistbump"],char:"\u{1f91c}",fitzpatrick_scale:!0,category:"people"},v:{keywords:["fingers","ohyeah","hand","peace","victory","two"],char:"\u270c",fitzpatrick_scale:!0,category:"people"},ok_hand:{keywords:["fingers","limbs","perfect","ok","okay"],char:"\u{1f44c}",fitzpatrick_scale:!0,category:"people"},raised_hand:{keywords:["fingers","stop","highfive","palm","ban"],char:"\u270b",fitzpatrick_scale:!0,category:"people"},raised_back_of_hand:{keywords:["fingers","raised","backhand"],char:"\u{1f91a}",fitzpatrick_scale:!0,category:"people"},open_hands:{keywords:["fingers","butterfly","hands","open"],char:"\u{1f450}",fitzpatrick_scale:!0,category:"people"},muscle:{keywords:["arm","flex","hand","summer","strong","biceps"],char:"\u{1f4aa}",fitzpatrick_scale:!0,category:"people"},pray:{keywords:["please","hope","wish","namaste","highfive"],char:"\u{1f64f}",fitzpatrick_scale:!0,category:"people"},foot:{keywords:["kick","stomp"],char:"\u{1f9b6}",fitzpatrick_scale:!0,category:"people"},leg:{keywords:["kick","limb"],char:"\u{1f9b5}",fitzpatrick_scale:!0,category:"people"},handshake:{keywords:["agreement","shake"],char:"\u{1f91d}",fitzpatrick_scale:!1,category:"people"},point_up:{keywords:["hand","fingers","direction","up"],char:"\u261d",fitzpatrick_scale:!0,category:"people"},point_up_2:{keywords:["fingers","hand","direction","up"],char:"\u{1f446}",fitzpatrick_scale:!0,category:"people"},point_down:{keywords:["fingers","hand","direction","down"],char:"\u{1f447}",fitzpatrick_scale:!0,category:"people"},point_left:{keywords:["direction","fingers","hand","left"],char:"\u{1f448}",fitzpatrick_scale:!0,category:"people"},point_right:{keywords:["fingers","hand","direction","right"],char:"\u{1f449}",fitzpatrick_scale:!0,category:"people"},fu:{keywords:["hand","fingers","rude","middle","flipping"],char:"\u{1f595}",fitzpatrick_scale:!0,category:"people"},raised_hand_with_fingers_splayed:{keywords:["hand","fingers","palm"],char:"\u{1f590}",fitzpatrick_scale:!0,category:"people"},love_you:{keywords:["hand","fingers","gesture"],char:"\u{1f91f}",fitzpatrick_scale:!0,category:"people"},metal:{keywords:["hand","fingers","evil_eye","sign_of_horns","rock_on"],char:"\u{1f918}",fitzpatrick_scale:!0,category:"people"},crossed_fingers:{keywords:["good","lucky"],char:"\u{1f91e}",fitzpatrick_scale:!0,category:"people"},vulcan_salute:{keywords:["hand","fingers","spock","star trek"],char:"\u{1f596}",fitzpatrick_scale:!0,category:"people"},writing_hand:{keywords:["lower_left_ballpoint_pen","stationery","write","compose"],char:"\u270d",fitzpatrick_scale:!0,category:"people"},selfie:{keywords:["camera","phone"],char:"\u{1f933}",fitzpatrick_scale:!0,category:"people"},nail_care:{keywords:["beauty","manicure","finger","fashion","nail"],char:"\u{1f485}",fitzpatrick_scale:!0,category:"people"},lips:{keywords:["mouth","kiss"],char:"\u{1f444}",fitzpatrick_scale:!1,category:"people"},tooth:{keywords:["teeth","dentist"],char:"\u{1f9b7}",fitzpatrick_scale:!1,category:"people"},tongue:{keywords:["mouth","playful"],char:"\u{1f445}",fitzpatrick_scale:!1,category:"people"},ear:{keywords:["face","hear","sound","listen"],char:"\u{1f442}",fitzpatrick_scale:!0,category:"people"},nose:{keywords:["smell","sniff"],char:"\u{1f443}",fitzpatrick_scale:!0,category:"people"},eye:{keywords:["face","look","see","watch","stare"],char:"\u{1f441}",fitzpatrick_scale:!1,category:"people"},eyes:{keywords:["look","watch","stalk","peek","see"],char:"\u{1f440}",fitzpatrick_scale:!1,category:"people"},brain:{keywords:["smart","intelligent"],char:"\u{1f9e0}",fitzpatrick_scale:!1,category:"people"},bust_in_silhouette:{keywords:["user","person","human"],char:"\u{1f464}",fitzpatrick_scale:!1,category:"people"},busts_in_silhouette:{keywords:["user","person","human","group","team"],char:"\u{1f465}",fitzpatrick_scale:!1,category:"people"},speaking_head:{keywords:["user","person","human","sing","say","talk"],char:"\u{1f5e3}",fitzpatrick_scale:!1,category:"people"},baby:{keywords:["child","boy","girl","toddler"],char:"\u{1f476}",fitzpatrick_scale:!0,category:"people"},child:{keywords:["gender-neutral","young"],char:"\u{1f9d2}",fitzpatrick_scale:!0,category:"people"},boy:{keywords:["man","male","guy","teenager"],char:"\u{1f466}",fitzpatrick_scale:!0,category:"people"},girl:{keywords:["female","woman","teenager"],char:"\u{1f467}",fitzpatrick_scale:!0,category:"people"},adult:{keywords:["gender-neutral","person"],char:"\u{1f9d1}",fitzpatrick_scale:!0,category:"people"},man:{keywords:["mustache","father","dad","guy","classy","sir","moustache"],char:"\u{1f468}",fitzpatrick_scale:!0,category:"people"},woman:{keywords:["female","girls","lady"],char:"\u{1f469}",fitzpatrick_scale:!0,category:"people"},blonde_woman:{keywords:["woman","female","girl","blonde","person"],char:"\u{1f471}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},blonde_man:{keywords:["man","male","boy","blonde","guy","person"],char:"\u{1f471}",fitzpatrick_scale:!0,category:"people"},bearded_person:{keywords:["person","bewhiskered"],char:"\u{1f9d4}",fitzpatrick_scale:!0,category:"people"},older_adult:{keywords:["human","elder","senior","gender-neutral"],char:"\u{1f9d3}",fitzpatrick_scale:!0,category:"people"},older_man:{keywords:["human","male","men","old","elder","senior"],char:"\u{1f474}",fitzpatrick_scale:!0,category:"people"},older_woman:{keywords:["human","female","women","lady","old","elder","senior"],char:"\u{1f475}",fitzpatrick_scale:!0,category:"people"},man_with_gua_pi_mao:{keywords:["male","boy","chinese"],char:"\u{1f472}",fitzpatrick_scale:!0,category:"people"},woman_with_headscarf:{keywords:["female","hijab","mantilla","tichel"],char:"\u{1f9d5}",fitzpatrick_scale:!0,category:"people"},woman_with_turban:{keywords:["female","indian","hinduism","arabs","woman"],char:"\u{1f473}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_with_turban:{keywords:["male","indian","hinduism","arabs"],char:"\u{1f473}",fitzpatrick_scale:!0,category:"people"},policewoman:{keywords:["woman","police","law","legal","enforcement","arrest","911","female"],char:"\u{1f46e}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},policeman:{keywords:["man","police","law","legal","enforcement","arrest","911"],char:"\u{1f46e}",fitzpatrick_scale:!0,category:"people"},construction_worker_woman:{keywords:["female","human","wip","build","construction","worker","labor","woman"],char:"\u{1f477}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},construction_worker_man:{keywords:["male","human","wip","guy","build","construction","worker","labor"],char:"\u{1f477}",fitzpatrick_scale:!0,category:"people"},guardswoman:{keywords:["uk","gb","british","female","royal","woman"],char:"\u{1f482}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},guardsman:{keywords:["uk","gb","british","male","guy","royal"],char:"\u{1f482}",fitzpatrick_scale:!0,category:"people"},female_detective:{keywords:["human","spy","detective","female","woman"],char:"\u{1f575}\ufe0f\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},male_detective:{keywords:["human","spy","detective"],char:"\u{1f575}",fitzpatrick_scale:!0,category:"people"},woman_health_worker:{keywords:["doctor","nurse","therapist","healthcare","woman","human"],char:"\u{1f469}\u200d\u2695\ufe0f",fitzpatrick_scale:!0,category:"people"},man_health_worker:{keywords:["doctor","nurse","therapist","healthcare","man","human"],char:"\u{1f468}\u200d\u2695\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_farmer:{keywords:["rancher","gardener","woman","human"],char:"\u{1f469}\u200d\u{1f33e}",fitzpatrick_scale:!0,category:"people"},man_farmer:{keywords:["rancher","gardener","man","human"],char:"\u{1f468}\u200d\u{1f33e}",fitzpatrick_scale:!0,category:"people"},woman_cook:{keywords:["chef","woman","human"],char:"\u{1f469}\u200d\u{1f373}",fitzpatrick_scale:!0,category:"people"},man_cook:{keywords:["chef","man","human"],char:"\u{1f468}\u200d\u{1f373}",fitzpatrick_scale:!0,category:"people"},woman_student:{keywords:["graduate","woman","human"],char:"\u{1f469}\u200d\u{1f393}",fitzpatrick_scale:!0,category:"people"},man_student:{keywords:["graduate","man","human"],char:"\u{1f468}\u200d\u{1f393}",fitzpatrick_scale:!0,category:"people"},woman_singer:{keywords:["rockstar","entertainer","woman","human"],char:"\u{1f469}\u200d\u{1f3a4}",fitzpatrick_scale:!0,category:"people"},man_singer:{keywords:["rockstar","entertainer","man","human"],char:"\u{1f468}\u200d\u{1f3a4}",fitzpatrick_scale:!0,category:"people"},woman_teacher:{keywords:["instructor","professor","woman","human"],char:"\u{1f469}\u200d\u{1f3eb}",fitzpatrick_scale:!0,category:"people"},man_teacher:{keywords:["instructor","professor","man","human"],char:"\u{1f468}\u200d\u{1f3eb}",fitzpatrick_scale:!0,category:"people"},woman_factory_worker:{keywords:["assembly","industrial","woman","human"],char:"\u{1f469}\u200d\u{1f3ed}",fitzpatrick_scale:!0,category:"people"},man_factory_worker:{keywords:["assembly","industrial","man","human"],char:"\u{1f468}\u200d\u{1f3ed}",fitzpatrick_scale:!0,category:"people"},woman_technologist:{keywords:["coder","developer","engineer","programmer","software","woman","human","laptop","computer"],char:"\u{1f469}\u200d\u{1f4bb}",fitzpatrick_scale:!0,category:"people"},man_technologist:{keywords:["coder","developer","engineer","programmer","software","man","human","laptop","computer"],char:"\u{1f468}\u200d\u{1f4bb}",fitzpatrick_scale:!0,category:"people"},woman_office_worker:{keywords:["business","manager","woman","human"],char:"\u{1f469}\u200d\u{1f4bc}",fitzpatrick_scale:!0,category:"people"},man_office_worker:{keywords:["business","manager","man","human"],char:"\u{1f468}\u200d\u{1f4bc}",fitzpatrick_scale:!0,category:"people"},woman_mechanic:{keywords:["plumber","woman","human","wrench"],char:"\u{1f469}\u200d\u{1f527}",fitzpatrick_scale:!0,category:"people"},man_mechanic:{keywords:["plumber","man","human","wrench"],char:"\u{1f468}\u200d\u{1f527}",fitzpatrick_scale:!0,category:"people"},woman_scientist:{keywords:["biologist","chemist","engineer","physicist","woman","human"],char:"\u{1f469}\u200d\u{1f52c}",fitzpatrick_scale:!0,category:"people"},man_scientist:{keywords:["biologist","chemist","engineer","physicist","man","human"],char:"\u{1f468}\u200d\u{1f52c}",fitzpatrick_scale:!0,category:"people"},woman_artist:{keywords:["painter","woman","human"],char:"\u{1f469}\u200d\u{1f3a8}",fitzpatrick_scale:!0,category:"people"},man_artist:{keywords:["painter","man","human"],char:"\u{1f468}\u200d\u{1f3a8}",fitzpatrick_scale:!0,category:"people"},woman_firefighter:{keywords:["fireman","woman","human"],char:"\u{1f469}\u200d\u{1f692}",fitzpatrick_scale:!0,category:"people"},man_firefighter:{keywords:["fireman","man","human"],char:"\u{1f468}\u200d\u{1f692}",fitzpatrick_scale:!0,category:"people"},woman_pilot:{keywords:["aviator","plane","woman","human"],char:"\u{1f469}\u200d\u2708\ufe0f",fitzpatrick_scale:!0,category:"people"},man_pilot:{keywords:["aviator","plane","man","human"],char:"\u{1f468}\u200d\u2708\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_astronaut:{keywords:["space","rocket","woman","human"],char:"\u{1f469}\u200d\u{1f680}",fitzpatrick_scale:!0,category:"people"},man_astronaut:{keywords:["space","rocket","man","human"],char:"\u{1f468}\u200d\u{1f680}",fitzpatrick_scale:!0,category:"people"},woman_judge:{keywords:["justice","court","woman","human"],char:"\u{1f469}\u200d\u2696\ufe0f",fitzpatrick_scale:!0,category:"people"},man_judge:{keywords:["justice","court","man","human"],char:"\u{1f468}\u200d\u2696\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_superhero:{keywords:["woman","female","good","heroine","superpowers"],char:"\u{1f9b8}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_superhero:{keywords:["man","male","good","hero","superpowers"],char:"\u{1f9b8}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_supervillain:{keywords:["woman","female","evil","bad","criminal","heroine","superpowers"],char:"\u{1f9b9}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_supervillain:{keywords:["man","male","evil","bad","criminal","hero","superpowers"],char:"\u{1f9b9}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},mrs_claus:{keywords:["woman","female","xmas","mother christmas"],char:"\u{1f936}",fitzpatrick_scale:!0,category:"people"},santa:{keywords:["festival","man","male","xmas","father christmas"],char:"\u{1f385}",fitzpatrick_scale:!0,category:"people"},sorceress:{keywords:["woman","female","mage","witch"],char:"\u{1f9d9}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},wizard:{keywords:["man","male","mage","sorcerer"],char:"\u{1f9d9}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_elf:{keywords:["woman","female"],char:"\u{1f9dd}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_elf:{keywords:["man","male"],char:"\u{1f9dd}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_vampire:{keywords:["woman","female"],char:"\u{1f9db}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_vampire:{keywords:["man","male","dracula"],char:"\u{1f9db}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_zombie:{keywords:["woman","female","undead","walking dead"],char:"\u{1f9df}\u200d\u2640\ufe0f",fitzpatrick_scale:!1,category:"people"},man_zombie:{keywords:["man","male","dracula","undead","walking dead"],char:"\u{1f9df}\u200d\u2642\ufe0f",fitzpatrick_scale:!1,category:"people"},woman_genie:{keywords:["woman","female"],char:"\u{1f9de}\u200d\u2640\ufe0f",fitzpatrick_scale:!1,category:"people"},man_genie:{keywords:["man","male"],char:"\u{1f9de}\u200d\u2642\ufe0f",fitzpatrick_scale:!1,category:"people"},mermaid:{keywords:["woman","female","merwoman","ariel"],char:"\u{1f9dc}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},merman:{keywords:["man","male","triton"],char:"\u{1f9dc}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_fairy:{keywords:["woman","female"],char:"\u{1f9da}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_fairy:{keywords:["man","male"],char:"\u{1f9da}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},angel:{keywords:["heaven","wings","halo"],char:"\u{1f47c}",fitzpatrick_scale:!0,category:"people"},pregnant_woman:{keywords:["baby"],char:"\u{1f930}",fitzpatrick_scale:!0,category:"people"},breastfeeding:{keywords:["nursing","baby"],char:"\u{1f931}",fitzpatrick_scale:!0,category:"people"},princess:{keywords:["girl","woman","female","blond","crown","royal","queen"],char:"\u{1f478}",fitzpatrick_scale:!0,category:"people"},prince:{keywords:["boy","man","male","crown","royal","king"],char:"\u{1f934}",fitzpatrick_scale:!0,category:"people"},bride_with_veil:{keywords:["couple","marriage","wedding","woman","bride"],char:"\u{1f470}",fitzpatrick_scale:!0,category:"people"},man_in_tuxedo:{keywords:["couple","marriage","wedding","groom"],char:"\u{1f935}",fitzpatrick_scale:!0,category:"people"},running_woman:{keywords:["woman","walking","exercise","race","running","female"],char:"\u{1f3c3}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},running_man:{keywords:["man","walking","exercise","race","running"],char:"\u{1f3c3}",fitzpatrick_scale:!0,category:"people"},walking_woman:{keywords:["human","feet","steps","woman","female"],char:"\u{1f6b6}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},walking_man:{keywords:["human","feet","steps"],char:"\u{1f6b6}",fitzpatrick_scale:!0,category:"people"},dancer:{keywords:["female","girl","woman","fun"],char:"\u{1f483}",fitzpatrick_scale:!0,category:"people"},man_dancing:{keywords:["male","boy","fun","dancer"],char:"\u{1f57a}",fitzpatrick_scale:!0,category:"people"},dancing_women:{keywords:["female","bunny","women","girls"],char:"\u{1f46f}",fitzpatrick_scale:!1,category:"people"},dancing_men:{keywords:["male","bunny","men","boys"],char:"\u{1f46f}\u200d\u2642\ufe0f",fitzpatrick_scale:!1,category:"people"},couple:{keywords:["pair","people","human","love","date","dating","like","affection","valentines","marriage"],char:"\u{1f46b}",fitzpatrick_scale:!1,category:"people"},two_men_holding_hands:{keywords:["pair","couple","love","like","bromance","friendship","people","human"],char:"\u{1f46c}",fitzpatrick_scale:!1,category:"people"},two_women_holding_hands:{keywords:["pair","friendship","couple","love","like","female","people","human"],char:"\u{1f46d}",fitzpatrick_scale:!1,category:"people"},bowing_woman:{keywords:["woman","female","girl"],char:"\u{1f647}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},bowing_man:{keywords:["man","male","boy"],char:"\u{1f647}",fitzpatrick_scale:!0,category:"people"},man_facepalming:{keywords:["man","male","boy","disbelief"],char:"\u{1f926}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_facepalming:{keywords:["woman","female","girl","disbelief"],char:"\u{1f926}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_shrugging:{keywords:["woman","female","girl","confused","indifferent","doubt"],char:"\u{1f937}",fitzpatrick_scale:!0,category:"people"},man_shrugging:{keywords:["man","male","boy","confused","indifferent","doubt"],char:"\u{1f937}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},tipping_hand_woman:{keywords:["female","girl","woman","human","information"],char:"\u{1f481}",fitzpatrick_scale:!0,category:"people"},tipping_hand_man:{keywords:["male","boy","man","human","information"],char:"\u{1f481}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},no_good_woman:{keywords:["female","girl","woman","nope"],char:"\u{1f645}",fitzpatrick_scale:!0,category:"people"},no_good_man:{keywords:["male","boy","man","nope"],char:"\u{1f645}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},ok_woman:{keywords:["women","girl","female","pink","human","woman"],char:"\u{1f646}",fitzpatrick_scale:!0,category:"people"},ok_man:{keywords:["men","boy","male","blue","human","man"],char:"\u{1f646}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},raising_hand_woman:{keywords:["female","girl","woman"],char:"\u{1f64b}",fitzpatrick_scale:!0,category:"people"},raising_hand_man:{keywords:["male","boy","man"],char:"\u{1f64b}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},pouting_woman:{keywords:["female","girl","woman"],char:"\u{1f64e}",fitzpatrick_scale:!0,category:"people"},pouting_man:{keywords:["male","boy","man"],char:"\u{1f64e}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},frowning_woman:{keywords:["female","girl","woman","sad","depressed","discouraged","unhappy"],char:"\u{1f64d}",fitzpatrick_scale:!0,category:"people"},frowning_man:{keywords:["male","boy","man","sad","depressed","discouraged","unhappy"],char:"\u{1f64d}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},haircut_woman:{keywords:["female","girl","woman"],char:"\u{1f487}",fitzpatrick_scale:!0,category:"people"},haircut_man:{keywords:["male","boy","man"],char:"\u{1f487}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},massage_woman:{keywords:["female","girl","woman","head"],char:"\u{1f486}",fitzpatrick_scale:!0,category:"people"},massage_man:{keywords:["male","boy","man","head"],char:"\u{1f486}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_in_steamy_room:{keywords:["female","woman","spa","steamroom","sauna"],char:"\u{1f9d6}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_in_steamy_room:{keywords:["male","man","spa","steamroom","sauna"],char:"\u{1f9d6}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},couple_with_heart_woman_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:"\u{1f491}",fitzpatrick_scale:!1,category:"people"},couple_with_heart_woman_woman:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:"\u{1f469}\u200d\u2764\ufe0f\u200d\u{1f469}",fitzpatrick_scale:!1,category:"people"},couple_with_heart_man_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:"\u{1f468}\u200d\u2764\ufe0f\u200d\u{1f468}",fitzpatrick_scale:!1,category:"people"},couplekiss_man_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:"\u{1f48f}",fitzpatrick_scale:!1,category:"people"},couplekiss_woman_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:"\u{1f469}\u200d\u2764\ufe0f\u200d\u{1f48b}\u200d\u{1f469}",fitzpatrick_scale:!1,category:"people"},couplekiss_man_man:{keywords:["pair","valentines","love","like","dating","marriage"],char:"\u{1f468}\u200d\u2764\ufe0f\u200d\u{1f48b}\u200d\u{1f468}",fitzpatrick_scale:!1,category:"people"},family_man_woman_boy:{keywords:["home","parents","child","mom","dad","father","mother","people","human"],char:"\u{1f46a}",fitzpatrick_scale:!1,category:"people"},family_man_woman_girl:{keywords:["home","parents","people","human","child"],char:"\u{1f468}\u200d\u{1f469}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},family_man_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:"\u{1f468}\u200d\u{1f469}\u200d\u{1f467}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_man_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:"\u{1f468}\u200d\u{1f469}\u200d\u{1f466}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_man_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:"\u{1f468}\u200d\u{1f469}\u200d\u{1f467}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},family_woman_woman_boy:{keywords:["home","parents","people","human","children"],char:"\u{1f469}\u200d\u{1f469}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl:{keywords:["home","parents","people","human","children"],char:"\u{1f469}\u200d\u{1f469}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:"\u{1f469}\u200d\u{1f469}\u200d\u{1f467}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_woman_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:"\u{1f469}\u200d\u{1f469}\u200d\u{1f466}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:"\u{1f469}\u200d\u{1f469}\u200d\u{1f467}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},family_man_man_boy:{keywords:["home","parents","people","human","children"],char:"\u{1f468}\u200d\u{1f468}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_man_man_girl:{keywords:["home","parents","people","human","children"],char:"\u{1f468}\u200d\u{1f468}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},family_man_man_girl_boy:{keywords:["home","parents","people","human","children"],char:"\u{1f468}\u200d\u{1f468}\u200d\u{1f467}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_man_man_boy_boy:{keywords:["home","parents","people","human","children"],char:"\u{1f468}\u200d\u{1f468}\u200d\u{1f466}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_man_man_girl_girl:{keywords:["home","parents","people","human","children"],char:"\u{1f468}\u200d\u{1f468}\u200d\u{1f467}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},family_woman_boy:{keywords:["home","parent","people","human","child"],char:"\u{1f469}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_woman_girl:{keywords:["home","parent","people","human","child"],char:"\u{1f469}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},family_woman_girl_boy:{keywords:["home","parent","people","human","children"],char:"\u{1f469}\u200d\u{1f467}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_woman_boy_boy:{keywords:["home","parent","people","human","children"],char:"\u{1f469}\u200d\u{1f466}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_woman_girl_girl:{keywords:["home","parent","people","human","children"],char:"\u{1f469}\u200d\u{1f467}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},family_man_boy:{keywords:["home","parent","people","human","child"],char:"\u{1f468}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_man_girl:{keywords:["home","parent","people","human","child"],char:"\u{1f468}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},family_man_girl_boy:{keywords:["home","parent","people","human","children"],char:"\u{1f468}\u200d\u{1f467}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_man_boy_boy:{keywords:["home","parent","people","human","children"],char:"\u{1f468}\u200d\u{1f466}\u200d\u{1f466}",fitzpatrick_scale:!1,category:"people"},family_man_girl_girl:{keywords:["home","parent","people","human","children"],char:"\u{1f468}\u200d\u{1f467}\u200d\u{1f467}",fitzpatrick_scale:!1,category:"people"},yarn:{keywords:["ball","crochet","knit"],char:"\u{1f9f6}",fitzpatrick_scale:!1,category:"people"},thread:{keywords:["needle","sewing","spool","string"],char:"\u{1f9f5}",fitzpatrick_scale:!1,category:"people"},coat:{keywords:["jacket"],char:"\u{1f9e5}",fitzpatrick_scale:!1,category:"people"},labcoat:{keywords:["doctor","experiment","scientist","chemist"],char:"\u{1f97c}",fitzpatrick_scale:!1,category:"people"},womans_clothes:{keywords:["fashion","shopping_bags","female"],char:"\u{1f45a}",fitzpatrick_scale:!1,category:"people"},tshirt:{keywords:["fashion","cloth","casual","shirt","tee"],char:"\u{1f455}",fitzpatrick_scale:!1,category:"people"},jeans:{keywords:["fashion","shopping"],char:"\u{1f456}",fitzpatrick_scale:!1,category:"people"},necktie:{keywords:["shirt","suitup","formal","fashion","cloth","business"],char:"\u{1f454}",fitzpatrick_scale:!1,category:"people"},dress:{keywords:["clothes","fashion","shopping"],char:"\u{1f457}",fitzpatrick_scale:!1,category:"people"},bikini:{keywords:["swimming","female","woman","girl","fashion","beach","summer"],char:"\u{1f459}",fitzpatrick_scale:!1,category:"people"},kimono:{keywords:["dress","fashion","women","female","japanese"],char:"\u{1f458}",fitzpatrick_scale:!1,category:"people"},lipstick:{keywords:["female","girl","fashion","woman"],char:"\u{1f484}",fitzpatrick_scale:!1,category:"people"},kiss:{keywords:["face","lips","love","like","affection","valentines"],char:"\u{1f48b}",fitzpatrick_scale:!1,category:"people"},footprints:{keywords:["feet","tracking","walking","beach"],char:"\u{1f463}",fitzpatrick_scale:!1,category:"people"},flat_shoe:{keywords:["ballet","slip-on","slipper"],char:"\u{1f97f}",fitzpatrick_scale:!1,category:"people"},high_heel:{keywords:["fashion","shoes","female","pumps","stiletto"],char:"\u{1f460}",fitzpatrick_scale:!1,category:"people"},sandal:{keywords:["shoes","fashion","flip flops"],char:"\u{1f461}",fitzpatrick_scale:!1,category:"people"},boot:{keywords:["shoes","fashion"],char:"\u{1f462}",fitzpatrick_scale:!1,category:"people"},mans_shoe:{keywords:["fashion","male"],char:"\u{1f45e}",fitzpatrick_scale:!1,category:"people"},athletic_shoe:{keywords:["shoes","sports","sneakers"],char:"\u{1f45f}",fitzpatrick_scale:!1,category:"people"},hiking_boot:{keywords:["backpacking","camping","hiking"],char:"\u{1f97e}",fitzpatrick_scale:!1,category:"people"},socks:{keywords:["stockings","clothes"],char:"\u{1f9e6}",fitzpatrick_scale:!1,category:"people"},gloves:{keywords:["hands","winter","clothes"],char:"\u{1f9e4}",fitzpatrick_scale:!1,category:"people"},scarf:{keywords:["neck","winter","clothes"],char:"\u{1f9e3}",fitzpatrick_scale:!1,category:"people"},womans_hat:{keywords:["fashion","accessories","female","lady","spring"],char:"\u{1f452}",fitzpatrick_scale:!1,category:"people"},tophat:{keywords:["magic","gentleman","classy","circus"],char:"\u{1f3a9}",fitzpatrick_scale:!1,category:"people"},billed_hat:{keywords:["cap","baseball"],char:"\u{1f9e2}",fitzpatrick_scale:!1,category:"people"},rescue_worker_helmet:{keywords:["construction","build"],char:"\u26d1",fitzpatrick_scale:!1,category:"people"},mortar_board:{keywords:["school","college","degree","university","graduation","cap","hat","legal","learn","education"],char:"\u{1f393}",fitzpatrick_scale:!1,category:"people"},crown:{keywords:["king","kod","leader","royalty","lord"],char:"\u{1f451}",fitzpatrick_scale:!1,category:"people"},school_satchel:{keywords:["student","education","bag","backpack"],char:"\u{1f392}",fitzpatrick_scale:!1,category:"people"},luggage:{keywords:["packing","travel"],char:"\u{1f9f3}",fitzpatrick_scale:!1,category:"people"},pouch:{keywords:["bag","accessories","shopping"],char:"\u{1f45d}",fitzpatrick_scale:!1,category:"people"},purse:{keywords:["fashion","accessories","money","sales","shopping"],char:"\u{1f45b}",fitzpatrick_scale:!1,category:"people"},handbag:{keywords:["fashion","accessory","accessories","shopping"],char:"\u{1f45c}",fitzpatrick_scale:!1,category:"people"},briefcase:{keywords:["business","documents","work","law","legal","job","career"],char:"\u{1f4bc}",fitzpatrick_scale:!1,category:"people"},eyeglasses:{keywords:["fashion","accessories","eyesight","nerdy","dork","geek"],char:"\u{1f453}",fitzpatrick_scale:!1,category:"people"},dark_sunglasses:{keywords:["face","cool","accessories"],char:"\u{1f576}",fitzpatrick_scale:!1,category:"people"},goggles:{keywords:["eyes","protection","safety"],char:"\u{1f97d}",fitzpatrick_scale:!1,category:"people"},ring:{keywords:["wedding","propose","marriage","valentines","diamond","fashion","jewelry","gem","engagement"],char:"\u{1f48d}",fitzpatrick_scale:!1,category:"people"},closed_umbrella:{keywords:["weather","rain","drizzle"],char:"\u{1f302}",fitzpatrick_scale:!1,category:"people"},dog:{keywords:["animal","friend","nature","woof","puppy","pet","faithful"],char:"\u{1f436}",fitzpatrick_scale:!1,category:"animals_and_nature"},cat:{keywords:["animal","meow","nature","pet","kitten"],char:"\u{1f431}",fitzpatrick_scale:!1,category:"animals_and_nature"},mouse:{keywords:["animal","nature","cheese_wedge","rodent"],char:"\u{1f42d}",fitzpatrick_scale:!1,category:"animals_and_nature"},hamster:{keywords:["animal","nature"],char:"\u{1f439}",fitzpatrick_scale:!1,category:"animals_and_nature"},rabbit:{keywords:["animal","nature","pet","spring","magic","bunny"],char:"\u{1f430}",fitzpatrick_scale:!1,category:"animals_and_nature"},fox_face:{keywords:["animal","nature","face"],char:"\u{1f98a}",fitzpatrick_scale:!1,category:"animals_and_nature"},bear:{keywords:["animal","nature","wild"],char:"\u{1f43b}",fitzpatrick_scale:!1,category:"animals_and_nature"},panda_face:{keywords:["animal","nature","panda"],char:"\u{1f43c}",fitzpatrick_scale:!1,category:"animals_and_nature"},koala:{keywords:["animal","nature"],char:"\u{1f428}",fitzpatrick_scale:!1,category:"animals_and_nature"},tiger:{keywords:["animal","cat","danger","wild","nature","roar"],char:"\u{1f42f}",fitzpatrick_scale:!1,category:"animals_and_nature"},lion:{keywords:["animal","nature"],char:"\u{1f981}",fitzpatrick_scale:!1,category:"animals_and_nature"},cow:{keywords:["beef","ox","animal","nature","moo","milk"],char:"\u{1f42e}",fitzpatrick_scale:!1,category:"animals_and_nature"},pig:{keywords:["animal","oink","nature"],char:"\u{1f437}",fitzpatrick_scale:!1,category:"animals_and_nature"},pig_nose:{keywords:["animal","oink"],char:"\u{1f43d}",fitzpatrick_scale:!1,category:"animals_and_nature"},frog:{keywords:["animal","nature","croak","toad"],char:"\u{1f438}",fitzpatrick_scale:!1,category:"animals_and_nature"},squid:{keywords:["animal","nature","ocean","sea"],char:"\u{1f991}",fitzpatrick_scale:!1,category:"animals_and_nature"},octopus:{keywords:["animal","creature","ocean","sea","nature","beach"],char:"\u{1f419}",fitzpatrick_scale:!1,category:"animals_and_nature"},shrimp:{keywords:["animal","ocean","nature","seafood"],char:"\u{1f990}",fitzpatrick_scale:!1,category:"animals_and_nature"},monkey_face:{keywords:["animal","nature","circus"],char:"\u{1f435}",fitzpatrick_scale:!1,category:"animals_and_nature"},gorilla:{keywords:["animal","nature","circus"],char:"\u{1f98d}",fitzpatrick_scale:!1,category:"animals_and_nature"},see_no_evil:{keywords:["monkey","animal","nature","haha"],char:"\u{1f648}",fitzpatrick_scale:!1,category:"animals_and_nature"},hear_no_evil:{keywords:["animal","monkey","nature"],char:"\u{1f649}",fitzpatrick_scale:!1,category:"animals_and_nature"},speak_no_evil:{keywords:["monkey","animal","nature","omg"],char:"\u{1f64a}",fitzpatrick_scale:!1,category:"animals_and_nature"},monkey:{keywords:["animal","nature","banana","circus"],char:"\u{1f412}",fitzpatrick_scale:!1,category:"animals_and_nature"},chicken:{keywords:["animal","cluck","nature","bird"],char:"\u{1f414}",fitzpatrick_scale:!1,category:"animals_and_nature"},penguin:{keywords:["animal","nature"],char:"\u{1f427}",fitzpatrick_scale:!1,category:"animals_and_nature"},bird:{keywords:["animal","nature","fly","tweet","spring"],char:"\u{1f426}",fitzpatrick_scale:!1,category:"animals_and_nature"},baby_chick:{keywords:["animal","chicken","bird"],char:"\u{1f424}",fitzpatrick_scale:!1,category:"animals_and_nature"},hatching_chick:{keywords:["animal","chicken","egg","born","baby","bird"],char:"\u{1f423}",fitzpatrick_scale:!1,category:"animals_and_nature"},hatched_chick:{keywords:["animal","chicken","baby","bird"],char:"\u{1f425}",fitzpatrick_scale:!1,category:"animals_and_nature"},duck:{keywords:["animal","nature","bird","mallard"],char:"\u{1f986}",fitzpatrick_scale:!1,category:"animals_and_nature"},eagle:{keywords:["animal","nature","bird"],char:"\u{1f985}",fitzpatrick_scale:!1,category:"animals_and_nature"},owl:{keywords:["animal","nature","bird","hoot"],char:"\u{1f989}",fitzpatrick_scale:!1,category:"animals_and_nature"},bat:{keywords:["animal","nature","blind","vampire"],char:"\u{1f987}",fitzpatrick_scale:!1,category:"animals_and_nature"},wolf:{keywords:["animal","nature","wild"],char:"\u{1f43a}",fitzpatrick_scale:!1,category:"animals_and_nature"},boar:{keywords:["animal","nature"],char:"\u{1f417}",fitzpatrick_scale:!1,category:"animals_and_nature"},horse:{keywords:["animal","brown","nature"],char:"\u{1f434}",fitzpatrick_scale:!1,category:"animals_and_nature"},unicorn:{keywords:["animal","nature","mystical"],char:"\u{1f984}",fitzpatrick_scale:!1,category:"animals_and_nature"},honeybee:{keywords:["animal","insect","nature","bug","spring","honey"],char:"\u{1f41d}",fitzpatrick_scale:!1,category:"animals_and_nature"},bug:{keywords:["animal","insect","nature","worm"],char:"\u{1f41b}",fitzpatrick_scale:!1,category:"animals_and_nature"},butterfly:{keywords:["animal","insect","nature","caterpillar"],char:"\u{1f98b}",fitzpatrick_scale:!1,category:"animals_and_nature"},snail:{keywords:["slow","animal","shell"],char:"\u{1f40c}",fitzpatrick_scale:!1,category:"animals_and_nature"},beetle:{keywords:["animal","insect","nature","ladybug"],char:"\u{1f41e}",fitzpatrick_scale:!1,category:"animals_and_nature"},ant:{keywords:["animal","insect","nature","bug"],char:"\u{1f41c}",fitzpatrick_scale:!1,category:"animals_and_nature"},grasshopper:{keywords:["animal","cricket","chirp"],char:"\u{1f997}",fitzpatrick_scale:!1,category:"animals_and_nature"},spider:{keywords:["animal","arachnid"],char:"\u{1f577}",fitzpatrick_scale:!1,category:"animals_and_nature"},scorpion:{keywords:["animal","arachnid"],char:"\u{1f982}",fitzpatrick_scale:!1,category:"animals_and_nature"},crab:{keywords:["animal","crustacean"],char:"\u{1f980}",fitzpatrick_scale:!1,category:"animals_and_nature"},snake:{keywords:["animal","evil","nature","hiss","python"],char:"\u{1f40d}",fitzpatrick_scale:!1,category:"animals_and_nature"},lizard:{keywords:["animal","nature","reptile"],char:"\u{1f98e}",fitzpatrick_scale:!1,category:"animals_and_nature"},"t-rex":{keywords:["animal","nature","dinosaur","tyrannosaurus","extinct"],char:"\u{1f996}",fitzpatrick_scale:!1,category:"animals_and_nature"},sauropod:{keywords:["animal","nature","dinosaur","brachiosaurus","brontosaurus","diplodocus","extinct"],char:"\u{1f995}",fitzpatrick_scale:!1,category:"animals_and_nature"},turtle:{keywords:["animal","slow","nature","tortoise"],char:"\u{1f422}",fitzpatrick_scale:!1,category:"animals_and_nature"},tropical_fish:{keywords:["animal","swim","ocean","beach","nemo"],char:"\u{1f420}",fitzpatrick_scale:!1,category:"animals_and_nature"},fish:{keywords:["animal","food","nature"],char:"\u{1f41f}",fitzpatrick_scale:!1,category:"animals_and_nature"},blowfish:{keywords:["animal","nature","food","sea","ocean"],char:"\u{1f421}",fitzpatrick_scale:!1,category:"animals_and_nature"},dolphin:{keywords:["animal","nature","fish","sea","ocean","flipper","fins","beach"],char:"\u{1f42c}",fitzpatrick_scale:!1,category:"animals_and_nature"},shark:{keywords:["animal","nature","fish","sea","ocean","jaws","fins","beach"],char:"\u{1f988}",fitzpatrick_scale:!1,category:"animals_and_nature"},whale:{keywords:["animal","nature","sea","ocean"],char:"\u{1f433}",fitzpatrick_scale:!1,category:"animals_and_nature"},whale2:{keywords:["animal","nature","sea","ocean"],char:"\u{1f40b}",fitzpatrick_scale:!1,category:"animals_and_nature"},crocodile:{keywords:["animal","nature","reptile","lizard","alligator"],char:"\u{1f40a}",fitzpatrick_scale:!1,category:"animals_and_nature"},leopard:{keywords:["animal","nature"],char:"\u{1f406}",fitzpatrick_scale:!1,category:"animals_and_nature"},zebra:{keywords:["animal","nature","stripes","safari"],char:"\u{1f993}",fitzpatrick_scale:!1,category:"animals_and_nature"},tiger2:{keywords:["animal","nature","roar"],char:"\u{1f405}",fitzpatrick_scale:!1,category:"animals_and_nature"},water_buffalo:{keywords:["animal","nature","ox","cow"],char:"\u{1f403}",fitzpatrick_scale:!1,category:"animals_and_nature"},ox:{keywords:["animal","cow","beef"],char:"\u{1f402}",fitzpatrick_scale:!1,category:"animals_and_nature"},cow2:{keywords:["beef","ox","animal","nature","moo","milk"],char:"\u{1f404}",fitzpatrick_scale:!1,category:"animals_and_nature"},deer:{keywords:["animal","nature","horns","venison"],char:"\u{1f98c}",fitzpatrick_scale:!1,category:"animals_and_nature"},dromedary_camel:{keywords:["animal","hot","desert","hump"],char:"\u{1f42a}",fitzpatrick_scale:!1,category:"animals_and_nature"},camel:{keywords:["animal","nature","hot","desert","hump"],char:"\u{1f42b}",fitzpatrick_scale:!1,category:"animals_and_nature"},giraffe:{keywords:["animal","nature","spots","safari"],char:"\u{1f992}",fitzpatrick_scale:!1,category:"animals_and_nature"},elephant:{keywords:["animal","nature","nose","th","circus"],char:"\u{1f418}",fitzpatrick_scale:!1,category:"animals_and_nature"},rhinoceros:{keywords:["animal","nature","horn"],char:"\u{1f98f}",fitzpatrick_scale:!1,category:"animals_and_nature"},goat:{keywords:["animal","nature"],char:"\u{1f410}",fitzpatrick_scale:!1,category:"animals_and_nature"},ram:{keywords:["animal","sheep","nature"],char:"\u{1f40f}",fitzpatrick_scale:!1,category:"animals_and_nature"},sheep:{keywords:["animal","nature","wool","shipit"],char:"\u{1f411}",fitzpatrick_scale:!1,category:"animals_and_nature"},racehorse:{keywords:["animal","gamble","luck"],char:"\u{1f40e}",fitzpatrick_scale:!1,category:"animals_and_nature"},pig2:{keywords:["animal","nature"],char:"\u{1f416}",fitzpatrick_scale:!1,category:"animals_and_nature"},rat:{keywords:["animal","mouse","rodent"],char:"\u{1f400}",fitzpatrick_scale:!1,category:"animals_and_nature"},mouse2:{keywords:["animal","nature","rodent"],char:"\u{1f401}",fitzpatrick_scale:!1,category:"animals_and_nature"},rooster:{keywords:["animal","nature","chicken"],char:"\u{1f413}",fitzpatrick_scale:!1,category:"animals_and_nature"},turkey:{keywords:["animal","bird"],char:"\u{1f983}",fitzpatrick_scale:!1,category:"animals_and_nature"},dove:{keywords:["animal","bird"],char:"\u{1f54a}",fitzpatrick_scale:!1,category:"animals_and_nature"},dog2:{keywords:["animal","nature","friend","doge","pet","faithful"],char:"\u{1f415}",fitzpatrick_scale:!1,category:"animals_and_nature"},poodle:{keywords:["dog","animal","101","nature","pet"],char:"\u{1f429}",fitzpatrick_scale:!1,category:"animals_and_nature"},cat2:{keywords:["animal","meow","pet","cats"],char:"\u{1f408}",fitzpatrick_scale:!1,category:"animals_and_nature"},rabbit2:{keywords:["animal","nature","pet","magic","spring"],char:"\u{1f407}",fitzpatrick_scale:!1,category:"animals_and_nature"},chipmunk:{keywords:["animal","nature","rodent","squirrel"],char:"\u{1f43f}",fitzpatrick_scale:!1,category:"animals_and_nature"},hedgehog:{keywords:["animal","nature","spiny"],char:"\u{1f994}",fitzpatrick_scale:!1,category:"animals_and_nature"},raccoon:{keywords:["animal","nature"],char:"\u{1f99d}",fitzpatrick_scale:!1,category:"animals_and_nature"},llama:{keywords:["animal","nature","alpaca"],char:"\u{1f999}",fitzpatrick_scale:!1,category:"animals_and_nature"},hippopotamus:{keywords:["animal","nature"],char:"\u{1f99b}",fitzpatrick_scale:!1,category:"animals_and_nature"},kangaroo:{keywords:["animal","nature","australia","joey","hop","marsupial"],char:"\u{1f998}",fitzpatrick_scale:!1,category:"animals_and_nature"},badger:{keywords:["animal","nature","honey"],char:"\u{1f9a1}",fitzpatrick_scale:!1,category:"animals_and_nature"},swan:{keywords:["animal","nature","bird"],char:"\u{1f9a2}",fitzpatrick_scale:!1,category:"animals_and_nature"},peacock:{keywords:["animal","nature","peahen","bird"],char:"\u{1f99a}",fitzpatrick_scale:!1,category:"animals_and_nature"},parrot:{keywords:["animal","nature","bird","pirate","talk"],char:"\u{1f99c}",fitzpatrick_scale:!1,category:"animals_and_nature"},lobster:{keywords:["animal","nature","bisque","claws","seafood"],char:"\u{1f99e}",fitzpatrick_scale:!1,category:"animals_and_nature"},mosquito:{keywords:["animal","nature","insect","malaria"],char:"\u{1f99f}",fitzpatrick_scale:!1,category:"animals_and_nature"},paw_prints:{keywords:["animal","tracking","footprints","dog","cat","pet","feet"],char:"\u{1f43e}",fitzpatrick_scale:!1,category:"animals_and_nature"},dragon:{keywords:["animal","myth","nature","chinese","green"],char:"\u{1f409}",fitzpatrick_scale:!1,category:"animals_and_nature"},dragon_face:{keywords:["animal","myth","nature","chinese","green"],char:"\u{1f432}",fitzpatrick_scale:!1,category:"animals_and_nature"},cactus:{keywords:["vegetable","plant","nature"],char:"\u{1f335}",fitzpatrick_scale:!1,category:"animals_and_nature"},christmas_tree:{keywords:["festival","vacation","december","xmas","celebration"],char:"\u{1f384}",fitzpatrick_scale:!1,category:"animals_and_nature"},evergreen_tree:{keywords:["plant","nature"],char:"\u{1f332}",fitzpatrick_scale:!1,category:"animals_and_nature"},deciduous_tree:{keywords:["plant","nature"],char:"\u{1f333}",fitzpatrick_scale:!1,category:"animals_and_nature"},palm_tree:{keywords:["plant","vegetable","nature","summer","beach","mojito","tropical"],char:"\u{1f334}",fitzpatrick_scale:!1,category:"animals_and_nature"},seedling:{keywords:["plant","nature","grass","lawn","spring"],char:"\u{1f331}",fitzpatrick_scale:!1,category:"animals_and_nature"},herb:{keywords:["vegetable","plant","medicine","weed","grass","lawn"],char:"\u{1f33f}",fitzpatrick_scale:!1,category:"animals_and_nature"},shamrock:{keywords:["vegetable","plant","nature","irish","clover"],char:"\u2618",fitzpatrick_scale:!1,category:"animals_and_nature"},four_leaf_clover:{keywords:["vegetable","plant","nature","lucky","irish"],char:"\u{1f340}",fitzpatrick_scale:!1,category:"animals_and_nature"},bamboo:{keywords:["plant","nature","vegetable","panda","pine_decoration"],char:"\u{1f38d}",fitzpatrick_scale:!1,category:"animals_and_nature"},tanabata_tree:{keywords:["plant","nature","branch","summer"],char:"\u{1f38b}",fitzpatrick_scale:!1,category:"animals_and_nature"},leaves:{keywords:["nature","plant","tree","vegetable","grass","lawn","spring"],char:"\u{1f343}",fitzpatrick_scale:!1,category:"animals_and_nature"},fallen_leaf:{keywords:["nature","plant","vegetable","leaves"],char:"\u{1f342}",fitzpatrick_scale:!1,category:"animals_and_nature"},maple_leaf:{keywords:["nature","plant","vegetable","ca","fall"],char:"\u{1f341}",fitzpatrick_scale:!1,category:"animals_and_nature"},ear_of_rice:{keywords:["nature","plant"],char:"\u{1f33e}",fitzpatrick_scale:!1,category:"animals_and_nature"},hibiscus:{keywords:["plant","vegetable","flowers","beach"],char:"\u{1f33a}",fitzpatrick_scale:!1,category:"animals_and_nature"},sunflower:{keywords:["nature","plant","fall"],char:"\u{1f33b}",fitzpatrick_scale:!1,category:"animals_and_nature"},rose:{keywords:["flowers","valentines","love","spring"],char:"\u{1f339}",fitzpatrick_scale:!1,category:"animals_and_nature"},wilted_flower:{keywords:["plant","nature","flower"],char:"\u{1f940}",fitzpatrick_scale:!1,category:"animals_and_nature"},tulip:{keywords:["flowers","plant","nature","summer","spring"],char:"\u{1f337}",fitzpatrick_scale:!1,category:"animals_and_nature"},blossom:{keywords:["nature","flowers","yellow"],char:"\u{1f33c}",fitzpatrick_scale:!1,category:"animals_and_nature"},cherry_blossom:{keywords:["nature","plant","spring","flower"],char:"\u{1f338}",fitzpatrick_scale:!1,category:"animals_and_nature"},bouquet:{keywords:["flowers","nature","spring"],char:"\u{1f490}",fitzpatrick_scale:!1,category:"animals_and_nature"},mushroom:{keywords:["plant","vegetable"],char:"\u{1f344}",fitzpatrick_scale:!1,category:"animals_and_nature"},chestnut:{keywords:["food","squirrel"],char:"\u{1f330}",fitzpatrick_scale:!1,category:"animals_and_nature"},jack_o_lantern:{keywords:["halloween","light","pumpkin","creepy","fall"],char:"\u{1f383}",fitzpatrick_scale:!1,category:"animals_and_nature"},shell:{keywords:["nature","sea","beach"],char:"\u{1f41a}",fitzpatrick_scale:!1,category:"animals_and_nature"},spider_web:{keywords:["animal","insect","arachnid","silk"],char:"\u{1f578}",fitzpatrick_scale:!1,category:"animals_and_nature"},earth_americas:{keywords:["globe","world","USA","international"],char:"\u{1f30e}",fitzpatrick_scale:!1,category:"animals_and_nature"},earth_africa:{keywords:["globe","world","international"],char:"\u{1f30d}",fitzpatrick_scale:!1,category:"animals_and_nature"},earth_asia:{keywords:["globe","world","east","international"],char:"\u{1f30f}",fitzpatrick_scale:!1,category:"animals_and_nature"},full_moon:{keywords:["nature","yellow","twilight","planet","space","night","evening","sleep"],char:"\u{1f315}",fitzpatrick_scale:!1,category:"animals_and_nature"},waning_gibbous_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep","waxing_gibbous_moon"],char:"\u{1f316}",fitzpatrick_scale:!1,category:"animals_and_nature"},last_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\u{1f317}",fitzpatrick_scale:!1,category:"animals_and_nature"},waning_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\u{1f318}",fitzpatrick_scale:!1,category:"animals_and_nature"},new_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\u{1f311}",fitzpatrick_scale:!1,category:"animals_and_nature"},waxing_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\u{1f312}",fitzpatrick_scale:!1,category:"animals_and_nature"},first_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\u{1f313}",fitzpatrick_scale:!1,category:"animals_and_nature"},waxing_gibbous_moon:{keywords:["nature","night","sky","gray","twilight","planet","space","evening","sleep"],char:"\u{1f314}",fitzpatrick_scale:!1,category:"animals_and_nature"},new_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\u{1f31a}",fitzpatrick_scale:!1,category:"animals_and_nature"},full_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\u{1f31d}",fitzpatrick_scale:!1,category:"animals_and_nature"},first_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\u{1f31b}",fitzpatrick_scale:!1,category:"animals_and_nature"},last_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\u{1f31c}",fitzpatrick_scale:!1,category:"animals_and_nature"},sun_with_face:{keywords:["nature","morning","sky"],char:"\u{1f31e}",fitzpatrick_scale:!1,category:"animals_and_nature"},crescent_moon:{keywords:["night","sleep","sky","evening","magic"],char:"\u{1f319}",fitzpatrick_scale:!1,category:"animals_and_nature"},star:{keywords:["night","yellow"],char:"\u2b50",fitzpatrick_scale:!1,category:"animals_and_nature"},star2:{keywords:["night","sparkle","awesome","good","magic"],char:"\u{1f31f}",fitzpatrick_scale:!1,category:"animals_and_nature"},dizzy:{keywords:["star","sparkle","shoot","magic"],char:"\u{1f4ab}",fitzpatrick_scale:!1,category:"animals_and_nature"},sparkles:{keywords:["stars","shine","shiny","cool","awesome","good","magic"],char:"\u2728",fitzpatrick_scale:!1,category:"animals_and_nature"},comet:{keywords:["space"],char:"\u2604",fitzpatrick_scale:!1,category:"animals_and_nature"},sunny:{keywords:["weather","nature","brightness","summer","beach","spring"],char:"\u2600\ufe0f",fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_small_cloud:{keywords:["weather"],char:"\u{1f324}",fitzpatrick_scale:!1,category:"animals_and_nature"},partly_sunny:{keywords:["weather","nature","cloudy","morning","fall","spring"],char:"\u26c5",fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_large_cloud:{keywords:["weather"],char:"\u{1f325}",fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_rain_cloud:{keywords:["weather"],char:"\u{1f326}",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud:{keywords:["weather","sky"],char:"\u2601\ufe0f",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_rain:{keywords:["weather"],char:"\u{1f327}",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_lightning_and_rain:{keywords:["weather","lightning"],char:"\u26c8",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_lightning:{keywords:["weather","thunder"],char:"\u{1f329}",fitzpatrick_scale:!1,category:"animals_and_nature"},zap:{keywords:["thunder","weather","lightning bolt","fast"],char:"\u26a1",fitzpatrick_scale:!1,category:"animals_and_nature"},fire:{keywords:["hot","cook","flame"],char:"\u{1f525}",fitzpatrick_scale:!1,category:"animals_and_nature"},boom:{keywords:["bomb","explode","explosion","collision","blown"],char:"\u{1f4a5}",fitzpatrick_scale:!1,category:"animals_and_nature"},snowflake:{keywords:["winter","season","cold","weather","christmas","xmas"],char:"\u2744\ufe0f",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_snow:{keywords:["weather"],char:"\u{1f328}",fitzpatrick_scale:!1,category:"animals_and_nature"},snowman:{keywords:["winter","season","cold","weather","christmas","xmas","frozen","without_snow"],char:"\u26c4",fitzpatrick_scale:!1,category:"animals_and_nature"},snowman_with_snow:{keywords:["winter","season","cold","weather","christmas","xmas","frozen"],char:"\u2603",fitzpatrick_scale:!1,category:"animals_and_nature"},wind_face:{keywords:["gust","air"],char:"\u{1f32c}",fitzpatrick_scale:!1,category:"animals_and_nature"},dash:{keywords:["wind","air","fast","shoo","fart","smoke","puff"],char:"\u{1f4a8}",fitzpatrick_scale:!1,category:"animals_and_nature"},tornado:{keywords:["weather","cyclone","twister"],char:"\u{1f32a}",fitzpatrick_scale:!1,category:"animals_and_nature"},fog:{keywords:["weather"],char:"\u{1f32b}",fitzpatrick_scale:!1,category:"animals_and_nature"},open_umbrella:{keywords:["weather","spring"],char:"\u2602",fitzpatrick_scale:!1,category:"animals_and_nature"},umbrella:{keywords:["rainy","weather","spring"],char:"\u2614",fitzpatrick_scale:!1,category:"animals_and_nature"},droplet:{keywords:["water","drip","faucet","spring"],char:"\u{1f4a7}",fitzpatrick_scale:!1,category:"animals_and_nature"},sweat_drops:{keywords:["water","drip","oops"],char:"\u{1f4a6}",fitzpatrick_scale:!1,category:"animals_and_nature"},ocean:{keywords:["sea","water","wave","nature","tsunami","disaster"],char:"\u{1f30a}",fitzpatrick_scale:!1,category:"animals_and_nature"},green_apple:{keywords:["fruit","nature"],char:"\u{1f34f}",fitzpatrick_scale:!1,category:"food_and_drink"},apple:{keywords:["fruit","mac","school"],char:"\u{1f34e}",fitzpatrick_scale:!1,category:"food_and_drink"},pear:{keywords:["fruit","nature","food"],char:"\u{1f350}",fitzpatrick_scale:!1,category:"food_and_drink"},tangerine:{keywords:["food","fruit","nature","orange"],char:"\u{1f34a}",fitzpatrick_scale:!1,category:"food_and_drink"},lemon:{keywords:["fruit","nature"],char:"\u{1f34b}",fitzpatrick_scale:!1,category:"food_and_drink"},banana:{keywords:["fruit","food","monkey"],char:"\u{1f34c}",fitzpatrick_scale:!1,category:"food_and_drink"},watermelon:{keywords:["fruit","food","picnic","summer"],char:"\u{1f349}",fitzpatrick_scale:!1,category:"food_and_drink"},grapes:{keywords:["fruit","food","wine"],char:"\u{1f347}",fitzpatrick_scale:!1,category:"food_and_drink"},strawberry:{keywords:["fruit","food","nature"],char:"\u{1f353}",fitzpatrick_scale:!1,category:"food_and_drink"},melon:{keywords:["fruit","nature","food"],char:"\u{1f348}",fitzpatrick_scale:!1,category:"food_and_drink"},cherries:{keywords:["food","fruit"],char:"\u{1f352}",fitzpatrick_scale:!1,category:"food_and_drink"},peach:{keywords:["fruit","nature","food"],char:"\u{1f351}",fitzpatrick_scale:!1,category:"food_and_drink"},pineapple:{keywords:["fruit","nature","food"],char:"\u{1f34d}",fitzpatrick_scale:!1,category:"food_and_drink"},coconut:{keywords:["fruit","nature","food","palm"],char:"\u{1f965}",fitzpatrick_scale:!1,category:"food_and_drink"},kiwi_fruit:{keywords:["fruit","food"],char:"\u{1f95d}",fitzpatrick_scale:!1,category:"food_and_drink"},mango:{keywords:["fruit","food","tropical"],char:"\u{1f96d}",fitzpatrick_scale:!1,category:"food_and_drink"},avocado:{keywords:["fruit","food"],char:"\u{1f951}",fitzpatrick_scale:!1,category:"food_and_drink"},broccoli:{keywords:["fruit","food","vegetable"],char:"\u{1f966}",fitzpatrick_scale:!1,category:"food_and_drink"},tomato:{keywords:["fruit","vegetable","nature","food"],char:"\u{1f345}",fitzpatrick_scale:!1,category:"food_and_drink"},eggplant:{keywords:["vegetable","nature","food","aubergine"],char:"\u{1f346}",fitzpatrick_scale:!1,category:"food_and_drink"},cucumber:{keywords:["fruit","food","pickle"],char:"\u{1f952}",fitzpatrick_scale:!1,category:"food_and_drink"},carrot:{keywords:["vegetable","food","orange"],char:"\u{1f955}",fitzpatrick_scale:!1,category:"food_and_drink"},hot_pepper:{keywords:["food","spicy","chilli","chili"],char:"\u{1f336}",fitzpatrick_scale:!1,category:"food_and_drink"},potato:{keywords:["food","tuber","vegatable","starch"],char:"\u{1f954}",fitzpatrick_scale:!1,category:"food_and_drink"},corn:{keywords:["food","vegetable","plant"],char:"\u{1f33d}",fitzpatrick_scale:!1,category:"food_and_drink"},leafy_greens:{keywords:["food","vegetable","plant","bok choy","cabbage","kale","lettuce"],char:"\u{1f96c}",fitzpatrick_scale:!1,category:"food_and_drink"},sweet_potato:{keywords:["food","nature"],char:"\u{1f360}",fitzpatrick_scale:!1,category:"food_and_drink"},peanuts:{keywords:["food","nut"],char:"\u{1f95c}",fitzpatrick_scale:!1,category:"food_and_drink"},honey_pot:{keywords:["bees","sweet","kitchen"],char:"\u{1f36f}",fitzpatrick_scale:!1,category:"food_and_drink"},croissant:{keywords:["food","bread","french"],char:"\u{1f950}",fitzpatrick_scale:!1,category:"food_and_drink"},bread:{keywords:["food","wheat","breakfast","toast"],char:"\u{1f35e}",fitzpatrick_scale:!1,category:"food_and_drink"},baguette_bread:{keywords:["food","bread","french"],char:"\u{1f956}",fitzpatrick_scale:!1,category:"food_and_drink"},bagel:{keywords:["food","bread","bakery","schmear"],char:"\u{1f96f}",fitzpatrick_scale:!1,category:"food_and_drink"},pretzel:{keywords:["food","bread","twisted"],char:"\u{1f968}",fitzpatrick_scale:!1,category:"food_and_drink"},cheese:{keywords:["food","chadder"],char:"\u{1f9c0}",fitzpatrick_scale:!1,category:"food_and_drink"},egg:{keywords:["food","chicken","breakfast"],char:"\u{1f95a}",fitzpatrick_scale:!1,category:"food_and_drink"},bacon:{keywords:["food","breakfast","pork","pig","meat"],char:"\u{1f953}",fitzpatrick_scale:!1,category:"food_and_drink"},steak:{keywords:["food","cow","meat","cut","chop","lambchop","porkchop"],char:"\u{1f969}",fitzpatrick_scale:!1,category:"food_and_drink"},pancakes:{keywords:["food","breakfast","flapjacks","hotcakes"],char:"\u{1f95e}",fitzpatrick_scale:!1,category:"food_and_drink"},poultry_leg:{keywords:["food","meat","drumstick","bird","chicken","turkey"],char:"\u{1f357}",fitzpatrick_scale:!1,category:"food_and_drink"},meat_on_bone:{keywords:["good","food","drumstick"],char:"\u{1f356}",fitzpatrick_scale:!1,category:"food_and_drink"},bone:{keywords:["skeleton"],char:"\u{1f9b4}",fitzpatrick_scale:!1,category:"food_and_drink"},fried_shrimp:{keywords:["food","animal","appetizer","summer"],char:"\u{1f364}",fitzpatrick_scale:!1,category:"food_and_drink"},fried_egg:{keywords:["food","breakfast","kitchen","egg"],char:"\u{1f373}",fitzpatrick_scale:!1,category:"food_and_drink"},hamburger:{keywords:["meat","fast food","beef","cheeseburger","mcdonalds","burger king"],char:"\u{1f354}",fitzpatrick_scale:!1,category:"food_and_drink"},fries:{keywords:["chips","snack","fast food"],char:"\u{1f35f}",fitzpatrick_scale:!1,category:"food_and_drink"},stuffed_flatbread:{keywords:["food","flatbread","stuffed","gyro"],char:"\u{1f959}",fitzpatrick_scale:!1,category:"food_and_drink"},hotdog:{keywords:["food","frankfurter"],char:"\u{1f32d}",fitzpatrick_scale:!1,category:"food_and_drink"},pizza:{keywords:["food","party"],char:"\u{1f355}",fitzpatrick_scale:!1,category:"food_and_drink"},sandwich:{keywords:["food","lunch","bread"],char:"\u{1f96a}",fitzpatrick_scale:!1,category:"food_and_drink"},canned_food:{keywords:["food","soup"],char:"\u{1f96b}",fitzpatrick_scale:!1,category:"food_and_drink"},spaghetti:{keywords:["food","italian","noodle"],char:"\u{1f35d}",fitzpatrick_scale:!1,category:"food_and_drink"},taco:{keywords:["food","mexican"],char:"\u{1f32e}",fitzpatrick_scale:!1,category:"food_and_drink"},burrito:{keywords:["food","mexican"],char:"\u{1f32f}",fitzpatrick_scale:!1,category:"food_and_drink"},green_salad:{keywords:["food","healthy","lettuce"],char:"\u{1f957}",fitzpatrick_scale:!1,category:"food_and_drink"},shallow_pan_of_food:{keywords:["food","cooking","casserole","paella"],char:"\u{1f958}",fitzpatrick_scale:!1,category:"food_and_drink"},ramen:{keywords:["food","japanese","noodle","chopsticks"],char:"\u{1f35c}",fitzpatrick_scale:!1,category:"food_and_drink"},stew:{keywords:["food","meat","soup"],char:"\u{1f372}",fitzpatrick_scale:!1,category:"food_and_drink"},fish_cake:{keywords:["food","japan","sea","beach","narutomaki","pink","swirl","kamaboko","surimi","ramen"],char:"\u{1f365}",fitzpatrick_scale:!1,category:"food_and_drink"},fortune_cookie:{keywords:["food","prophecy"],char:"\u{1f960}",fitzpatrick_scale:!1,category:"food_and_drink"},sushi:{keywords:["food","fish","japanese","rice"],char:"\u{1f363}",fitzpatrick_scale:!1,category:"food_and_drink"},bento:{keywords:["food","japanese","box"],char:"\u{1f371}",fitzpatrick_scale:!1,category:"food_and_drink"},curry:{keywords:["food","spicy","hot","indian"],char:"\u{1f35b}",fitzpatrick_scale:!1,category:"food_and_drink"},rice_ball:{keywords:["food","japanese"],char:"\u{1f359}",fitzpatrick_scale:!1,category:"food_and_drink"},rice:{keywords:["food","china","asian"],char:"\u{1f35a}",fitzpatrick_scale:!1,category:"food_and_drink"},rice_cracker:{keywords:["food","japanese"],char:"\u{1f358}",fitzpatrick_scale:!1,category:"food_and_drink"},oden:{keywords:["food","japanese"],char:"\u{1f362}",fitzpatrick_scale:!1,category:"food_and_drink"},dango:{keywords:["food","dessert","sweet","japanese","barbecue","meat"],char:"\u{1f361}",fitzpatrick_scale:!1,category:"food_and_drink"},shaved_ice:{keywords:["hot","dessert","summer"],char:"\u{1f367}",fitzpatrick_scale:!1,category:"food_and_drink"},ice_cream:{keywords:["food","hot","dessert"],char:"\u{1f368}",fitzpatrick_scale:!1,category:"food_and_drink"},icecream:{keywords:["food","hot","dessert","summer"],char:"\u{1f366}",fitzpatrick_scale:!1,category:"food_and_drink"},pie:{keywords:["food","dessert","pastry"],char:"\u{1f967}",fitzpatrick_scale:!1,category:"food_and_drink"},cake:{keywords:["food","dessert"],char:"\u{1f370}",fitzpatrick_scale:!1,category:"food_and_drink"},cupcake:{keywords:["food","dessert","bakery","sweet"],char:"\u{1f9c1}",fitzpatrick_scale:!1,category:"food_and_drink"},moon_cake:{keywords:["food","autumn"],char:"\u{1f96e}",fitzpatrick_scale:!1,category:"food_and_drink"},birthday:{keywords:["food","dessert","cake"],char:"\u{1f382}",fitzpatrick_scale:!1,category:"food_and_drink"},custard:{keywords:["dessert","food"],char:"\u{1f36e}",fitzpatrick_scale:!1,category:"food_and_drink"},candy:{keywords:["snack","dessert","sweet","lolly"],char:"\u{1f36c}",fitzpatrick_scale:!1,category:"food_and_drink"},lollipop:{keywords:["food","snack","candy","sweet"],char:"\u{1f36d}",fitzpatrick_scale:!1,category:"food_and_drink"},chocolate_bar:{keywords:["food","snack","dessert","sweet"],char:"\u{1f36b}",fitzpatrick_scale:!1,category:"food_and_drink"},popcorn:{keywords:["food","movie theater","films","snack"],char:"\u{1f37f}",fitzpatrick_scale:!1,category:"food_and_drink"},dumpling:{keywords:["food","empanada","pierogi","potsticker"],char:"\u{1f95f}",fitzpatrick_scale:!1,category:"food_and_drink"},doughnut:{keywords:["food","dessert","snack","sweet","donut"],char:"\u{1f369}",fitzpatrick_scale:!1,category:"food_and_drink"},cookie:{keywords:["food","snack","oreo","chocolate","sweet","dessert"],char:"\u{1f36a}",fitzpatrick_scale:!1,category:"food_and_drink"},milk_glass:{keywords:["beverage","drink","cow"],char:"\u{1f95b}",fitzpatrick_scale:!1,category:"food_and_drink"},beer:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:"\u{1f37a}",fitzpatrick_scale:!1,category:"food_and_drink"},beers:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:"\u{1f37b}",fitzpatrick_scale:!1,category:"food_and_drink"},clinking_glasses:{keywords:["beverage","drink","party","alcohol","celebrate","cheers","wine","champagne","toast"],char:"\u{1f942}",fitzpatrick_scale:!1,category:"food_and_drink"},wine_glass:{keywords:["drink","beverage","drunk","alcohol","booze"],char:"\u{1f377}",fitzpatrick_scale:!1,category:"food_and_drink"},tumbler_glass:{keywords:["drink","beverage","drunk","alcohol","liquor","booze","bourbon","scotch","whisky","glass","shot"],char:"\u{1f943}",fitzpatrick_scale:!1,category:"food_and_drink"},cocktail:{keywords:["drink","drunk","alcohol","beverage","booze","mojito"],char:"\u{1f378}",fitzpatrick_scale:!1,category:"food_and_drink"},tropical_drink:{keywords:["beverage","cocktail","summer","beach","alcohol","booze","mojito"],char:"\u{1f379}",fitzpatrick_scale:!1,category:"food_and_drink"},champagne:{keywords:["drink","wine","bottle","celebration"],char:"\u{1f37e}",fitzpatrick_scale:!1,category:"food_and_drink"},sake:{keywords:["wine","drink","drunk","beverage","japanese","alcohol","booze"],char:"\u{1f376}",fitzpatrick_scale:!1,category:"food_and_drink"},tea:{keywords:["drink","bowl","breakfast","green","british"],char:"\u{1f375}",fitzpatrick_scale:!1,category:"food_and_drink"},cup_with_straw:{keywords:["drink","soda"],char:"\u{1f964}",fitzpatrick_scale:!1,category:"food_and_drink"},coffee:{keywords:["beverage","caffeine","latte","espresso"],char:"\u2615",fitzpatrick_scale:!1,category:"food_and_drink"},baby_bottle:{keywords:["food","container","milk"],char:"\u{1f37c}",fitzpatrick_scale:!1,category:"food_and_drink"},salt:{keywords:["condiment","shaker"],char:"\u{1f9c2}",fitzpatrick_scale:!1,category:"food_and_drink"},spoon:{keywords:["cutlery","kitchen","tableware"],char:"\u{1f944}",fitzpatrick_scale:!1,category:"food_and_drink"},fork_and_knife:{keywords:["cutlery","kitchen"],char:"\u{1f374}",fitzpatrick_scale:!1,category:"food_and_drink"},plate_with_cutlery:{keywords:["food","eat","meal","lunch","dinner","restaurant"],char:"\u{1f37d}",fitzpatrick_scale:!1,category:"food_and_drink"},bowl_with_spoon:{keywords:["food","breakfast","cereal","oatmeal","porridge"],char:"\u{1f963}",fitzpatrick_scale:!1,category:"food_and_drink"},takeout_box:{keywords:["food","leftovers"],char:"\u{1f961}",fitzpatrick_scale:!1,category:"food_and_drink"},chopsticks:{keywords:["food"],char:"\u{1f962}",fitzpatrick_scale:!1,category:"food_and_drink"},soccer:{keywords:["sports","football"],char:"\u26bd",fitzpatrick_scale:!1,category:"activity"},basketball:{keywords:["sports","balls","NBA"],char:"\u{1f3c0}",fitzpatrick_scale:!1,category:"activity"},football:{keywords:["sports","balls","NFL"],char:"\u{1f3c8}",fitzpatrick_scale:!1,category:"activity"},baseball:{keywords:["sports","balls"],char:"\u26be",fitzpatrick_scale:!1,category:"activity"},softball:{keywords:["sports","balls"],char:"\u{1f94e}",fitzpatrick_scale:!1,category:"activity"},tennis:{keywords:["sports","balls","green"],char:"\u{1f3be}",fitzpatrick_scale:!1,category:"activity"},volleyball:{keywords:["sports","balls"],char:"\u{1f3d0}",fitzpatrick_scale:!1,category:"activity"},rugby_football:{keywords:["sports","team"],char:"\u{1f3c9}",fitzpatrick_scale:!1,category:"activity"},flying_disc:{keywords:["sports","frisbee","ultimate"],char:"\u{1f94f}",fitzpatrick_scale:!1,category:"activity"},"8ball":{keywords:["pool","hobby","game","luck","magic"],char:"\u{1f3b1}",fitzpatrick_scale:!1,category:"activity"},golf:{keywords:["sports","business","flag","hole","summer"],char:"\u26f3",fitzpatrick_scale:!1,category:"activity"},golfing_woman:{keywords:["sports","business","woman","female"],char:"\u{1f3cc}\ufe0f\u200d\u2640\ufe0f",fitzpatrick_scale:!1,category:"activity"},golfing_man:{keywords:["sports","business"],char:"\u{1f3cc}",fitzpatrick_scale:!0,category:"activity"},ping_pong:{keywords:["sports","pingpong"],char:"\u{1f3d3}",fitzpatrick_scale:!1,category:"activity"},badminton:{keywords:["sports"],char:"\u{1f3f8}",fitzpatrick_scale:!1,category:"activity"},goal_net:{keywords:["sports"],char:"\u{1f945}",fitzpatrick_scale:!1,category:"activity"},ice_hockey:{keywords:["sports"],char:"\u{1f3d2}",fitzpatrick_scale:!1,category:"activity"},field_hockey:{keywords:["sports"],char:"\u{1f3d1}",fitzpatrick_scale:!1,category:"activity"},lacrosse:{keywords:["sports","ball","stick"],char:"\u{1f94d}",fitzpatrick_scale:!1,category:"activity"},cricket:{keywords:["sports"],char:"\u{1f3cf}",fitzpatrick_scale:!1,category:"activity"},ski:{keywords:["sports","winter","cold","snow"],char:"\u{1f3bf}",fitzpatrick_scale:!1,category:"activity"},skier:{keywords:["sports","winter","snow"],char:"\u26f7",fitzpatrick_scale:!1,category:"activity"},snowboarder:{keywords:["sports","winter"],char:"\u{1f3c2}",fitzpatrick_scale:!0,category:"activity"},person_fencing:{keywords:["sports","fencing","sword"],char:"\u{1f93a}",fitzpatrick_scale:!1,category:"activity"},women_wrestling:{keywords:["sports","wrestlers"],char:"\u{1f93c}\u200d\u2640\ufe0f",fitzpatrick_scale:!1,category:"activity"},men_wrestling:{keywords:["sports","wrestlers"],char:"\u{1f93c}\u200d\u2642\ufe0f",fitzpatrick_scale:!1,category:"activity"},woman_cartwheeling:{keywords:["gymnastics"],char:"\u{1f938}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_cartwheeling:{keywords:["gymnastics"],char:"\u{1f938}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},woman_playing_handball:{keywords:["sports"],char:"\u{1f93e}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_playing_handball:{keywords:["sports"],char:"\u{1f93e}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},ice_skate:{keywords:["sports"],char:"\u26f8",fitzpatrick_scale:!1,category:"activity"},curling_stone:{keywords:["sports"],char:"\u{1f94c}",fitzpatrick_scale:!1,category:"activity"},skateboard:{keywords:["board"],char:"\u{1f6f9}",fitzpatrick_scale:!1,category:"activity"},sled:{keywords:["sleigh","luge","toboggan"],char:"\u{1f6f7}",fitzpatrick_scale:!1,category:"activity"},bow_and_arrow:{keywords:["sports"],char:"\u{1f3f9}",fitzpatrick_scale:!1,category:"activity"},fishing_pole_and_fish:{keywords:["food","hobby","summer"],char:"\u{1f3a3}",fitzpatrick_scale:!1,category:"activity"},boxing_glove:{keywords:["sports","fighting"],char:"\u{1f94a}",fitzpatrick_scale:!1,category:"activity"},martial_arts_uniform:{keywords:["judo","karate","taekwondo"],char:"\u{1f94b}",fitzpatrick_scale:!1,category:"activity"},rowing_woman:{keywords:["sports","hobby","water","ship","woman","female"],char:"\u{1f6a3}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},rowing_man:{keywords:["sports","hobby","water","ship"],char:"\u{1f6a3}",fitzpatrick_scale:!0,category:"activity"},climbing_woman:{keywords:["sports","hobby","woman","female","rock"],char:"\u{1f9d7}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},climbing_man:{keywords:["sports","hobby","man","male","rock"],char:"\u{1f9d7}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},swimming_woman:{keywords:["sports","exercise","human","athlete","water","summer","woman","female"],char:"\u{1f3ca}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},swimming_man:{keywords:["sports","exercise","human","athlete","water","summer"],char:"\u{1f3ca}",fitzpatrick_scale:!0,category:"activity"},woman_playing_water_polo:{keywords:["sports","pool"],char:"\u{1f93d}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_playing_water_polo:{keywords:["sports","pool"],char:"\u{1f93d}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},woman_in_lotus_position:{keywords:["woman","female","meditation","yoga","serenity","zen","mindfulness"],char:"\u{1f9d8}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_in_lotus_position:{keywords:["man","male","meditation","yoga","serenity","zen","mindfulness"],char:"\u{1f9d8}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},surfing_woman:{keywords:["sports","ocean","sea","summer","beach","woman","female"],char:"\u{1f3c4}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},surfing_man:{keywords:["sports","ocean","sea","summer","beach"],char:"\u{1f3c4}",fitzpatrick_scale:!0,category:"activity"},bath:{keywords:["clean","shower","bathroom"],char:"\u{1f6c0}",fitzpatrick_scale:!0,category:"activity"},basketball_woman:{keywords:["sports","human","woman","female"],char:"\u26f9\ufe0f\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},basketball_man:{keywords:["sports","human"],char:"\u26f9",fitzpatrick_scale:!0,category:"activity"},weight_lifting_woman:{keywords:["sports","training","exercise","woman","female"],char:"\u{1f3cb}\ufe0f\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},weight_lifting_man:{keywords:["sports","training","exercise"],char:"\u{1f3cb}",fitzpatrick_scale:!0,category:"activity"},biking_woman:{keywords:["sports","bike","exercise","hipster","woman","female"],char:"\u{1f6b4}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},biking_man:{keywords:["sports","bike","exercise","hipster"],char:"\u{1f6b4}",fitzpatrick_scale:!0,category:"activity"},mountain_biking_woman:{keywords:["transportation","sports","human","race","bike","woman","female"],char:"\u{1f6b5}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},mountain_biking_man:{keywords:["transportation","sports","human","race","bike"],char:"\u{1f6b5}",fitzpatrick_scale:!0,category:"activity"},horse_racing:{keywords:["animal","betting","competition","gambling","luck"],char:"\u{1f3c7}",fitzpatrick_scale:!0,category:"activity"},business_suit_levitating:{keywords:["suit","business","levitate","hover","jump"],char:"\u{1f574}",fitzpatrick_scale:!0,category:"activity"},trophy:{keywords:["win","award","contest","place","ftw","ceremony"],char:"\u{1f3c6}",fitzpatrick_scale:!1,category:"activity"},running_shirt_with_sash:{keywords:["play","pageant"],char:"\u{1f3bd}",fitzpatrick_scale:!1,category:"activity"},medal_sports:{keywords:["award","winning"],char:"\u{1f3c5}",fitzpatrick_scale:!1,category:"activity"},medal_military:{keywords:["award","winning","army"],char:"\u{1f396}",fitzpatrick_scale:!1,category:"activity"},"1st_place_medal":{keywords:["award","winning","first"],char:"\u{1f947}",fitzpatrick_scale:!1,category:"activity"},"2nd_place_medal":{keywords:["award","second"],char:"\u{1f948}",fitzpatrick_scale:!1,category:"activity"},"3rd_place_medal":{keywords:["award","third"],char:"\u{1f949}",fitzpatrick_scale:!1,category:"activity"},reminder_ribbon:{keywords:["sports","cause","support","awareness"],char:"\u{1f397}",fitzpatrick_scale:!1,category:"activity"},rosette:{keywords:["flower","decoration","military"],char:"\u{1f3f5}",fitzpatrick_scale:!1,category:"activity"},ticket:{keywords:["event","concert","pass"],char:"\u{1f3ab}",fitzpatrick_scale:!1,category:"activity"},tickets:{keywords:["sports","concert","entrance"],char:"\u{1f39f}",fitzpatrick_scale:!1,category:"activity"},performing_arts:{keywords:["acting","theater","drama"],char:"\u{1f3ad}",fitzpatrick_scale:!1,category:"activity"},art:{keywords:["design","paint","draw","colors"],char:"\u{1f3a8}",fitzpatrick_scale:!1,category:"activity"},circus_tent:{keywords:["festival","carnival","party"],char:"\u{1f3aa}",fitzpatrick_scale:!1,category:"activity"},woman_juggling:{keywords:["juggle","balance","skill","multitask"],char:"\u{1f939}\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_juggling:{keywords:["juggle","balance","skill","multitask"],char:"\u{1f939}\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},microphone:{keywords:["sound","music","PA","sing","talkshow"],char:"\u{1f3a4}",fitzpatrick_scale:!1,category:"activity"},headphones:{keywords:["music","score","gadgets"],char:"\u{1f3a7}",fitzpatrick_scale:!1,category:"activity"},musical_score:{keywords:["treble","clef","compose"],char:"\u{1f3bc}",fitzpatrick_scale:!1,category:"activity"},musical_keyboard:{keywords:["piano","instrument","compose"],char:"\u{1f3b9}",fitzpatrick_scale:!1,category:"activity"},drum:{keywords:["music","instrument","drumsticks","snare"],char:"\u{1f941}",fitzpatrick_scale:!1,category:"activity"},saxophone:{keywords:["music","instrument","jazz","blues"],char:"\u{1f3b7}",fitzpatrick_scale:!1,category:"activity"},trumpet:{keywords:["music","brass"],char:"\u{1f3ba}",fitzpatrick_scale:!1,category:"activity"},guitar:{keywords:["music","instrument"],char:"\u{1f3b8}",fitzpatrick_scale:!1,category:"activity"},violin:{keywords:["music","instrument","orchestra","symphony"],char:"\u{1f3bb}",fitzpatrick_scale:!1,category:"activity"},clapper:{keywords:["movie","film","record"],char:"\u{1f3ac}",fitzpatrick_scale:!1,category:"activity"},video_game:{keywords:["play","console","PS4","controller"],char:"\u{1f3ae}",fitzpatrick_scale:!1,category:"activity"},space_invader:{keywords:["game","arcade","play"],char:"\u{1f47e}",fitzpatrick_scale:!1,category:"activity"},dart:{keywords:["game","play","bar","target","bullseye"],char:"\u{1f3af}",fitzpatrick_scale:!1,category:"activity"},game_die:{keywords:["dice","random","tabletop","play","luck"],char:"\u{1f3b2}",fitzpatrick_scale:!1,category:"activity"},chess_pawn:{keywords:["expendable"],char:"\u265f",fitzpatrick_scale:!1,category:"activity"},slot_machine:{keywords:["bet","gamble","vegas","fruit machine","luck","casino"],char:"\u{1f3b0}",fitzpatrick_scale:!1,category:"activity"},jigsaw:{keywords:["interlocking","puzzle","piece"],char:"\u{1f9e9}",fitzpatrick_scale:!1,category:"activity"},bowling:{keywords:["sports","fun","play"],char:"\u{1f3b3}",fitzpatrick_scale:!1,category:"activity"},red_car:{keywords:["red","transportation","vehicle"],char:"\u{1f697}",fitzpatrick_scale:!1,category:"travel_and_places"},taxi:{keywords:["uber","vehicle","cars","transportation"],char:"\u{1f695}",fitzpatrick_scale:!1,category:"travel_and_places"},blue_car:{keywords:["transportation","vehicle"],char:"\u{1f699}",fitzpatrick_scale:!1,category:"travel_and_places"},bus:{keywords:["car","vehicle","transportation"],char:"\u{1f68c}",fitzpatrick_scale:!1,category:"travel_and_places"},trolleybus:{keywords:["bart","transportation","vehicle"],char:"\u{1f68e}",fitzpatrick_scale:!1,category:"travel_and_places"},racing_car:{keywords:["sports","race","fast","formula","f1"],char:"\u{1f3ce}",fitzpatrick_scale:!1,category:"travel_and_places"},police_car:{keywords:["vehicle","cars","transportation","law","legal","enforcement"],char:"\u{1f693}",fitzpatrick_scale:!1,category:"travel_and_places"},ambulance:{keywords:["health","911","hospital"],char:"\u{1f691}",fitzpatrick_scale:!1,category:"travel_and_places"},fire_engine:{keywords:["transportation","cars","vehicle"],char:"\u{1f692}",fitzpatrick_scale:!1,category:"travel_and_places"},minibus:{keywords:["vehicle","car","transportation"],char:"\u{1f690}",fitzpatrick_scale:!1,category:"travel_and_places"},truck:{keywords:["cars","transportation"],char:"\u{1f69a}",fitzpatrick_scale:!1,category:"travel_and_places"},articulated_lorry:{keywords:["vehicle","cars","transportation","express"],char:"\u{1f69b}",fitzpatrick_scale:!1,category:"travel_and_places"},tractor:{keywords:["vehicle","car","farming","agriculture"],char:"\u{1f69c}",fitzpatrick_scale:!1,category:"travel_and_places"},kick_scooter:{keywords:["vehicle","kick","razor"],char:"\u{1f6f4}",fitzpatrick_scale:!1,category:"travel_and_places"},motorcycle:{keywords:["race","sports","fast"],char:"\u{1f3cd}",fitzpatrick_scale:!1,category:"travel_and_places"},bike:{keywords:["sports","bicycle","exercise","hipster"],char:"\u{1f6b2}",fitzpatrick_scale:!1,category:"travel_and_places"},motor_scooter:{keywords:["vehicle","vespa","sasha"],char:"\u{1f6f5}",fitzpatrick_scale:!1,category:"travel_and_places"},rotating_light:{keywords:["police","ambulance","911","emergency","alert","error","pinged","law","legal"],char:"\u{1f6a8}",fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_police_car:{keywords:["vehicle","law","legal","enforcement","911"],char:"\u{1f694}",fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_bus:{keywords:["vehicle","transportation"],char:"\u{1f68d}",fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_automobile:{keywords:["car","vehicle","transportation"],char:"\u{1f698}",fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_taxi:{keywords:["vehicle","cars","uber"],char:"\u{1f696}",fitzpatrick_scale:!1,category:"travel_and_places"},aerial_tramway:{keywords:["transportation","vehicle","ski"],char:"\u{1f6a1}",fitzpatrick_scale:!1,category:"travel_and_places"},mountain_cableway:{keywords:["transportation","vehicle","ski"],char:"\u{1f6a0}",fitzpatrick_scale:!1,category:"travel_and_places"},suspension_railway:{keywords:["vehicle","transportation"],char:"\u{1f69f}",fitzpatrick_scale:!1,category:"travel_and_places"},railway_car:{keywords:["transportation","vehicle"],char:"\u{1f683}",fitzpatrick_scale:!1,category:"travel_and_places"},train:{keywords:["transportation","vehicle","carriage","public","travel"],char:"\u{1f68b}",fitzpatrick_scale:!1,category:"travel_and_places"},monorail:{keywords:["transportation","vehicle"],char:"\u{1f69d}",fitzpatrick_scale:!1,category:"travel_and_places"},bullettrain_side:{keywords:["transportation","vehicle"],char:"\u{1f684}",fitzpatrick_scale:!1,category:"travel_and_places"},bullettrain_front:{keywords:["transportation","vehicle","speed","fast","public","travel"],char:"\u{1f685}",fitzpatrick_scale:!1,category:"travel_and_places"},light_rail:{keywords:["transportation","vehicle"],char:"\u{1f688}",fitzpatrick_scale:!1,category:"travel_and_places"},mountain_railway:{keywords:["transportation","vehicle"],char:"\u{1f69e}",fitzpatrick_scale:!1,category:"travel_and_places"},steam_locomotive:{keywords:["transportation","vehicle","train"],char:"\u{1f682}",fitzpatrick_scale:!1,category:"travel_and_places"},train2:{keywords:["transportation","vehicle"],char:"\u{1f686}",fitzpatrick_scale:!1,category:"travel_and_places"},metro:{keywords:["transportation","blue-square","mrt","underground","tube"],char:"\u{1f687}",fitzpatrick_scale:!1,category:"travel_and_places"},tram:{keywords:["transportation","vehicle"],char:"\u{1f68a}",fitzpatrick_scale:!1,category:"travel_and_places"},station:{keywords:["transportation","vehicle","public"],char:"\u{1f689}",fitzpatrick_scale:!1,category:"travel_and_places"},flying_saucer:{keywords:["transportation","vehicle","ufo"],char:"\u{1f6f8}",fitzpatrick_scale:!1,category:"travel_and_places"},helicopter:{keywords:["transportation","vehicle","fly"],char:"\u{1f681}",fitzpatrick_scale:!1,category:"travel_and_places"},small_airplane:{keywords:["flight","transportation","fly","vehicle"],char:"\u{1f6e9}",fitzpatrick_scale:!1,category:"travel_and_places"},airplane:{keywords:["vehicle","transportation","flight","fly"],char:"\u2708\ufe0f",fitzpatrick_scale:!1,category:"travel_and_places"},flight_departure:{keywords:["airport","flight","landing"],char:"\u{1f6eb}",fitzpatrick_scale:!1,category:"travel_and_places"},flight_arrival:{keywords:["airport","flight","boarding"],char:"\u{1f6ec}",fitzpatrick_scale:!1,category:"travel_and_places"},sailboat:{keywords:["ship","summer","transportation","water","sailing"],char:"\u26f5",fitzpatrick_scale:!1,category:"travel_and_places"},motor_boat:{keywords:["ship"],char:"\u{1f6e5}",fitzpatrick_scale:!1,category:"travel_and_places"},speedboat:{keywords:["ship","transportation","vehicle","summer"],char:"\u{1f6a4}",fitzpatrick_scale:!1,category:"travel_and_places"},ferry:{keywords:["boat","ship","yacht"],char:"\u26f4",fitzpatrick_scale:!1,category:"travel_and_places"},passenger_ship:{keywords:["yacht","cruise","ferry"],char:"\u{1f6f3}",fitzpatrick_scale:!1,category:"travel_and_places"},rocket:{keywords:["launch","ship","staffmode","NASA","outer space","outer_space","fly"],char:"\u{1f680}",fitzpatrick_scale:!1,category:"travel_and_places"},artificial_satellite:{keywords:["communication","gps","orbit","spaceflight","NASA","ISS"],char:"\u{1f6f0}",fitzpatrick_scale:!1,category:"travel_and_places"},seat:{keywords:["sit","airplane","transport","bus","flight","fly"],char:"\u{1f4ba}",fitzpatrick_scale:!1,category:"travel_and_places"},canoe:{keywords:["boat","paddle","water","ship"],char:"\u{1f6f6}",fitzpatrick_scale:!1,category:"travel_and_places"},anchor:{keywords:["ship","ferry","sea","boat"],char:"\u2693",fitzpatrick_scale:!1,category:"travel_and_places"},construction:{keywords:["wip","progress","caution","warning"],char:"\u{1f6a7}",fitzpatrick_scale:!1,category:"travel_and_places"},fuelpump:{keywords:["gas station","petroleum"],char:"\u26fd",fitzpatrick_scale:!1,category:"travel_and_places"},busstop:{keywords:["transportation","wait"],char:"\u{1f68f}",fitzpatrick_scale:!1,category:"travel_and_places"},vertical_traffic_light:{keywords:["transportation","driving"],char:"\u{1f6a6}",fitzpatrick_scale:!1,category:"travel_and_places"},traffic_light:{keywords:["transportation","signal"],char:"\u{1f6a5}",fitzpatrick_scale:!1,category:"travel_and_places"},checkered_flag:{keywords:["contest","finishline","race","gokart"],char:"\u{1f3c1}",fitzpatrick_scale:!1,category:"travel_and_places"},ship:{keywords:["transportation","titanic","deploy"],char:"\u{1f6a2}",fitzpatrick_scale:!1,category:"travel_and_places"},ferris_wheel:{keywords:["photo","carnival","londoneye"],char:"\u{1f3a1}",fitzpatrick_scale:!1,category:"travel_and_places"},roller_coaster:{keywords:["carnival","playground","photo","fun"],char:"\u{1f3a2}",fitzpatrick_scale:!1,category:"travel_and_places"},carousel_horse:{keywords:["photo","carnival"],char:"\u{1f3a0}",fitzpatrick_scale:!1,category:"travel_and_places"},building_construction:{keywords:["wip","working","progress"],char:"\u{1f3d7}",fitzpatrick_scale:!1,category:"travel_and_places"},foggy:{keywords:["photo","mountain"],char:"\u{1f301}",fitzpatrick_scale:!1,category:"travel_and_places"},tokyo_tower:{keywords:["photo","japanese"],char:"\u{1f5fc}",fitzpatrick_scale:!1,category:"travel_and_places"},factory:{keywords:["building","industry","pollution","smoke"],char:"\u{1f3ed}",fitzpatrick_scale:!1,category:"travel_and_places"},fountain:{keywords:["photo","summer","water","fresh"],char:"\u26f2",fitzpatrick_scale:!1,category:"travel_and_places"},rice_scene:{keywords:["photo","japan","asia","tsukimi"],char:"\u{1f391}",fitzpatrick_scale:!1,category:"travel_and_places"},mountain:{keywords:["photo","nature","environment"],char:"\u26f0",fitzpatrick_scale:!1,category:"travel_and_places"},mountain_snow:{keywords:["photo","nature","environment","winter","cold"],char:"\u{1f3d4}",fitzpatrick_scale:!1,category:"travel_and_places"},mount_fuji:{keywords:["photo","mountain","nature","japanese"],char:"\u{1f5fb}",fitzpatrick_scale:!1,category:"travel_and_places"},volcano:{keywords:["photo","nature","disaster"],char:"\u{1f30b}",fitzpatrick_scale:!1,category:"travel_and_places"},japan:{keywords:["nation","country","japanese","asia"],char:"\u{1f5fe}",fitzpatrick_scale:!1,category:"travel_and_places"},camping:{keywords:["photo","outdoors","tent"],char:"\u{1f3d5}",fitzpatrick_scale:!1,category:"travel_and_places"},tent:{keywords:["photo","camping","outdoors"],char:"\u26fa",fitzpatrick_scale:!1,category:"travel_and_places"},national_park:{keywords:["photo","environment","nature"],char:"\u{1f3de}",fitzpatrick_scale:!1,category:"travel_and_places"},motorway:{keywords:["road","cupertino","interstate","highway"],char:"\u{1f6e3}",fitzpatrick_scale:!1,category:"travel_and_places"},railway_track:{keywords:["train","transportation"],char:"\u{1f6e4}",fitzpatrick_scale:!1,category:"travel_and_places"},sunrise:{keywords:["morning","view","vacation","photo"],char:"\u{1f305}",fitzpatrick_scale:!1,category:"travel_and_places"},sunrise_over_mountains:{keywords:["view","vacation","photo"],char:"\u{1f304}",fitzpatrick_scale:!1,category:"travel_and_places"},desert:{keywords:["photo","warm","saharah"],char:"\u{1f3dc}",fitzpatrick_scale:!1,category:"travel_and_places"},beach_umbrella:{keywords:["weather","summer","sunny","sand","mojito"],char:"\u{1f3d6}",fitzpatrick_scale:!1,category:"travel_and_places"},desert_island:{keywords:["photo","tropical","mojito"],char:"\u{1f3dd}",fitzpatrick_scale:!1,category:"travel_and_places"},city_sunrise:{keywords:["photo","good morning","dawn"],char:"\u{1f307}",fitzpatrick_scale:!1,category:"travel_and_places"},city_sunset:{keywords:["photo","evening","sky","buildings"],char:"\u{1f306}",fitzpatrick_scale:!1,category:"travel_and_places"},cityscape:{keywords:["photo","night life","urban"],char:"\u{1f3d9}",fitzpatrick_scale:!1,category:"travel_and_places"},night_with_stars:{keywords:["evening","city","downtown"],char:"\u{1f303}",fitzpatrick_scale:!1,category:"travel_and_places"},bridge_at_night:{keywords:["photo","sanfrancisco"],char:"\u{1f309}",fitzpatrick_scale:!1,category:"travel_and_places"},milky_way:{keywords:["photo","space","stars"],char:"\u{1f30c}",fitzpatrick_scale:!1,category:"travel_and_places"},stars:{keywords:["night","photo"],char:"\u{1f320}",fitzpatrick_scale:!1,category:"travel_and_places"},sparkler:{keywords:["stars","night","shine"],char:"\u{1f387}",fitzpatrick_scale:!1,category:"travel_and_places"},fireworks:{keywords:["photo","festival","carnival","congratulations"],char:"\u{1f386}",fitzpatrick_scale:!1,category:"travel_and_places"},rainbow:{keywords:["nature","happy","unicorn_face","photo","sky","spring"],char:"\u{1f308}",fitzpatrick_scale:!1,category:"travel_and_places"},houses:{keywords:["buildings","photo"],char:"\u{1f3d8}",fitzpatrick_scale:!1,category:"travel_and_places"},european_castle:{keywords:["building","royalty","history"],char:"\u{1f3f0}",fitzpatrick_scale:!1,category:"travel_and_places"},japanese_castle:{keywords:["photo","building"],char:"\u{1f3ef}",fitzpatrick_scale:!1,category:"travel_and_places"},stadium:{keywords:["photo","place","sports","concert","venue"],char:"\u{1f3df}",fitzpatrick_scale:!1,category:"travel_and_places"},statue_of_liberty:{keywords:["american","newyork"],char:"\u{1f5fd}",fitzpatrick_scale:!1,category:"travel_and_places"},house:{keywords:["building","home"],char:"\u{1f3e0}",fitzpatrick_scale:!1,category:"travel_and_places"},house_with_garden:{keywords:["home","plant","nature"],char:"\u{1f3e1}",fitzpatrick_scale:!1,category:"travel_and_places"},derelict_house:{keywords:["abandon","evict","broken","building"],char:"\u{1f3da}",fitzpatrick_scale:!1,category:"travel_and_places"},office:{keywords:["building","bureau","work"],char:"\u{1f3e2}",fitzpatrick_scale:!1,category:"travel_and_places"},department_store:{keywords:["building","shopping","mall"],char:"\u{1f3ec}",fitzpatrick_scale:!1,category:"travel_and_places"},post_office:{keywords:["building","envelope","communication"],char:"\u{1f3e3}",fitzpatrick_scale:!1,category:"travel_and_places"},european_post_office:{keywords:["building","email"],char:"\u{1f3e4}",fitzpatrick_scale:!1,category:"travel_and_places"},hospital:{keywords:["building","health","surgery","doctor"],char:"\u{1f3e5}",fitzpatrick_scale:!1,category:"travel_and_places"},bank:{keywords:["building","money","sales","cash","business","enterprise"],char:"\u{1f3e6}",fitzpatrick_scale:!1,category:"travel_and_places"},hotel:{keywords:["building","accomodation","checkin"],char:"\u{1f3e8}",fitzpatrick_scale:!1,category:"travel_and_places"},convenience_store:{keywords:["building","shopping","groceries"],char:"\u{1f3ea}",fitzpatrick_scale:!1,category:"travel_and_places"},school:{keywords:["building","student","education","learn","teach"],char:"\u{1f3eb}",fitzpatrick_scale:!1,category:"travel_and_places"},love_hotel:{keywords:["like","affection","dating"],char:"\u{1f3e9}",fitzpatrick_scale:!1,category:"travel_and_places"},wedding:{keywords:["love","like","affection","couple","marriage","bride","groom"],char:"\u{1f492}",fitzpatrick_scale:!1,category:"travel_and_places"},classical_building:{keywords:["art","culture","history"],char:"\u{1f3db}",fitzpatrick_scale:!1,category:"travel_and_places"},church:{keywords:["building","religion","christ"],char:"\u26ea",fitzpatrick_scale:!1,category:"travel_and_places"},mosque:{keywords:["islam","worship","minaret"],char:"\u{1f54c}",fitzpatrick_scale:!1,category:"travel_and_places"},synagogue:{keywords:["judaism","worship","temple","jewish"],char:"\u{1f54d}",fitzpatrick_scale:!1,category:"travel_and_places"},kaaba:{keywords:["mecca","mosque","islam"],char:"\u{1f54b}",fitzpatrick_scale:!1,category:"travel_and_places"},shinto_shrine:{keywords:["temple","japan","kyoto"],char:"\u26e9",fitzpatrick_scale:!1,category:"travel_and_places"},watch:{keywords:["time","accessories"],char:"\u231a",fitzpatrick_scale:!1,category:"objects"},iphone:{keywords:["technology","apple","gadgets","dial"],char:"\u{1f4f1}",fitzpatrick_scale:!1,category:"objects"},calling:{keywords:["iphone","incoming"],char:"\u{1f4f2}",fitzpatrick_scale:!1,category:"objects"},computer:{keywords:["technology","laptop","screen","display","monitor"],char:"\u{1f4bb}",fitzpatrick_scale:!1,category:"objects"},keyboard:{keywords:["technology","computer","type","input","text"],char:"\u2328",fitzpatrick_scale:!1,category:"objects"},desktop_computer:{keywords:["technology","computing","screen"],char:"\u{1f5a5}",fitzpatrick_scale:!1,category:"objects"},printer:{keywords:["paper","ink"],char:"\u{1f5a8}",fitzpatrick_scale:!1,category:"objects"},computer_mouse:{keywords:["click"],char:"\u{1f5b1}",fitzpatrick_scale:!1,category:"objects"},trackball:{keywords:["technology","trackpad"],char:"\u{1f5b2}",fitzpatrick_scale:!1,category:"objects"},joystick:{keywords:["game","play"],char:"\u{1f579}",fitzpatrick_scale:!1,category:"objects"},clamp:{keywords:["tool"],char:"\u{1f5dc}",fitzpatrick_scale:!1,category:"objects"},minidisc:{keywords:["technology","record","data","disk","90s"],char:"\u{1f4bd}",fitzpatrick_scale:!1,category:"objects"},floppy_disk:{keywords:["oldschool","technology","save","90s","80s"],char:"\u{1f4be}",fitzpatrick_scale:!1,category:"objects"},cd:{keywords:["technology","dvd","disk","disc","90s"],char:"\u{1f4bf}",fitzpatrick_scale:!1,category:"objects"},dvd:{keywords:["cd","disk","disc"],char:"\u{1f4c0}",fitzpatrick_scale:!1,category:"objects"},vhs:{keywords:["record","video","oldschool","90s","80s"],char:"\u{1f4fc}",fitzpatrick_scale:!1,category:"objects"},camera:{keywords:["gadgets","photography"],char:"\u{1f4f7}",fitzpatrick_scale:!1,category:"objects"},camera_flash:{keywords:["photography","gadgets"],char:"\u{1f4f8}",fitzpatrick_scale:!1,category:"objects"},video_camera:{keywords:["film","record"],char:"\u{1f4f9}",fitzpatrick_scale:!1,category:"objects"},movie_camera:{keywords:["film","record"],char:"\u{1f3a5}",fitzpatrick_scale:!1,category:"objects"},film_projector:{keywords:["video","tape","record","movie"],char:"\u{1f4fd}",fitzpatrick_scale:!1,category:"objects"},film_strip:{keywords:["movie"],char:"\u{1f39e}",fitzpatrick_scale:!1,category:"objects"},telephone_receiver:{keywords:["technology","communication","dial"],char:"\u{1f4de}",fitzpatrick_scale:!1,category:"objects"},phone:{keywords:["technology","communication","dial","telephone"],char:"\u260e\ufe0f",fitzpatrick_scale:!1,category:"objects"},pager:{keywords:["bbcall","oldschool","90s"],char:"\u{1f4df}",fitzpatrick_scale:!1,category:"objects"},fax:{keywords:["communication","technology"],char:"\u{1f4e0}",fitzpatrick_scale:!1,category:"objects"},tv:{keywords:["technology","program","oldschool","show","television"],char:"\u{1f4fa}",fitzpatrick_scale:!1,category:"objects"},radio:{keywords:["communication","music","podcast","program"],char:"\u{1f4fb}",fitzpatrick_scale:!1,category:"objects"},studio_microphone:{keywords:["sing","recording","artist","talkshow"],char:"\u{1f399}",fitzpatrick_scale:!1,category:"objects"},level_slider:{keywords:["scale"],char:"\u{1f39a}",fitzpatrick_scale:!1,category:"objects"},control_knobs:{keywords:["dial"],char:"\u{1f39b}",fitzpatrick_scale:!1,category:"objects"},compass:{keywords:["magnetic","navigation","orienteering"],char:"\u{1f9ed}",fitzpatrick_scale:!1,category:"objects"},stopwatch:{keywords:["time","deadline"],char:"\u23f1",fitzpatrick_scale:!1,category:"objects"},timer_clock:{keywords:["alarm"],char:"\u23f2",fitzpatrick_scale:!1,category:"objects"},alarm_clock:{keywords:["time","wake"],char:"\u23f0",fitzpatrick_scale:!1,category:"objects"},mantelpiece_clock:{keywords:["time"],char:"\u{1f570}",fitzpatrick_scale:!1,category:"objects"},hourglass_flowing_sand:{keywords:["oldschool","time","countdown"],char:"\u23f3",fitzpatrick_scale:!1,category:"objects"},hourglass:{keywords:["time","clock","oldschool","limit","exam","quiz","test"],char:"\u231b",fitzpatrick_scale:!1,category:"objects"},satellite:{keywords:["communication","future","radio","space"],char:"\u{1f4e1}",fitzpatrick_scale:!1,category:"objects"},battery:{keywords:["power","energy","sustain"],char:"\u{1f50b}",fitzpatrick_scale:!1,category:"objects"},electric_plug:{keywords:["charger","power"],char:"\u{1f50c}",fitzpatrick_scale:!1,category:"objects"},bulb:{keywords:["light","electricity","idea"],char:"\u{1f4a1}",fitzpatrick_scale:!1,category:"objects"},flashlight:{keywords:["dark","camping","sight","night"],char:"\u{1f526}",fitzpatrick_scale:!1,category:"objects"},candle:{keywords:["fire","wax"],char:"\u{1f56f}",fitzpatrick_scale:!1,category:"objects"},fire_extinguisher:{keywords:["quench"],char:"\u{1f9ef}",fitzpatrick_scale:!1,category:"objects"},wastebasket:{keywords:["bin","trash","rubbish","garbage","toss"],char:"\u{1f5d1}",fitzpatrick_scale:!1,category:"objects"},oil_drum:{keywords:["barrell"],char:"\u{1f6e2}",fitzpatrick_scale:!1,category:"objects"},money_with_wings:{keywords:["dollar","bills","payment","sale"],char:"\u{1f4b8}",fitzpatrick_scale:!1,category:"objects"},dollar:{keywords:["money","sales","bill","currency"],char:"\u{1f4b5}",fitzpatrick_scale:!1,category:"objects"},yen:{keywords:["money","sales","japanese","dollar","currency"],char:"\u{1f4b4}",fitzpatrick_scale:!1,category:"objects"},euro:{keywords:["money","sales","dollar","currency"],char:"\u{1f4b6}",fitzpatrick_scale:!1,category:"objects"},pound:{keywords:["british","sterling","money","sales","bills","uk","england","currency"],char:"\u{1f4b7}",fitzpatrick_scale:!1,category:"objects"},moneybag:{keywords:["dollar","payment","coins","sale"],char:"\u{1f4b0}",fitzpatrick_scale:!1,category:"objects"},credit_card:{keywords:["money","sales","dollar","bill","payment","shopping"],char:"\u{1f4b3}",fitzpatrick_scale:!1,category:"objects"},gem:{keywords:["blue","ruby","diamond","jewelry"],char:"\u{1f48e}",fitzpatrick_scale:!1,category:"objects"},balance_scale:{keywords:["law","fairness","weight"],char:"\u2696",fitzpatrick_scale:!1,category:"objects"},toolbox:{keywords:["tools","diy","fix","maintainer","mechanic"],char:"\u{1f9f0}",fitzpatrick_scale:!1,category:"objects"},wrench:{keywords:["tools","diy","ikea","fix","maintainer"],char:"\u{1f527}",fitzpatrick_scale:!1,category:"objects"},hammer:{keywords:["tools","build","create"],char:"\u{1f528}",fitzpatrick_scale:!1,category:"objects"},hammer_and_pick:{keywords:["tools","build","create"],char:"\u2692",fitzpatrick_scale:!1,category:"objects"},hammer_and_wrench:{keywords:["tools","build","create"],char:"\u{1f6e0}",fitzpatrick_scale:!1,category:"objects"},pick:{keywords:["tools","dig"],char:"\u26cf",fitzpatrick_scale:!1,category:"objects"},nut_and_bolt:{keywords:["handy","tools","fix"],char:"\u{1f529}",fitzpatrick_scale:!1,category:"objects"},gear:{keywords:["cog"],char:"\u2699",fitzpatrick_scale:!1,category:"objects"},brick:{keywords:["bricks"],char:"\u{1f9f1}",fitzpatrick_scale:!1,category:"objects"},chains:{keywords:["lock","arrest"],char:"\u26d3",fitzpatrick_scale:!1,category:"objects"},magnet:{keywords:["attraction","magnetic"],char:"\u{1f9f2}",fitzpatrick_scale:!1,category:"objects"},gun:{keywords:["violence","weapon","pistol","revolver"],char:"\u{1f52b}",fitzpatrick_scale:!1,category:"objects"},bomb:{keywords:["boom","explode","explosion","terrorism"],char:"\u{1f4a3}",fitzpatrick_scale:!1,category:"objects"},firecracker:{keywords:["dynamite","boom","explode","explosion","explosive"],char:"\u{1f9e8}",fitzpatrick_scale:!1,category:"objects"},hocho:{keywords:["knife","blade","cutlery","kitchen","weapon"],char:"\u{1f52a}",fitzpatrick_scale:!1,category:"objects"},dagger:{keywords:["weapon"],char:"\u{1f5e1}",fitzpatrick_scale:!1,category:"objects"},crossed_swords:{keywords:["weapon"],char:"\u2694",fitzpatrick_scale:!1,category:"objects"},shield:{keywords:["protection","security"],char:"\u{1f6e1}",fitzpatrick_scale:!1,category:"objects"},smoking:{keywords:["kills","tobacco","cigarette","joint","smoke"],char:"\u{1f6ac}",fitzpatrick_scale:!1,category:"objects"},skull_and_crossbones:{keywords:["poison","danger","deadly","scary","death","pirate","evil"],char:"\u2620",fitzpatrick_scale:!1,category:"objects"},coffin:{keywords:["vampire","dead","die","death","rip","graveyard","cemetery","casket","funeral","box"],char:"\u26b0",fitzpatrick_scale:!1,category:"objects"},funeral_urn:{keywords:["dead","die","death","rip","ashes"],char:"\u26b1",fitzpatrick_scale:!1,category:"objects"},amphora:{keywords:["vase","jar"],char:"\u{1f3fa}",fitzpatrick_scale:!1,category:"objects"},crystal_ball:{keywords:["disco","party","magic","circus","fortune_teller"],char:"\u{1f52e}",fitzpatrick_scale:!1,category:"objects"},prayer_beads:{keywords:["dhikr","religious"],char:"\u{1f4ff}",fitzpatrick_scale:!1,category:"objects"},nazar_amulet:{keywords:["bead","charm"],char:"\u{1f9ff}",fitzpatrick_scale:!1,category:"objects"},barber:{keywords:["hair","salon","style"],char:"\u{1f488}",fitzpatrick_scale:!1,category:"objects"},alembic:{keywords:["distilling","science","experiment","chemistry"],char:"\u2697",fitzpatrick_scale:!1,category:"objects"},telescope:{keywords:["stars","space","zoom","science","astronomy"],char:"\u{1f52d}",fitzpatrick_scale:!1,category:"objects"},microscope:{keywords:["laboratory","experiment","zoomin","science","study"],char:"\u{1f52c}",fitzpatrick_scale:!1,category:"objects"},hole:{keywords:["embarrassing"],char:"\u{1f573}",fitzpatrick_scale:!1,category:"objects"},pill:{keywords:["health","medicine","doctor","pharmacy","drug"],char:"\u{1f48a}",fitzpatrick_scale:!1,category:"objects"},syringe:{keywords:["health","hospital","drugs","blood","medicine","needle","doctor","nurse"],char:"\u{1f489}",fitzpatrick_scale:!1,category:"objects"},dna:{keywords:["biologist","genetics","life"],char:"\u{1f9ec}",fitzpatrick_scale:!1,category:"objects"},microbe:{keywords:["amoeba","bacteria","germs"],char:"\u{1f9a0}",fitzpatrick_scale:!1,category:"objects"},petri_dish:{keywords:["bacteria","biology","culture","lab"],char:"\u{1f9eb}",fitzpatrick_scale:!1,category:"objects"},test_tube:{keywords:["chemistry","experiment","lab","science"],char:"\u{1f9ea}",fitzpatrick_scale:!1,category:"objects"},thermometer:{keywords:["weather","temperature","hot","cold"],char:"\u{1f321}",fitzpatrick_scale:!1,category:"objects"},broom:{keywords:["cleaning","sweeping","witch"],char:"\u{1f9f9}",fitzpatrick_scale:!1,category:"objects"},basket:{keywords:["laundry"],char:"\u{1f9fa}",fitzpatrick_scale:!1,category:"objects"},toilet_paper:{keywords:["roll"],char:"\u{1f9fb}",fitzpatrick_scale:!1,category:"objects"},label:{keywords:["sale","tag"],char:"\u{1f3f7}",fitzpatrick_scale:!1,category:"objects"},bookmark:{keywords:["favorite","label","save"],char:"\u{1f516}",fitzpatrick_scale:!1,category:"objects"},toilet:{keywords:["restroom","wc","washroom","bathroom","potty"],char:"\u{1f6bd}",fitzpatrick_scale:!1,category:"objects"},shower:{keywords:["clean","water","bathroom"],char:"\u{1f6bf}",fitzpatrick_scale:!1,category:"objects"},bathtub:{keywords:["clean","shower","bathroom"],char:"\u{1f6c1}",fitzpatrick_scale:!1,category:"objects"},soap:{keywords:["bar","bathing","cleaning","lather"],char:"\u{1f9fc}",fitzpatrick_scale:!1,category:"objects"},sponge:{keywords:["absorbing","cleaning","porous"],char:"\u{1f9fd}",fitzpatrick_scale:!1,category:"objects"},lotion_bottle:{keywords:["moisturizer","sunscreen"],char:"\u{1f9f4}",fitzpatrick_scale:!1,category:"objects"},key:{keywords:["lock","door","password"],char:"\u{1f511}",fitzpatrick_scale:!1,category:"objects"},old_key:{keywords:["lock","door","password"],char:"\u{1f5dd}",fitzpatrick_scale:!1,category:"objects"},couch_and_lamp:{keywords:["read","chill"],char:"\u{1f6cb}",fitzpatrick_scale:!1,category:"objects"},sleeping_bed:{keywords:["bed","rest"],char:"\u{1f6cc}",fitzpatrick_scale:!0,category:"objects"},bed:{keywords:["sleep","rest"],char:"\u{1f6cf}",fitzpatrick_scale:!1,category:"objects"},door:{keywords:["house","entry","exit"],char:"\u{1f6aa}",fitzpatrick_scale:!1,category:"objects"},bellhop_bell:{keywords:["service"],char:"\u{1f6ce}",fitzpatrick_scale:!1,category:"objects"},teddy_bear:{keywords:["plush","stuffed"],char:"\u{1f9f8}",fitzpatrick_scale:!1,category:"objects"},framed_picture:{keywords:["photography"],char:"\u{1f5bc}",fitzpatrick_scale:!1,category:"objects"},world_map:{keywords:["location","direction"],char:"\u{1f5fa}",fitzpatrick_scale:!1,category:"objects"},parasol_on_ground:{keywords:["weather","summer"],char:"\u26f1",fitzpatrick_scale:!1,category:"objects"},moyai:{keywords:["rock","easter island","moai"],char:"\u{1f5ff}",fitzpatrick_scale:!1,category:"objects"},shopping:{keywords:["mall","buy","purchase"],char:"\u{1f6cd}",fitzpatrick_scale:!1,category:"objects"},shopping_cart:{keywords:["trolley"],char:"\u{1f6d2}",fitzpatrick_scale:!1,category:"objects"},balloon:{keywords:["party","celebration","birthday","circus"],char:"\u{1f388}",fitzpatrick_scale:!1,category:"objects"},flags:{keywords:["fish","japanese","koinobori","carp","banner"],char:"\u{1f38f}",fitzpatrick_scale:!1,category:"objects"},ribbon:{keywords:["decoration","pink","girl","bowtie"],char:"\u{1f380}",fitzpatrick_scale:!1,category:"objects"},gift:{keywords:["present","birthday","christmas","xmas"],char:"\u{1f381}",fitzpatrick_scale:!1,category:"objects"},confetti_ball:{keywords:["festival","party","birthday","circus"],char:"\u{1f38a}",fitzpatrick_scale:!1,category:"objects"},tada:{keywords:["party","congratulations","birthday","magic","circus","celebration"],char:"\u{1f389}",fitzpatrick_scale:!1,category:"objects"},dolls:{keywords:["japanese","toy","kimono"],char:"\u{1f38e}",fitzpatrick_scale:!1,category:"objects"},wind_chime:{keywords:["nature","ding","spring","bell"],char:"\u{1f390}",fitzpatrick_scale:!1,category:"objects"},crossed_flags:{keywords:["japanese","nation","country","border"],char:"\u{1f38c}",fitzpatrick_scale:!1,category:"objects"},izakaya_lantern:{keywords:["light","paper","halloween","spooky"],char:"\u{1f3ee}",fitzpatrick_scale:!1,category:"objects"},red_envelope:{keywords:["gift"],char:"\u{1f9e7}",fitzpatrick_scale:!1,category:"objects"},email:{keywords:["letter","postal","inbox","communication"],char:"\u2709\ufe0f",fitzpatrick_scale:!1,category:"objects"},envelope_with_arrow:{keywords:["email","communication"],char:"\u{1f4e9}",fitzpatrick_scale:!1,category:"objects"},incoming_envelope:{keywords:["email","inbox"],char:"\u{1f4e8}",fitzpatrick_scale:!1,category:"objects"},"e-mail":{keywords:["communication","inbox"],char:"\u{1f4e7}",fitzpatrick_scale:!1,category:"objects"},love_letter:{keywords:["email","like","affection","envelope","valentines"],char:"\u{1f48c}",fitzpatrick_scale:!1,category:"objects"},postbox:{keywords:["email","letter","envelope"],char:"\u{1f4ee}",fitzpatrick_scale:!1,category:"objects"},mailbox_closed:{keywords:["email","communication","inbox"],char:"\u{1f4ea}",fitzpatrick_scale:!1,category:"objects"},mailbox:{keywords:["email","inbox","communication"],char:"\u{1f4eb}",fitzpatrick_scale:!1,category:"objects"},mailbox_with_mail:{keywords:["email","inbox","communication"],char:"\u{1f4ec}",fitzpatrick_scale:!1,category:"objects"},mailbox_with_no_mail:{keywords:["email","inbox"],char:"\u{1f4ed}",fitzpatrick_scale:!1,category:"objects"},package:{keywords:["mail","gift","cardboard","box","moving"],char:"\u{1f4e6}",fitzpatrick_scale:!1,category:"objects"},postal_horn:{keywords:["instrument","music"],char:"\u{1f4ef}",fitzpatrick_scale:!1,category:"objects"},inbox_tray:{keywords:["email","documents"],char:"\u{1f4e5}",fitzpatrick_scale:!1,category:"objects"},outbox_tray:{keywords:["inbox","email"],char:"\u{1f4e4}",fitzpatrick_scale:!1,category:"objects"},scroll:{keywords:["documents","ancient","history","paper"],char:"\u{1f4dc}",fitzpatrick_scale:!1,category:"objects"},page_with_curl:{keywords:["documents","office","paper"],char:"\u{1f4c3}",fitzpatrick_scale:!1,category:"objects"},bookmark_tabs:{keywords:["favorite","save","order","tidy"],char:"\u{1f4d1}",fitzpatrick_scale:!1,category:"objects"},receipt:{keywords:["accounting","expenses"],char:"\u{1f9fe}",fitzpatrick_scale:!1,category:"objects"},bar_chart:{keywords:["graph","presentation","stats"],char:"\u{1f4ca}",fitzpatrick_scale:!1,category:"objects"},chart_with_upwards_trend:{keywords:["graph","presentation","stats","recovery","business","economics","money","sales","good","success"],char:"\u{1f4c8}",fitzpatrick_scale:!1,category:"objects"},chart_with_downwards_trend:{keywords:["graph","presentation","stats","recession","business","economics","money","sales","bad","failure"],char:"\u{1f4c9}",fitzpatrick_scale:!1,category:"objects"},page_facing_up:{keywords:["documents","office","paper","information"],char:"\u{1f4c4}",fitzpatrick_scale:!1,category:"objects"},date:{keywords:["calendar","schedule"],char:"\u{1f4c5}",fitzpatrick_scale:!1,category:"objects"},calendar:{keywords:["schedule","date","planning"],char:"\u{1f4c6}",fitzpatrick_scale:!1,category:"objects"},spiral_calendar:{keywords:["date","schedule","planning"],char:"\u{1f5d3}",fitzpatrick_scale:!1,category:"objects"},card_index:{keywords:["business","stationery"],char:"\u{1f4c7}",fitzpatrick_scale:!1,category:"objects"},card_file_box:{keywords:["business","stationery"],char:"\u{1f5c3}",fitzpatrick_scale:!1,category:"objects"},ballot_box:{keywords:["election","vote"],char:"\u{1f5f3}",fitzpatrick_scale:!1,category:"objects"},file_cabinet:{keywords:["filing","organizing"],char:"\u{1f5c4}",fitzpatrick_scale:!1,category:"objects"},clipboard:{keywords:["stationery","documents"],char:"\u{1f4cb}",fitzpatrick_scale:!1,category:"objects"},spiral_notepad:{keywords:["memo","stationery"],char:"\u{1f5d2}",fitzpatrick_scale:!1,category:"objects"},file_folder:{keywords:["documents","business","office"],char:"\u{1f4c1}",fitzpatrick_scale:!1,category:"objects"},open_file_folder:{keywords:["documents","load"],char:"\u{1f4c2}",fitzpatrick_scale:!1,category:"objects"},card_index_dividers:{keywords:["organizing","business","stationery"],char:"\u{1f5c2}",fitzpatrick_scale:!1,category:"objects"},newspaper_roll:{keywords:["press","headline"],char:"\u{1f5de}",fitzpatrick_scale:!1,category:"objects"},newspaper:{keywords:["press","headline"],char:"\u{1f4f0}",fitzpatrick_scale:!1,category:"objects"},notebook:{keywords:["stationery","record","notes","paper","study"],char:"\u{1f4d3}",fitzpatrick_scale:!1,category:"objects"},closed_book:{keywords:["read","library","knowledge","textbook","learn"],char:"\u{1f4d5}",fitzpatrick_scale:!1,category:"objects"},green_book:{keywords:["read","library","knowledge","study"],char:"\u{1f4d7}",fitzpatrick_scale:!1,category:"objects"},blue_book:{keywords:["read","library","knowledge","learn","study"],char:"\u{1f4d8}",fitzpatrick_scale:!1,category:"objects"},orange_book:{keywords:["read","library","knowledge","textbook","study"],char:"\u{1f4d9}",fitzpatrick_scale:!1,category:"objects"},notebook_with_decorative_cover:{keywords:["classroom","notes","record","paper","study"],char:"\u{1f4d4}",fitzpatrick_scale:!1,category:"objects"},ledger:{keywords:["notes","paper"],char:"\u{1f4d2}",fitzpatrick_scale:!1,category:"objects"},books:{keywords:["literature","library","study"],char:"\u{1f4da}",fitzpatrick_scale:!1,category:"objects"},open_book:{keywords:["book","read","library","knowledge","literature","learn","study"],char:"\u{1f4d6}",fitzpatrick_scale:!1,category:"objects"},safety_pin:{keywords:["diaper"],char:"\u{1f9f7}",fitzpatrick_scale:!1,category:"objects"},link:{keywords:["rings","url"],char:"\u{1f517}",fitzpatrick_scale:!1,category:"objects"},paperclip:{keywords:["documents","stationery"],char:"\u{1f4ce}",fitzpatrick_scale:!1,category:"objects"},paperclips:{keywords:["documents","stationery"],char:"\u{1f587}",fitzpatrick_scale:!1,category:"objects"},scissors:{keywords:["stationery","cut"],char:"\u2702\ufe0f",fitzpatrick_scale:!1,category:"objects"},triangular_ruler:{keywords:["stationery","math","architect","sketch"],char:"\u{1f4d0}",fitzpatrick_scale:!1,category:"objects"},straight_ruler:{keywords:["stationery","calculate","length","math","school","drawing","architect","sketch"],char:"\u{1f4cf}",fitzpatrick_scale:!1,category:"objects"},abacus:{keywords:["calculation"],char:"\u{1f9ee}",fitzpatrick_scale:!1,category:"objects"},pushpin:{keywords:["stationery","mark","here"],char:"\u{1f4cc}",fitzpatrick_scale:!1,category:"objects"},round_pushpin:{keywords:["stationery","location","map","here"],char:"\u{1f4cd}",fitzpatrick_scale:!1,category:"objects"},triangular_flag_on_post:{keywords:["mark","milestone","place"],char:"\u{1f6a9}",fitzpatrick_scale:!1,category:"objects"},white_flag:{keywords:["losing","loser","lost","surrender","give up","fail"],char:"\u{1f3f3}",fitzpatrick_scale:!1,category:"objects"},black_flag:{keywords:["pirate"],char:"\u{1f3f4}",fitzpatrick_scale:!1,category:"objects"},rainbow_flag:{keywords:["flag","rainbow","pride","gay","lgbt","glbt","queer","homosexual","lesbian","bisexual","transgender"],char:"\u{1f3f3}\ufe0f\u200d\u{1f308}",fitzpatrick_scale:!1,category:"objects"},closed_lock_with_key:{keywords:["security","privacy"],char:"\u{1f510}",fitzpatrick_scale:!1,category:"objects"},lock:{keywords:["security","password","padlock"],char:"\u{1f512}",fitzpatrick_scale:!1,category:"objects"},unlock:{keywords:["privacy","security"],char:"\u{1f513}",fitzpatrick_scale:!1,category:"objects"},lock_with_ink_pen:{keywords:["security","secret"],char:"\u{1f50f}",fitzpatrick_scale:!1,category:"objects"},pen:{keywords:["stationery","writing","write"],char:"\u{1f58a}",fitzpatrick_scale:!1,category:"objects"},fountain_pen:{keywords:["stationery","writing","write"],char:"\u{1f58b}",fitzpatrick_scale:!1,category:"objects"},black_nib:{keywords:["pen","stationery","writing","write"],char:"\u2712\ufe0f",fitzpatrick_scale:!1,category:"objects"},memo:{keywords:["write","documents","stationery","pencil","paper","writing","legal","exam","quiz","test","study","compose"],char:"\u{1f4dd}",fitzpatrick_scale:!1,category:"objects"},pencil2:{keywords:["stationery","write","paper","writing","school","study"],char:"\u270f\ufe0f",fitzpatrick_scale:!1,category:"objects"},crayon:{keywords:["drawing","creativity"],char:"\u{1f58d}",fitzpatrick_scale:!1,category:"objects"},paintbrush:{keywords:["drawing","creativity","art"],char:"\u{1f58c}",fitzpatrick_scale:!1,category:"objects"},mag:{keywords:["search","zoom","find","detective"],char:"\u{1f50d}",fitzpatrick_scale:!1,category:"objects"},mag_right:{keywords:["search","zoom","find","detective"],char:"\u{1f50e}",fitzpatrick_scale:!1,category:"objects"},heart:{keywords:["love","like","valentines"],char:"\u2764\ufe0f",fitzpatrick_scale:!1,category:"symbols"},orange_heart:{keywords:["love","like","affection","valentines"],char:"\u{1f9e1}",fitzpatrick_scale:!1,category:"symbols"},yellow_heart:{keywords:["love","like","affection","valentines"],char:"\u{1f49b}",fitzpatrick_scale:!1,category:"symbols"},green_heart:{keywords:["love","like","affection","valentines"],char:"\u{1f49a}",fitzpatrick_scale:!1,category:"symbols"},blue_heart:{keywords:["love","like","affection","valentines"],char:"\u{1f499}",fitzpatrick_scale:!1,category:"symbols"},purple_heart:{keywords:["love","like","affection","valentines"],char:"\u{1f49c}",fitzpatrick_scale:!1,category:"symbols"},black_heart:{keywords:["evil"],char:"\u{1f5a4}",fitzpatrick_scale:!1,category:"symbols"},broken_heart:{keywords:["sad","sorry","break","heart","heartbreak"],char:"\u{1f494}",fitzpatrick_scale:!1,category:"symbols"},heavy_heart_exclamation:{keywords:["decoration","love"],char:"\u2763",fitzpatrick_scale:!1,category:"symbols"},two_hearts:{keywords:["love","like","affection","valentines","heart"],char:"\u{1f495}",fitzpatrick_scale:!1,category:"symbols"},revolving_hearts:{keywords:["love","like","affection","valentines"],char:"\u{1f49e}",fitzpatrick_scale:!1,category:"symbols"},heartbeat:{keywords:["love","like","affection","valentines","pink","heart"],char:"\u{1f493}",fitzpatrick_scale:!1,category:"symbols"},heartpulse:{keywords:["like","love","affection","valentines","pink"],char:"\u{1f497}",fitzpatrick_scale:!1,category:"symbols"},sparkling_heart:{keywords:["love","like","affection","valentines"],char:"\u{1f496}",fitzpatrick_scale:!1,category:"symbols"},cupid:{keywords:["love","like","heart","affection","valentines"],char:"\u{1f498}",fitzpatrick_scale:!1,category:"symbols"},gift_heart:{keywords:["love","valentines"],char:"\u{1f49d}",fitzpatrick_scale:!1,category:"symbols"},heart_decoration:{keywords:["purple-square","love","like"],char:"\u{1f49f}",fitzpatrick_scale:!1,category:"symbols"},peace_symbol:{keywords:["hippie"],char:"\u262e",fitzpatrick_scale:!1,category:"symbols"},latin_cross:{keywords:["christianity"],char:"\u271d",fitzpatrick_scale:!1,category:"symbols"},star_and_crescent:{keywords:["islam"],char:"\u262a",fitzpatrick_scale:!1,category:"symbols"},om:{keywords:["hinduism","buddhism","sikhism","jainism"],char:"\u{1f549}",fitzpatrick_scale:!1,category:"symbols"},wheel_of_dharma:{keywords:["hinduism","buddhism","sikhism","jainism"],char:"\u2638",fitzpatrick_scale:!1,category:"symbols"},star_of_david:{keywords:["judaism"],char:"\u2721",fitzpatrick_scale:!1,category:"symbols"},six_pointed_star:{keywords:["purple-square","religion","jewish","hexagram"],char:"\u{1f52f}",fitzpatrick_scale:!1,category:"symbols"},menorah:{keywords:["hanukkah","candles","jewish"],char:"\u{1f54e}",fitzpatrick_scale:!1,category:"symbols"},yin_yang:{keywords:["balance"],char:"\u262f",fitzpatrick_scale:!1,category:"symbols"},orthodox_cross:{keywords:["suppedaneum","religion"],char:"\u2626",fitzpatrick_scale:!1,category:"symbols"},place_of_worship:{keywords:["religion","church","temple","prayer"],char:"\u{1f6d0}",fitzpatrick_scale:!1,category:"symbols"},ophiuchus:{keywords:["sign","purple-square","constellation","astrology"],char:"\u26ce",fitzpatrick_scale:!1,category:"symbols"},aries:{keywords:["sign","purple-square","zodiac","astrology"],char:"\u2648",fitzpatrick_scale:!1,category:"symbols"},taurus:{keywords:["purple-square","sign","zodiac","astrology"],char:"\u2649",fitzpatrick_scale:!1,category:"symbols"},gemini:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u264a",fitzpatrick_scale:!1,category:"symbols"},cancer:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u264b",fitzpatrick_scale:!1,category:"symbols"},leo:{keywords:["sign","purple-square","zodiac","astrology"],char:"\u264c",fitzpatrick_scale:!1,category:"symbols"},virgo:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u264d",fitzpatrick_scale:!1,category:"symbols"},libra:{keywords:["sign","purple-square","zodiac","astrology"],char:"\u264e",fitzpatrick_scale:!1,category:"symbols"},scorpius:{keywords:["sign","zodiac","purple-square","astrology","scorpio"],char:"\u264f",fitzpatrick_scale:!1,category:"symbols"},sagittarius:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u2650",fitzpatrick_scale:!1,category:"symbols"},capricorn:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u2651",fitzpatrick_scale:!1,category:"symbols"},aquarius:{keywords:["sign","purple-square","zodiac","astrology"],char:"\u2652",fitzpatrick_scale:!1,category:"symbols"},pisces:{keywords:["purple-square","sign","zodiac","astrology"],char:"\u2653",fitzpatrick_scale:!1,category:"symbols"},id:{keywords:["purple-square","words"],char:"\u{1f194}",fitzpatrick_scale:!1,category:"symbols"},atom_symbol:{keywords:["science","physics","chemistry"],char:"\u269b",fitzpatrick_scale:!1,category:"symbols"},u7a7a:{keywords:["kanji","japanese","chinese","empty","sky","blue-square"],char:"\u{1f233}",fitzpatrick_scale:!1,category:"symbols"},u5272:{keywords:["cut","divide","chinese","kanji","pink-square"],char:"\u{1f239}",fitzpatrick_scale:!1,category:"symbols"},radioactive:{keywords:["nuclear","danger"],char:"\u2622",fitzpatrick_scale:!1,category:"symbols"},biohazard:{keywords:["danger"],char:"\u2623",fitzpatrick_scale:!1,category:"symbols"},mobile_phone_off:{keywords:["mute","orange-square","silence","quiet"],char:"\u{1f4f4}",fitzpatrick_scale:!1,category:"symbols"},vibration_mode:{keywords:["orange-square","phone"],char:"\u{1f4f3}",fitzpatrick_scale:!1,category:"symbols"},u6709:{keywords:["orange-square","chinese","have","kanji"],char:"\u{1f236}",fitzpatrick_scale:!1,category:"symbols"},u7121:{keywords:["nothing","chinese","kanji","japanese","orange-square"],char:"\u{1f21a}",fitzpatrick_scale:!1,category:"symbols"},u7533:{keywords:["chinese","japanese","kanji","orange-square"],char:"\u{1f238}",fitzpatrick_scale:!1,category:"symbols"},u55b6:{keywords:["japanese","opening hours","orange-square"],char:"\u{1f23a}",fitzpatrick_scale:!1,category:"symbols"},u6708:{keywords:["chinese","month","moon","japanese","orange-square","kanji"],char:"\u{1f237}\ufe0f",fitzpatrick_scale:!1,category:"symbols"},eight_pointed_black_star:{keywords:["orange-square","shape","polygon"],char:"\u2734\ufe0f",fitzpatrick_scale:!1,category:"symbols"},vs:{keywords:["words","orange-square"],char:"\u{1f19a}",fitzpatrick_scale:!1,category:"symbols"},accept:{keywords:["ok","good","chinese","kanji","agree","yes","orange-circle"],char:"\u{1f251}",fitzpatrick_scale:!1,category:"symbols"},white_flower:{keywords:["japanese","spring"],char:"\u{1f4ae}",fitzpatrick_scale:!1,category:"symbols"},ideograph_advantage:{keywords:["chinese","kanji","obtain","get","circle"],char:"\u{1f250}",fitzpatrick_scale:!1,category:"symbols"},secret:{keywords:["privacy","chinese","sshh","kanji","red-circle"],char:"\u3299\ufe0f",fitzpatrick_scale:!1,category:"symbols"},congratulations:{keywords:["chinese","kanji","japanese","red-circle"],char:"\u3297\ufe0f",fitzpatrick_scale:!1,category:"symbols"},u5408:{keywords:["japanese","chinese","join","kanji","red-square"],char:"\u{1f234}",fitzpatrick_scale:!1,category:"symbols"},u6e80:{keywords:["full","chinese","japanese","red-square","kanji"],char:"\u{1f235}",fitzpatrick_scale:!1,category:"symbols"},u7981:{keywords:["kanji","japanese","chinese","forbidden","limit","restricted","red-square"],char:"\u{1f232}",fitzpatrick_scale:!1,category:"symbols"},a:{keywords:["red-square","alphabet","letter"],char:"\u{1f170}\ufe0f",fitzpatrick_scale:!1,category:"symbols"},b:{keywords:["red-square","alphabet","letter"],char:"\u{1f171}\ufe0f",fitzpatrick_scale:!1,category:"symbols"},ab:{keywords:["red-square","alphabet"],char:"\u{1f18e}",fitzpatrick_scale:!1,category:"symbols"},cl:{keywords:["alphabet","words","red-square"],char:"\u{1f191}",fitzpatrick_scale:!1,category:"symbols"},o2:{keywords:["alphabet","red-square","letter"],char:"\u{1f17e}\ufe0f",fitzpatrick_scale:!1,category:"symbols"},sos:{keywords:["help","red-square","words","emergency","911"],char:"\u{1f198}",fitzpatrick_scale:!1,category:"symbols"},no_entry:{keywords:["limit","security","privacy","bad","denied","stop","circle"],char:"\u26d4",fitzpatrick_scale:!1,category:"symbols"},name_badge:{keywords:["fire","forbid"],char:"\u{1f4db}",fitzpatrick_scale:!1,category:"symbols"},no_entry_sign:{keywords:["forbid","stop","limit","denied","disallow","circle"],char:"\u{1f6ab}",fitzpatrick_scale:!1,category:"symbols"},x:{keywords:["no","delete","remove","cancel","red"],char:"\u274c",fitzpatrick_scale:!1,category:"symbols"},o:{keywords:["circle","round"],char:"\u2b55",fitzpatrick_scale:!1,category:"symbols"},stop_sign:{keywords:["stop"],char:"\u{1f6d1}",fitzpatrick_scale:!1,category:"symbols"},anger:{keywords:["angry","mad"],char:"\u{1f4a2}",fitzpatrick_scale:!1,category:"symbols"},hotsprings:{keywords:["bath","warm","relax"],char:"\u2668\ufe0f",fitzpatrick_scale:!1,category:"symbols"},no_pedestrians:{keywords:["rules","crossing","walking","circle"],char:"\u{1f6b7}",fitzpatrick_scale:!1,category:"symbols"},do_not_litter:{keywords:["trash","bin","garbage","circle"],char:"\u{1f6af}",fitzpatrick_scale:!1,category:"symbols"},no_bicycles:{keywords:["cyclist","prohibited","circle"],char:"\u{1f6b3}",fitzpatrick_scale:!1,category:"symbols"},"non-potable_water":{keywords:["drink","faucet","tap","circle"],char:"\u{1f6b1}",fitzpatrick_scale:!1,category:"symbols"},underage:{keywords:["18","drink","pub","night","minor","circle"],char:"\u{1f51e}",fitzpatrick_scale:!1,category:"symbols"},no_mobile_phones:{keywords:["iphone","mute","circle"],char:"\u{1f4f5}",fitzpatrick_scale:!1,category:"symbols"},exclamation:{keywords:["heavy_exclamation_mark","danger","surprise","punctuation","wow","warning"],char:"\u2757",fitzpatrick_scale:!1,category:"symbols"},grey_exclamation:{keywords:["surprise","punctuation","gray","wow","warning"],char:"\u2755",fitzpatrick_scale:!1,category:"symbols"},question:{keywords:["doubt","confused"],char:"\u2753",fitzpatrick_scale:!1,category:"symbols"},grey_question:{keywords:["doubts","gray","huh","confused"],char:"\u2754",fitzpatrick_scale:!1,category:"symbols"},bangbang:{keywords:["exclamation","surprise"],char:"\u203c\ufe0f",fitzpatrick_scale:!1,category:"symbols"},interrobang:{keywords:["wat","punctuation","surprise"],char:"\u2049\ufe0f",fitzpatrick_scale:!1,category:"symbols"},100:{keywords:["score","perfect","numbers","century","exam","quiz","test","pass","hundred"],char:"\u{1f4af}",fitzpatrick_scale:!1,category:"symbols"},low_brightness:{keywords:["sun","afternoon","warm","summer"],char:"\u{1f505}",fitzpatrick_scale:!1,category:"symbols"},high_brightness:{keywords:["sun","light"],char:"\u{1f506}",fitzpatrick_scale:!1,category:"symbols"},trident:{keywords:["weapon","spear"],char:"\u{1f531}",fitzpatrick_scale:!1,category:"symbols"},fleur_de_lis:{keywords:["decorative","scout"],char:"\u269c",fitzpatrick_scale:!1,category:"symbols"},part_alternation_mark:{keywords:["graph","presentation","stats","business","economics","bad"],char:"\u303d\ufe0f",fitzpatrick_scale:!1,category:"symbols"},warning:{keywords:["exclamation","wip","alert","error","problem","issue"],char:"\u26a0\ufe0f",fitzpatrick_scale:!1,category:"symbols"},children_crossing:{keywords:["school","warning","danger","sign","driving","yellow-diamond"],char:"\u{1f6b8}",fitzpatrick_scale:!1,category:"symbols"},beginner:{keywords:["badge","shield"],char:"\u{1f530}",fitzpatrick_scale:!1,category:"symbols"},recycle:{keywords:["arrow","environment","garbage","trash"],char:"\u267b\ufe0f",fitzpatrick_scale:!1,category:"symbols"},u6307:{keywords:["chinese","point","green-square","kanji"],char:"\u{1f22f}",fitzpatrick_scale:!1,category:"symbols"},chart:{keywords:["green-square","graph","presentation","stats"],char:"\u{1f4b9}",fitzpatrick_scale:!1,category:"symbols"},sparkle:{keywords:["stars","green-square","awesome","good","fireworks"],char:"\u2747\ufe0f",fitzpatrick_scale:!1,category:"symbols"},eight_spoked_asterisk:{keywords:["star","sparkle","green-square"],char:"\u2733\ufe0f",fitzpatrick_scale:!1,category:"symbols"},negative_squared_cross_mark:{keywords:["x","green-square","no","deny"],char:"\u274e",fitzpatrick_scale:!1,category:"symbols"},white_check_mark:{keywords:["green-square","ok","agree","vote","election","answer","tick"],char:"\u2705",fitzpatrick_scale:!1,category:"symbols"},diamond_shape_with_a_dot_inside:{keywords:["jewel","blue","gem","crystal","fancy"],char:"\u{1f4a0}",fitzpatrick_scale:!1,category:"symbols"},cyclone:{keywords:["weather","swirl","blue","cloud","vortex","spiral","whirlpool","spin","tornado","hurricane","typhoon"],char:"\u{1f300}",fitzpatrick_scale:!1,category:"symbols"},loop:{keywords:["tape","cassette"],char:"\u27bf",fitzpatrick_scale:!1,category:"symbols"},globe_with_meridians:{keywords:["earth","international","world","internet","interweb","i18n"],char:"\u{1f310}",fitzpatrick_scale:!1,category:"symbols"},m:{keywords:["alphabet","blue-circle","letter"],char:"\u24c2\ufe0f",fitzpatrick_scale:!1,category:"symbols"},atm:{keywords:["money","sales","cash","blue-square","payment","bank"],char:"\u{1f3e7}",fitzpatrick_scale:!1,category:"symbols"},sa:{keywords:["japanese","blue-square","katakana"],char:"\u{1f202}\ufe0f",fitzpatrick_scale:!1,category:"symbols"},passport_control:{keywords:["custom","blue-square"],char:"\u{1f6c2}",fitzpatrick_scale:!1,category:"symbols"},customs:{keywords:["passport","border","blue-square"],char:"\u{1f6c3}",fitzpatrick_scale:!1,category:"symbols"},baggage_claim:{keywords:["blue-square","airport","transport"],char:"\u{1f6c4}",fitzpatrick_scale:!1,category:"symbols"},left_luggage:{keywords:["blue-square","travel"],char:"\u{1f6c5}",fitzpatrick_scale:!1,category:"symbols"},wheelchair:{keywords:["blue-square","disabled","a11y","accessibility"],char:"\u267f",fitzpatrick_scale:!1,category:"symbols"},no_smoking:{keywords:["cigarette","blue-square","smell","smoke"],char:"\u{1f6ad}",fitzpatrick_scale:!1,category:"symbols"},wc:{keywords:["toilet","restroom","blue-square"],char:"\u{1f6be}",fitzpatrick_scale:!1,category:"symbols"},parking:{keywords:["cars","blue-square","alphabet","letter"],char:"\u{1f17f}\ufe0f",fitzpatrick_scale:!1,category:"symbols"},potable_water:{keywords:["blue-square","liquid","restroom","cleaning","faucet"],char:"\u{1f6b0}",fitzpatrick_scale:!1,category:"symbols"},mens:{keywords:["toilet","restroom","wc","blue-square","gender","male"],char:"\u{1f6b9}",fitzpatrick_scale:!1,category:"symbols"},womens:{keywords:["purple-square","woman","female","toilet","loo","restroom","gender"],char:"\u{1f6ba}",fitzpatrick_scale:!1,category:"symbols"},baby_symbol:{keywords:["orange-square","child"],char:"\u{1f6bc}",fitzpatrick_scale:!1,category:"symbols"},restroom:{keywords:["blue-square","toilet","refresh","wc","gender"],char:"\u{1f6bb}",fitzpatrick_scale:!1,category:"symbols"},put_litter_in_its_place:{keywords:["blue-square","sign","human","info"],char:"\u{1f6ae}",fitzpatrick_scale:!1,category:"symbols"},cinema:{keywords:["blue-square","record","film","movie","curtain","stage","theater"],char:"\u{1f3a6}",fitzpatrick_scale:!1,category:"symbols"},signal_strength:{keywords:["blue-square","reception","phone","internet","connection","wifi","bluetooth","bars"],char:"\u{1f4f6}",fitzpatrick_scale:!1,category:"symbols"},koko:{keywords:["blue-square","here","katakana","japanese","destination"],char:"\u{1f201}",fitzpatrick_scale:!1,category:"symbols"},ng:{keywords:["blue-square","words","shape","icon"],char:"\u{1f196}",fitzpatrick_scale:!1,category:"symbols"},ok:{keywords:["good","agree","yes","blue-square"],char:"\u{1f197}",fitzpatrick_scale:!1,category:"symbols"},up:{keywords:["blue-square","above","high"],char:"\u{1f199}",fitzpatrick_scale:!1,category:"symbols"},cool:{keywords:["words","blue-square"],char:"\u{1f192}",fitzpatrick_scale:!1,category:"symbols"},new:{keywords:["blue-square","words","start"],char:"\u{1f195}",fitzpatrick_scale:!1,category:"symbols"},free:{keywords:["blue-square","words"],char:"\u{1f193}",fitzpatrick_scale:!1,category:"symbols"},zero:{keywords:["0","numbers","blue-square","null"],char:"0\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},one:{keywords:["blue-square","numbers","1"],char:"1\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},two:{keywords:["numbers","2","prime","blue-square"],char:"2\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},three:{keywords:["3","numbers","prime","blue-square"],char:"3\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},four:{keywords:["4","numbers","blue-square"],char:"4\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},five:{keywords:["5","numbers","blue-square","prime"],char:"5\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},six:{keywords:["6","numbers","blue-square"],char:"6\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},seven:{keywords:["7","numbers","blue-square","prime"],char:"7\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},eight:{keywords:["8","blue-square","numbers"],char:"8\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},nine:{keywords:["blue-square","numbers","9"],char:"9\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},keycap_ten:{keywords:["numbers","10","blue-square"],char:"\u{1f51f}",fitzpatrick_scale:!1,category:"symbols"},asterisk:{keywords:["star","keycap"],char:"*\u20e3",fitzpatrick_scale:!1,category:"symbols"},1234:{keywords:["numbers","blue-square"],char:"\u{1f522}",fitzpatrick_scale:!1,category:"symbols"},eject_button:{keywords:["blue-square"],char:"\u23cf\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_forward:{keywords:["blue-square","right","direction","play"],char:"\u25b6\ufe0f",fitzpatrick_scale:!1,category:"symbols"},pause_button:{keywords:["pause","blue-square"],char:"\u23f8",fitzpatrick_scale:!1,category:"symbols"},next_track_button:{keywords:["forward","next","blue-square"],char:"\u23ed",fitzpatrick_scale:!1,category:"symbols"},stop_button:{keywords:["blue-square"],char:"\u23f9",fitzpatrick_scale:!1,category:"symbols"},record_button:{keywords:["blue-square"],char:"\u23fa",fitzpatrick_scale:!1,category:"symbols"},play_or_pause_button:{keywords:["blue-square","play","pause"],char:"\u23ef",fitzpatrick_scale:!1,category:"symbols"},previous_track_button:{keywords:["backward"],char:"\u23ee",fitzpatrick_scale:!1,category:"symbols"},fast_forward:{keywords:["blue-square","play","speed","continue"],char:"\u23e9",fitzpatrick_scale:!1,category:"symbols"},rewind:{keywords:["play","blue-square"],char:"\u23ea",fitzpatrick_scale:!1,category:"symbols"},twisted_rightwards_arrows:{keywords:["blue-square","shuffle","music","random"],char:"\u{1f500}",fitzpatrick_scale:!1,category:"symbols"},repeat:{keywords:["loop","record"],char:"\u{1f501}",fitzpatrick_scale:!1,category:"symbols"},repeat_one:{keywords:["blue-square","loop"],char:"\u{1f502}",fitzpatrick_scale:!1,category:"symbols"},arrow_backward:{keywords:["blue-square","left","direction"],char:"\u25c0\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_up_small:{keywords:["blue-square","triangle","direction","point","forward","top"],char:"\u{1f53c}",fitzpatrick_scale:!1,category:"symbols"},arrow_down_small:{keywords:["blue-square","direction","bottom"],char:"\u{1f53d}",fitzpatrick_scale:!1,category:"symbols"},arrow_double_up:{keywords:["blue-square","direction","top"],char:"\u23eb",fitzpatrick_scale:!1,category:"symbols"},arrow_double_down:{keywords:["blue-square","direction","bottom"],char:"\u23ec",fitzpatrick_scale:!1,category:"symbols"},arrow_right:{keywords:["blue-square","next"],char:"\u27a1\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_left:{keywords:["blue-square","previous","back"],char:"\u2b05\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_up:{keywords:["blue-square","continue","top","direction"],char:"\u2b06\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_down:{keywords:["blue-square","direction","bottom"],char:"\u2b07\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_upper_right:{keywords:["blue-square","point","direction","diagonal","northeast"],char:"\u2197\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_lower_right:{keywords:["blue-square","direction","diagonal","southeast"],char:"\u2198\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_lower_left:{keywords:["blue-square","direction","diagonal","southwest"],char:"\u2199\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_upper_left:{keywords:["blue-square","point","direction","diagonal","northwest"],char:"\u2196\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_up_down:{keywords:["blue-square","direction","way","vertical"],char:"\u2195\ufe0f",fitzpatrick_scale:!1,category:"symbols"},left_right_arrow:{keywords:["shape","direction","horizontal","sideways"],char:"\u2194\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrows_counterclockwise:{keywords:["blue-square","sync","cycle"],char:"\u{1f504}",fitzpatrick_scale:!1,category:"symbols"},arrow_right_hook:{keywords:["blue-square","return","rotate","direction"],char:"\u21aa\ufe0f",fitzpatrick_scale:!1,category:"symbols"},leftwards_arrow_with_hook:{keywords:["back","return","blue-square","undo","enter"],char:"\u21a9\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_heading_up:{keywords:["blue-square","direction","top"],char:"\u2934\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_heading_down:{keywords:["blue-square","direction","bottom"],char:"\u2935\ufe0f",fitzpatrick_scale:!1,category:"symbols"},hash:{keywords:["symbol","blue-square","twitter"],char:"#\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},information_source:{keywords:["blue-square","alphabet","letter"],char:"\u2139\ufe0f",fitzpatrick_scale:!1,category:"symbols"},abc:{keywords:["blue-square","alphabet"],char:"\u{1f524}",fitzpatrick_scale:!1,category:"symbols"},abcd:{keywords:["blue-square","alphabet"],char:"\u{1f521}",fitzpatrick_scale:!1,category:"symbols"},capital_abcd:{keywords:["alphabet","words","blue-square"],char:"\u{1f520}",fitzpatrick_scale:!1,category:"symbols"},symbols:{keywords:["blue-square","music","note","ampersand","percent","glyphs","characters"],char:"\u{1f523}",fitzpatrick_scale:!1,category:"symbols"},musical_note:{keywords:["score","tone","sound"],char:"\u{1f3b5}",fitzpatrick_scale:!1,category:"symbols"},notes:{keywords:["music","score"],char:"\u{1f3b6}",fitzpatrick_scale:!1,category:"symbols"},wavy_dash:{keywords:["draw","line","moustache","mustache","squiggle","scribble"],char:"\u3030\ufe0f",fitzpatrick_scale:!1,category:"symbols"},curly_loop:{keywords:["scribble","draw","shape","squiggle"],char:"\u27b0",fitzpatrick_scale:!1,category:"symbols"},heavy_check_mark:{keywords:["ok","nike","answer","yes","tick"],char:"\u2714\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrows_clockwise:{keywords:["sync","cycle","round","repeat"],char:"\u{1f503}",fitzpatrick_scale:!1,category:"symbols"},heavy_plus_sign:{keywords:["math","calculation","addition","more","increase"],char:"\u2795",fitzpatrick_scale:!1,category:"symbols"},heavy_minus_sign:{keywords:["math","calculation","subtract","less"],char:"\u2796",fitzpatrick_scale:!1,category:"symbols"},heavy_division_sign:{keywords:["divide","math","calculation"],char:"\u2797",fitzpatrick_scale:!1,category:"symbols"},heavy_multiplication_x:{keywords:["math","calculation"],char:"\u2716\ufe0f",fitzpatrick_scale:!1,category:"symbols"},infinity:{keywords:["forever"],char:"\u267e",fitzpatrick_scale:!1,category:"symbols"},heavy_dollar_sign:{keywords:["money","sales","payment","currency","buck"],char:"\u{1f4b2}",fitzpatrick_scale:!1,category:"symbols"},currency_exchange:{keywords:["money","sales","dollar","travel"],char:"\u{1f4b1}",fitzpatrick_scale:!1,category:"symbols"},copyright:{keywords:["ip","license","circle","law","legal"],char:"\xa9\ufe0f",fitzpatrick_scale:!1,category:"symbols"},registered:{keywords:["alphabet","circle"],char:"\xae\ufe0f",fitzpatrick_scale:!1,category:"symbols"},tm:{keywords:["trademark","brand","law","legal"],char:"\u2122\ufe0f",fitzpatrick_scale:!1,category:"symbols"},end:{keywords:["words","arrow"],char:"\u{1f51a}",fitzpatrick_scale:!1,category:"symbols"},back:{keywords:["arrow","words","return"],char:"\u{1f519}",fitzpatrick_scale:!1,category:"symbols"},on:{keywords:["arrow","words"],char:"\u{1f51b}",fitzpatrick_scale:!1,category:"symbols"},top:{keywords:["words","blue-square"],char:"\u{1f51d}",fitzpatrick_scale:!1,category:"symbols"},soon:{keywords:["arrow","words"],char:"\u{1f51c}",fitzpatrick_scale:!1,category:"symbols"},ballot_box_with_check:{keywords:["ok","agree","confirm","black-square","vote","election","yes","tick"],char:"\u2611\ufe0f",fitzpatrick_scale:!1,category:"symbols"},radio_button:{keywords:["input","old","music","circle"],char:"\u{1f518}",fitzpatrick_scale:!1,category:"symbols"},white_circle:{keywords:["shape","round"],char:"\u26aa",fitzpatrick_scale:!1,category:"symbols"},black_circle:{keywords:["shape","button","round"],char:"\u26ab",fitzpatrick_scale:!1,category:"symbols"},red_circle:{keywords:["shape","error","danger"],char:"\u{1f534}",fitzpatrick_scale:!1,category:"symbols"},large_blue_circle:{keywords:["shape","icon","button"],char:"\u{1f535}",fitzpatrick_scale:!1,category:"symbols"},small_orange_diamond:{keywords:["shape","jewel","gem"],char:"\u{1f538}",fitzpatrick_scale:!1,category:"symbols"},small_blue_diamond:{keywords:["shape","jewel","gem"],char:"\u{1f539}",fitzpatrick_scale:!1,category:"symbols"},large_orange_diamond:{keywords:["shape","jewel","gem"],char:"\u{1f536}",fitzpatrick_scale:!1,category:"symbols"},large_blue_diamond:{keywords:["shape","jewel","gem"],char:"\u{1f537}",fitzpatrick_scale:!1,category:"symbols"},small_red_triangle:{keywords:["shape","direction","up","top"],char:"\u{1f53a}",fitzpatrick_scale:!1,category:"symbols"},black_small_square:{keywords:["shape","icon"],char:"\u25aa\ufe0f",fitzpatrick_scale:!1,category:"symbols"},white_small_square:{keywords:["shape","icon"],char:"\u25ab\ufe0f",fitzpatrick_scale:!1,category:"symbols"},black_large_square:{keywords:["shape","icon","button"],char:"\u2b1b",fitzpatrick_scale:!1,category:"symbols"},white_large_square:{keywords:["shape","icon","stone","button"],char:"\u2b1c",fitzpatrick_scale:!1,category:"symbols"},small_red_triangle_down:{keywords:["shape","direction","bottom"],char:"\u{1f53b}",fitzpatrick_scale:!1,category:"symbols"},black_medium_square:{keywords:["shape","button","icon"],char:"\u25fc\ufe0f",fitzpatrick_scale:!1,category:"symbols"},white_medium_square:{keywords:["shape","stone","icon"],char:"\u25fb\ufe0f",fitzpatrick_scale:!1,category:"symbols"},black_medium_small_square:{keywords:["icon","shape","button"],char:"\u25fe",fitzpatrick_scale:!1,category:"symbols"},white_medium_small_square:{keywords:["shape","stone","icon","button"],char:"\u25fd",fitzpatrick_scale:!1,category:"symbols"},black_square_button:{keywords:["shape","input","frame"],char:"\u{1f532}",fitzpatrick_scale:!1,category:"symbols"},white_square_button:{keywords:["shape","input"],char:"\u{1f533}",fitzpatrick_scale:!1,category:"symbols"},speaker:{keywords:["sound","volume","silence","broadcast"],char:"\u{1f508}",fitzpatrick_scale:!1,category:"symbols"},sound:{keywords:["volume","speaker","broadcast"],char:"\u{1f509}",fitzpatrick_scale:!1,category:"symbols"},loud_sound:{keywords:["volume","noise","noisy","speaker","broadcast"],char:"\u{1f50a}",fitzpatrick_scale:!1,category:"symbols"},mute:{keywords:["sound","volume","silence","quiet"],char:"\u{1f507}",fitzpatrick_scale:!1,category:"symbols"},mega:{keywords:["sound","speaker","volume"],char:"\u{1f4e3}",fitzpatrick_scale:!1,category:"symbols"},loudspeaker:{keywords:["volume","sound"],char:"\u{1f4e2}",fitzpatrick_scale:!1,category:"symbols"},bell:{keywords:["sound","notification","christmas","xmas","chime"],char:"\u{1f514}",fitzpatrick_scale:!1,category:"symbols"},no_bell:{keywords:["sound","volume","mute","quiet","silent"],char:"\u{1f515}",fitzpatrick_scale:!1,category:"symbols"},black_joker:{keywords:["poker","cards","game","play","magic"],char:"\u{1f0cf}",fitzpatrick_scale:!1,category:"symbols"},mahjong:{keywords:["game","play","chinese","kanji"],char:"\u{1f004}",fitzpatrick_scale:!1,category:"symbols"},spades:{keywords:["poker","cards","suits","magic"],char:"\u2660\ufe0f",fitzpatrick_scale:!1,category:"symbols"},clubs:{keywords:["poker","cards","magic","suits"],char:"\u2663\ufe0f",fitzpatrick_scale:!1,category:"symbols"},hearts:{keywords:["poker","cards","magic","suits"],char:"\u2665\ufe0f",fitzpatrick_scale:!1,category:"symbols"},diamonds:{keywords:["poker","cards","magic","suits"],char:"\u2666\ufe0f",fitzpatrick_scale:!1,category:"symbols"},flower_playing_cards:{keywords:["game","sunset","red"],char:"\u{1f3b4}",fitzpatrick_scale:!1,category:"symbols"},thought_balloon:{keywords:["bubble","cloud","speech","thinking","dream"],char:"\u{1f4ad}",fitzpatrick_scale:!1,category:"symbols"},right_anger_bubble:{keywords:["caption","speech","thinking","mad"],char:"\u{1f5ef}",fitzpatrick_scale:!1,category:"symbols"},speech_balloon:{keywords:["bubble","words","message","talk","chatting"],char:"\u{1f4ac}",fitzpatrick_scale:!1,category:"symbols"},left_speech_bubble:{keywords:["words","message","talk","chatting"],char:"\u{1f5e8}",fitzpatrick_scale:!1,category:"symbols"},clock1:{keywords:["time","late","early","schedule"],char:"\u{1f550}",fitzpatrick_scale:!1,category:"symbols"},clock2:{keywords:["time","late","early","schedule"],char:"\u{1f551}",fitzpatrick_scale:!1,category:"symbols"},clock3:{keywords:["time","late","early","schedule"],char:"\u{1f552}",fitzpatrick_scale:!1,category:"symbols"},clock4:{keywords:["time","late","early","schedule"],char:"\u{1f553}",fitzpatrick_scale:!1,category:"symbols"},clock5:{keywords:["time","late","early","schedule"],char:"\u{1f554}",fitzpatrick_scale:!1,category:"symbols"},clock6:{keywords:["time","late","early","schedule","dawn","dusk"],char:"\u{1f555}",fitzpatrick_scale:!1,category:"symbols"},clock7:{keywords:["time","late","early","schedule"],char:"\u{1f556}",fitzpatrick_scale:!1,category:"symbols"},clock8:{keywords:["time","late","early","schedule"],char:"\u{1f557}",fitzpatrick_scale:!1,category:"symbols"},clock9:{keywords:["time","late","early","schedule"],char:"\u{1f558}",fitzpatrick_scale:!1,category:"symbols"},clock10:{keywords:["time","late","early","schedule"],char:"\u{1f559}",fitzpatrick_scale:!1,category:"symbols"},clock11:{keywords:["time","late","early","schedule"],char:"\u{1f55a}",fitzpatrick_scale:!1,category:"symbols"},clock12:{keywords:["time","noon","midnight","midday","late","early","schedule"],char:"\u{1f55b}",fitzpatrick_scale:!1,category:"symbols"},clock130:{keywords:["time","late","early","schedule"],char:"\u{1f55c}",fitzpatrick_scale:!1,category:"symbols"},clock230:{keywords:["time","late","early","schedule"],char:"\u{1f55d}",fitzpatrick_scale:!1,category:"symbols"},clock330:{keywords:["time","late","early","schedule"],char:"\u{1f55e}",fitzpatrick_scale:!1,category:"symbols"},clock430:{keywords:["time","late","early","schedule"],char:"\u{1f55f}",fitzpatrick_scale:!1,category:"symbols"},clock530:{keywords:["time","late","early","schedule"],char:"\u{1f560}",fitzpatrick_scale:!1,category:"symbols"},clock630:{keywords:["time","late","early","schedule"],char:"\u{1f561}",fitzpatrick_scale:!1,category:"symbols"},clock730:{keywords:["time","late","early","schedule"],char:"\u{1f562}",fitzpatrick_scale:!1,category:"symbols"},clock830:{keywords:["time","late","early","schedule"],char:"\u{1f563}",fitzpatrick_scale:!1,category:"symbols"},clock930:{keywords:["time","late","early","schedule"],char:"\u{1f564}",fitzpatrick_scale:!1,category:"symbols"},clock1030:{keywords:["time","late","early","schedule"],char:"\u{1f565}",fitzpatrick_scale:!1,category:"symbols"},clock1130:{keywords:["time","late","early","schedule"],char:"\u{1f566}",fitzpatrick_scale:!1,category:"symbols"},clock1230:{keywords:["time","late","early","schedule"],char:"\u{1f567}",fitzpatrick_scale:!1,category:"symbols"},afghanistan:{keywords:["af","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1eb}",fitzpatrick_scale:!1,category:"flags"},aland_islands:{keywords:["\xc5land","islands","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1fd}",fitzpatrick_scale:!1,category:"flags"},albania:{keywords:["al","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},algeria:{keywords:["dz","flag","nation","country","banner"],char:"\u{1f1e9}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},american_samoa:{keywords:["american","ws","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},andorra:{keywords:["ad","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1e9}",fitzpatrick_scale:!1,category:"flags"},angola:{keywords:["ao","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},anguilla:{keywords:["ai","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},antarctica:{keywords:["aq","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1f6}",fitzpatrick_scale:!1,category:"flags"},antigua_barbuda:{keywords:["antigua","barbuda","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},argentina:{keywords:["ar","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},armenia:{keywords:["am","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},aruba:{keywords:["aw","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},australia:{keywords:["au","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},austria:{keywords:["at","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},azerbaijan:{keywords:["az","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},bahamas:{keywords:["bs","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},bahrain:{keywords:["bh","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1ed}",fitzpatrick_scale:!1,category:"flags"},bangladesh:{keywords:["bd","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1e9}",fitzpatrick_scale:!1,category:"flags"},barbados:{keywords:["bb","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1e7}",fitzpatrick_scale:!1,category:"flags"},belarus:{keywords:["by","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1fe}",fitzpatrick_scale:!1,category:"flags"},belgium:{keywords:["be","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},belize:{keywords:["bz","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},benin:{keywords:["bj","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1ef}",fitzpatrick_scale:!1,category:"flags"},bermuda:{keywords:["bm","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},bhutan:{keywords:["bt","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},bolivia:{keywords:["bo","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},caribbean_netherlands:{keywords:["bonaire","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1f6}",fitzpatrick_scale:!1,category:"flags"},bosnia_herzegovina:{keywords:["bosnia","herzegovina","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},botswana:{keywords:["bw","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},brazil:{keywords:["br","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},british_indian_ocean_territory:{keywords:["british","indian","ocean","territory","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},british_virgin_islands:{keywords:["british","virgin","islands","bvi","flag","nation","country","banner"],char:"\u{1f1fb}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},brunei:{keywords:["bn","darussalam","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},bulgaria:{keywords:["bg","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},burkina_faso:{keywords:["burkina","faso","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1eb}",fitzpatrick_scale:!1,category:"flags"},burundi:{keywords:["bi","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},cape_verde:{keywords:["cabo","verde","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1fb}",fitzpatrick_scale:!1,category:"flags"},cambodia:{keywords:["kh","flag","nation","country","banner"],char:"\u{1f1f0}\u{1f1ed}",fitzpatrick_scale:!1,category:"flags"},cameroon:{keywords:["cm","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},canada:{keywords:["ca","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},canary_islands:{keywords:["canary","islands","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1e8}",fitzpatrick_scale:!1,category:"flags"},cayman_islands:{keywords:["cayman","islands","flag","nation","country","banner"],char:"\u{1f1f0}\u{1f1fe}",fitzpatrick_scale:!1,category:"flags"},central_african_republic:{keywords:["central","african","republic","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1eb}",fitzpatrick_scale:!1,category:"flags"},chad:{keywords:["td","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1e9}",fitzpatrick_scale:!1,category:"flags"},chile:{keywords:["flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},cn:{keywords:["china","chinese","prc","flag","country","nation","banner"],char:"\u{1f1e8}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},christmas_island:{keywords:["christmas","island","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1fd}",fitzpatrick_scale:!1,category:"flags"},cocos_islands:{keywords:["cocos","keeling","islands","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1e8}",fitzpatrick_scale:!1,category:"flags"},colombia:{keywords:["co","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},comoros:{keywords:["km","flag","nation","country","banner"],char:"\u{1f1f0}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},congo_brazzaville:{keywords:["congo","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},congo_kinshasa:{keywords:["congo","democratic","republic","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1e9}",fitzpatrick_scale:!1,category:"flags"},cook_islands:{keywords:["cook","islands","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},costa_rica:{keywords:["costa","rica","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},croatia:{keywords:["hr","flag","nation","country","banner"],char:"\u{1f1ed}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},cuba:{keywords:["cu","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},curacao:{keywords:["cura\xe7ao","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},cyprus:{keywords:["cy","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1fe}",fitzpatrick_scale:!1,category:"flags"},czech_republic:{keywords:["cz","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},denmark:{keywords:["dk","flag","nation","country","banner"],char:"\u{1f1e9}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},djibouti:{keywords:["dj","flag","nation","country","banner"],char:"\u{1f1e9}\u{1f1ef}",fitzpatrick_scale:!1,category:"flags"},dominica:{keywords:["dm","flag","nation","country","banner"],char:"\u{1f1e9}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},dominican_republic:{keywords:["dominican","republic","flag","nation","country","banner"],char:"\u{1f1e9}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},ecuador:{keywords:["ec","flag","nation","country","banner"],char:"\u{1f1ea}\u{1f1e8}",fitzpatrick_scale:!1,category:"flags"},egypt:{keywords:["eg","flag","nation","country","banner"],char:"\u{1f1ea}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},el_salvador:{keywords:["el","salvador","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1fb}",fitzpatrick_scale:!1,category:"flags"},equatorial_guinea:{keywords:["equatorial","gn","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1f6}",fitzpatrick_scale:!1,category:"flags"},eritrea:{keywords:["er","flag","nation","country","banner"],char:"\u{1f1ea}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},estonia:{keywords:["ee","flag","nation","country","banner"],char:"\u{1f1ea}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},ethiopia:{keywords:["et","flag","nation","country","banner"],char:"\u{1f1ea}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},eu:{keywords:["european","union","flag","banner"],char:"\u{1f1ea}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},falkland_islands:{keywords:["falkland","islands","malvinas","flag","nation","country","banner"],char:"\u{1f1eb}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},faroe_islands:{keywords:["faroe","islands","flag","nation","country","banner"],char:"\u{1f1eb}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},fiji:{keywords:["fj","flag","nation","country","banner"],char:"\u{1f1eb}\u{1f1ef}",fitzpatrick_scale:!1,category:"flags"},finland:{keywords:["fi","flag","nation","country","banner"],char:"\u{1f1eb}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},fr:{keywords:["banner","flag","nation","france","french","country"],char:"\u{1f1eb}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},french_guiana:{keywords:["french","guiana","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1eb}",fitzpatrick_scale:!1,category:"flags"},french_polynesia:{keywords:["french","polynesia","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1eb}",fitzpatrick_scale:!1,category:"flags"},french_southern_territories:{keywords:["french","southern","territories","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1eb}",fitzpatrick_scale:!1,category:"flags"},gabon:{keywords:["ga","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},gambia:{keywords:["gm","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},georgia:{keywords:["ge","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},de:{keywords:["german","nation","flag","country","banner"],char:"\u{1f1e9}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},ghana:{keywords:["gh","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1ed}",fitzpatrick_scale:!1,category:"flags"},gibraltar:{keywords:["gi","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},greece:{keywords:["gr","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},greenland:{keywords:["gl","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},grenada:{keywords:["gd","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1e9}",fitzpatrick_scale:!1,category:"flags"},guadeloupe:{keywords:["gp","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1f5}",fitzpatrick_scale:!1,category:"flags"},guam:{keywords:["gu","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},guatemala:{keywords:["gt","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},guernsey:{keywords:["gg","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},guinea:{keywords:["gn","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},guinea_bissau:{keywords:["gw","bissau","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},guyana:{keywords:["gy","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1fe}",fitzpatrick_scale:!1,category:"flags"},haiti:{keywords:["ht","flag","nation","country","banner"],char:"\u{1f1ed}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},honduras:{keywords:["hn","flag","nation","country","banner"],char:"\u{1f1ed}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},hong_kong:{keywords:["hong","kong","flag","nation","country","banner"],char:"\u{1f1ed}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},hungary:{keywords:["hu","flag","nation","country","banner"],char:"\u{1f1ed}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},iceland:{keywords:["is","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},india:{keywords:["in","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},indonesia:{keywords:["flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1e9}",fitzpatrick_scale:!1,category:"flags"},iran:{keywords:["iran,","islamic","republic","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},iraq:{keywords:["iq","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1f6}",fitzpatrick_scale:!1,category:"flags"},ireland:{keywords:["ie","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},isle_of_man:{keywords:["isle","man","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},israel:{keywords:["il","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},it:{keywords:["italy","flag","nation","country","banner"],char:"\u{1f1ee}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},cote_divoire:{keywords:["ivory","coast","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},jamaica:{keywords:["jm","flag","nation","country","banner"],char:"\u{1f1ef}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},jp:{keywords:["japanese","nation","flag","country","banner"],char:"\u{1f1ef}\u{1f1f5}",fitzpatrick_scale:!1,category:"flags"},jersey:{keywords:["je","flag","nation","country","banner"],char:"\u{1f1ef}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},jordan:{keywords:["jo","flag","nation","country","banner"],char:"\u{1f1ef}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},kazakhstan:{keywords:["kz","flag","nation","country","banner"],char:"\u{1f1f0}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},kenya:{keywords:["ke","flag","nation","country","banner"],char:"\u{1f1f0}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},kiribati:{keywords:["ki","flag","nation","country","banner"],char:"\u{1f1f0}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},kosovo:{keywords:["xk","flag","nation","country","banner"],char:"\u{1f1fd}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},kuwait:{keywords:["kw","flag","nation","country","banner"],char:"\u{1f1f0}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},kyrgyzstan:{keywords:["kg","flag","nation","country","banner"],char:"\u{1f1f0}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},laos:{keywords:["lao","democratic","republic","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},latvia:{keywords:["lv","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1fb}",fitzpatrick_scale:!1,category:"flags"},lebanon:{keywords:["lb","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1e7}",fitzpatrick_scale:!1,category:"flags"},lesotho:{keywords:["ls","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},liberia:{keywords:["lr","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},libya:{keywords:["ly","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1fe}",fitzpatrick_scale:!1,category:"flags"},liechtenstein:{keywords:["li","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},lithuania:{keywords:["lt","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},luxembourg:{keywords:["lu","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},macau:{keywords:["macao","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},macedonia:{keywords:["macedonia,","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},madagascar:{keywords:["mg","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},malawi:{keywords:["mw","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},malaysia:{keywords:["my","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1fe}",fitzpatrick_scale:!1,category:"flags"},maldives:{keywords:["mv","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1fb}",fitzpatrick_scale:!1,category:"flags"},mali:{keywords:["ml","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},malta:{keywords:["mt","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},marshall_islands:{keywords:["marshall","islands","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1ed}",fitzpatrick_scale:!1,category:"flags"},martinique:{keywords:["mq","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f6}",fitzpatrick_scale:!1,category:"flags"},mauritania:{keywords:["mr","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},mauritius:{keywords:["mu","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},mayotte:{keywords:["yt","flag","nation","country","banner"],char:"\u{1f1fe}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},mexico:{keywords:["mx","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1fd}",fitzpatrick_scale:!1,category:"flags"},micronesia:{keywords:["micronesia,","federated","states","flag","nation","country","banner"],char:"\u{1f1eb}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},moldova:{keywords:["moldova,","republic","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1e9}",fitzpatrick_scale:!1,category:"flags"},monaco:{keywords:["mc","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1e8}",fitzpatrick_scale:!1,category:"flags"},mongolia:{keywords:["mn","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},montenegro:{keywords:["me","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},montserrat:{keywords:["ms","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},morocco:{keywords:["ma","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},mozambique:{keywords:["mz","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},myanmar:{keywords:["mm","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},namibia:{keywords:["na","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},nauru:{keywords:["nr","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},nepal:{keywords:["np","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1f5}",fitzpatrick_scale:!1,category:"flags"},netherlands:{keywords:["nl","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},new_caledonia:{keywords:["new","caledonia","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1e8}",fitzpatrick_scale:!1,category:"flags"},new_zealand:{keywords:["new","zealand","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},nicaragua:{keywords:["ni","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},niger:{keywords:["ne","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},nigeria:{keywords:["flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},niue:{keywords:["nu","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},norfolk_island:{keywords:["norfolk","island","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1eb}",fitzpatrick_scale:!1,category:"flags"},northern_mariana_islands:{keywords:["northern","mariana","islands","flag","nation","country","banner"],char:"\u{1f1f2}\u{1f1f5}",fitzpatrick_scale:!1,category:"flags"},north_korea:{keywords:["north","korea","nation","flag","country","banner"],char:"\u{1f1f0}\u{1f1f5}",fitzpatrick_scale:!1,category:"flags"},norway:{keywords:["no","flag","nation","country","banner"],char:"\u{1f1f3}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},oman:{keywords:["om_symbol","flag","nation","country","banner"],char:"\u{1f1f4}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},pakistan:{keywords:["pk","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},palau:{keywords:["pw","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},palestinian_territories:{keywords:["palestine","palestinian","territories","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},panama:{keywords:["pa","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},papua_new_guinea:{keywords:["papua","new","guinea","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},paraguay:{keywords:["py","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1fe}",fitzpatrick_scale:!1,category:"flags"},peru:{keywords:["pe","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},philippines:{keywords:["ph","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1ed}",fitzpatrick_scale:!1,category:"flags"},pitcairn_islands:{keywords:["pitcairn","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},poland:{keywords:["pl","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},portugal:{keywords:["pt","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},puerto_rico:{keywords:["puerto","rico","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},qatar:{keywords:["qa","flag","nation","country","banner"],char:"\u{1f1f6}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},reunion:{keywords:["r\xe9union","flag","nation","country","banner"],char:"\u{1f1f7}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},romania:{keywords:["ro","flag","nation","country","banner"],char:"\u{1f1f7}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},ru:{keywords:["russian","federation","flag","nation","country","banner"],char:"\u{1f1f7}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},rwanda:{keywords:["rw","flag","nation","country","banner"],char:"\u{1f1f7}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},st_barthelemy:{keywords:["saint","barth\xe9lemy","flag","nation","country","banner"],char:"\u{1f1e7}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},st_helena:{keywords:["saint","helena","ascension","tristan","cunha","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1ed}",fitzpatrick_scale:!1,category:"flags"},st_kitts_nevis:{keywords:["saint","kitts","nevis","flag","nation","country","banner"],char:"\u{1f1f0}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},st_lucia:{keywords:["saint","lucia","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1e8}",fitzpatrick_scale:!1,category:"flags"},st_pierre_miquelon:{keywords:["saint","pierre","miquelon","flag","nation","country","banner"],char:"\u{1f1f5}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},st_vincent_grenadines:{keywords:["saint","vincent","grenadines","flag","nation","country","banner"],char:"\u{1f1fb}\u{1f1e8}",fitzpatrick_scale:!1,category:"flags"},samoa:{keywords:["ws","flag","nation","country","banner"],char:"\u{1f1fc}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},san_marino:{keywords:["san","marino","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},sao_tome_principe:{keywords:["sao","tome","principe","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},saudi_arabia:{keywords:["flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},senegal:{keywords:["sn","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},serbia:{keywords:["rs","flag","nation","country","banner"],char:"\u{1f1f7}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},seychelles:{keywords:["sc","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1e8}",fitzpatrick_scale:!1,category:"flags"},sierra_leone:{keywords:["sierra","leone","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},singapore:{keywords:["sg","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},sint_maarten:{keywords:["sint","maarten","dutch","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1fd}",fitzpatrick_scale:!1,category:"flags"},slovakia:{keywords:["sk","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},slovenia:{keywords:["si","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},solomon_islands:{keywords:["solomon","islands","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1e7}",fitzpatrick_scale:!1,category:"flags"},somalia:{keywords:["so","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},south_africa:{keywords:["south","africa","flag","nation","country","banner"],char:"\u{1f1ff}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},south_georgia_south_sandwich_islands:{keywords:["south","georgia","sandwich","islands","flag","nation","country","banner"],char:"\u{1f1ec}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},kr:{keywords:["south","korea","nation","flag","country","banner"],char:"\u{1f1f0}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},south_sudan:{keywords:["south","sd","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},es:{keywords:["spain","flag","nation","country","banner"],char:"\u{1f1ea}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},sri_lanka:{keywords:["sri","lanka","flag","nation","country","banner"],char:"\u{1f1f1}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},sudan:{keywords:["sd","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1e9}",fitzpatrick_scale:!1,category:"flags"},suriname:{keywords:["sr","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},swaziland:{keywords:["sz","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},sweden:{keywords:["se","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},switzerland:{keywords:["ch","flag","nation","country","banner"],char:"\u{1f1e8}\u{1f1ed}",fitzpatrick_scale:!1,category:"flags"},syria:{keywords:["syrian","arab","republic","flag","nation","country","banner"],char:"\u{1f1f8}\u{1f1fe}",fitzpatrick_scale:!1,category:"flags"},taiwan:{keywords:["tw","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},tajikistan:{keywords:["tj","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1ef}",fitzpatrick_scale:!1,category:"flags"},tanzania:{keywords:["tanzania,","united","republic","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},thailand:{keywords:["th","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1ed}",fitzpatrick_scale:!1,category:"flags"},timor_leste:{keywords:["timor","leste","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1f1}",fitzpatrick_scale:!1,category:"flags"},togo:{keywords:["tg","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},tokelau:{keywords:["tk","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1f0}",fitzpatrick_scale:!1,category:"flags"},tonga:{keywords:["to","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1f4}",fitzpatrick_scale:!1,category:"flags"},trinidad_tobago:{keywords:["trinidad","tobago","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1f9}",fitzpatrick_scale:!1,category:"flags"},tunisia:{keywords:["tn","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},tr:{keywords:["turkey","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1f7}",fitzpatrick_scale:!1,category:"flags"},turkmenistan:{keywords:["flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},turks_caicos_islands:{keywords:["turks","caicos","islands","flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1e8}",fitzpatrick_scale:!1,category:"flags"},tuvalu:{keywords:["flag","nation","country","banner"],char:"\u{1f1f9}\u{1f1fb}",fitzpatrick_scale:!1,category:"flags"},uganda:{keywords:["ug","flag","nation","country","banner"],char:"\u{1f1fa}\u{1f1ec}",fitzpatrick_scale:!1,category:"flags"},ukraine:{keywords:["ua","flag","nation","country","banner"],char:"\u{1f1fa}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},united_arab_emirates:{keywords:["united","arab","emirates","flag","nation","country","banner"],char:"\u{1f1e6}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},uk:{keywords:["united","kingdom","great","britain","northern","ireland","flag","nation","country","banner","british","UK","english","england","union jack"],char:"\u{1f1ec}\u{1f1e7}",fitzpatrick_scale:!1,category:"flags"},england:{keywords:["flag","english"],char:"\u{1f3f4}\u{e0067}\u{e0062}\u{e0065}\u{e006e}\u{e0067}\u{e007f}",fitzpatrick_scale:!1,category:"flags"},scotland:{keywords:["flag","scottish"],char:"\u{1f3f4}\u{e0067}\u{e0062}\u{e0073}\u{e0063}\u{e0074}\u{e007f}",fitzpatrick_scale:!1,category:"flags"},wales:{keywords:["flag","welsh"],char:"\u{1f3f4}\u{e0067}\u{e0062}\u{e0077}\u{e006c}\u{e0073}\u{e007f}",fitzpatrick_scale:!1,category:"flags"},us:{keywords:["united","states","america","flag","nation","country","banner"],char:"\u{1f1fa}\u{1f1f8}",fitzpatrick_scale:!1,category:"flags"},us_virgin_islands:{keywords:["virgin","islands","us","flag","nation","country","banner"],char:"\u{1f1fb}\u{1f1ee}",fitzpatrick_scale:!1,category:"flags"},uruguay:{keywords:["uy","flag","nation","country","banner"],char:"\u{1f1fa}\u{1f1fe}",fitzpatrick_scale:!1,category:"flags"},uzbekistan:{keywords:["uz","flag","nation","country","banner"],char:"\u{1f1fa}\u{1f1ff}",fitzpatrick_scale:!1,category:"flags"},vanuatu:{keywords:["vu","flag","nation","country","banner"],char:"\u{1f1fb}\u{1f1fa}",fitzpatrick_scale:!1,category:"flags"},vatican_city:{keywords:["vatican","city","flag","nation","country","banner"],char:"\u{1f1fb}\u{1f1e6}",fitzpatrick_scale:!1,category:"flags"},venezuela:{keywords:["ve","bolivarian","republic","flag","nation","country","banner"],char:"\u{1f1fb}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},vietnam:{keywords:["viet","nam","flag","nation","country","banner"],char:"\u{1f1fb}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},wallis_futuna:{keywords:["wallis","futuna","flag","nation","country","banner"],char:"\u{1f1fc}\u{1f1eb}",fitzpatrick_scale:!1,category:"flags"},western_sahara:{keywords:["western","sahara","flag","nation","country","banner"],char:"\u{1f1ea}\u{1f1ed}",fitzpatrick_scale:!1,category:"flags"},yemen:{keywords:["ye","flag","nation","country","banner"],char:"\u{1f1fe}\u{1f1ea}",fitzpatrick_scale:!1,category:"flags"},zambia:{keywords:["zm","flag","nation","country","banner"],char:"\u{1f1ff}\u{1f1f2}",fitzpatrick_scale:!1,category:"flags"},zimbabwe:{keywords:["zw","flag","nation","country","banner"],char:"\u{1f1ff}\u{1f1fc}",fitzpatrick_scale:!1,category:"flags"},united_nations:{keywords:["un","flag","banner"],char:"\u{1f1fa}\u{1f1f3}",fitzpatrick_scale:!1,category:"flags"},pirate_flag:{keywords:["skull","crossbones","flag","banner"],char:"\u{1f3f4}\u200d\u2620\ufe0f",fitzpatrick_scale:!1,category:"flags"}}); \ No newline at end of file diff --git a/static/js/tinymce/plugins/emoticons/plugin.min.js b/static/js/tinymce/plugins/emoticons/plugin.min.js new file mode 100644 index 0000000..d7d2aaf --- /dev/null +++ b/static/js/tinymce/plugins/emoticons/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.2.0 (2022-09-08) + */ +!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=t=>e=>t===e,o=e(null),n=e(void 0),s=()=>{},r=()=>!1;class a{constructor(t,e){this.tag=t,this.value=e}static some(t){return new a(!0,t)}static none(){return a.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?a.some(t(this.value)):a.none()}bind(t){return this.tag?t(this.value):a.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:a.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return null==t?a.none():a.some(t)}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}a.singletonNone=new a(!1);const i=(t,e)=>{const o=t.length,n=new Array(o);for(let s=0;s{let e=t;return{get:()=>e,set:t=>{e=t}}},c=Object.keys,u=Object.hasOwnProperty,g=(t,e)=>{const o=c(t);for(let n=0,s=o.length;nu.call(t,e),h=(d=(t,e)=>e,(...t)=>{if(0===t.length)throw new Error("Can't merge zero objects");const e={};for(let o=0;o{const t=(t=>{const e=l(a.none()),o=()=>e.get().each(t);return{clear:()=>{o(),e.set(a.none())},isSet:()=>e.get().isSome(),get:()=>e.get(),set:t=>{o(),e.set(a.some(t))}}})(s);return{...t,on:e=>t.get().each(e)}},v=(t,e,o=0,s)=>{const r=t.indexOf(e,o);return-1!==r&&(!!n(s)||r+e.length<=s)};var y=tinymce.util.Tools.resolve("tinymce.Resource");const f=t=>e=>e.options.get(t),b=f("emoticons_database"),w=f("emoticons_database_url"),_=f("emoticons_database_id"),j=f("emoticons_append"),C=f("emoticons_images_url"),k="All",A={symbols:"Symbols",people:"People",animals_and_nature:"Animals and Nature",food_and_drink:"Food and Drink",activity:"Activity",travel_and_places:"Travel and Places",objects:"Objects",flags:"Flags",user:"User Defined"},O=(t,e)=>m(t,e)?t[e]:e,x=t=>{const e=j(t);return o=t=>({keywords:[],category:"user",...t}),((t,e)=>{const o={};return g(t,((t,n)=>{const s=e(t,n);o[s.k]=s.v})),o})(e,((t,e)=>({k:e,v:o(t)})));var o},L=(t,e)=>v(t.title.toLowerCase(),e)||((t,o)=>{for(let o=0,s=t.length;o{const n=[],s=e.toLowerCase(),a=o.fold((()=>r),(t=>e=>e>=t));for(let o=0;o{const n={pattern:"",results:T(e.listAll(),"",a.some(300))},s=l(k),r=((t,e)=>{let n=null;const s=()=>{o(n)||(clearTimeout(n),n=null)};return{cancel:s,throttle:(...e)=>{s(),n=setTimeout((()=>{n=null,t.apply(null,e)}),200)}}})((t=>{(t=>{const o=t.getData(),n=s.get(),r=e.listCategory(n),i=T(r,o.pattern,n===k?a.some(300):a.none());t.setData({results:i})})(t)})),c={label:"Search",type:"input",name:D},u={type:"collection",name:"results"},g=()=>({title:"Emojis",size:"normal",body:{type:"tabpanel",tabs:i(e.listCategories(),(t=>({title:t,name:t,items:[c,u]})))},initialData:n,onTabChange:(t,e)=>{s.set(e.newTabName),r.throttle(t)},onChange:r.throttle,onAction:(e,o)=>{"results"===o.name&&(((t,e)=>{t.insertContent(e)})(t,o.value),e.close())},buttons:[{type:"cancel",text:"Close",primary:!0}]}),m=t.windowManager.open(g());m.focus(D),e.hasLoaded()||(m.block("Loading emojis..."),e.waitForLoad().then((()=>{m.redial(g()),r.throttle(m),m.focus(D),m.unblock()})).catch((t=>{m.redial({title:"Emojis",body:{type:"panel",items:[{type:"alertbanner",level:"error",icon:"warning",text:"Could not load emojis"}]},buttons:[{type:"cancel",text:"Close",primary:!0}],initialData:{pattern:"",results:[]}}),m.focus(D),m.unblock()})))};t.add("emoticons",((t,e)=>{((t,e)=>{const o=t.options.register;o("emoticons_database",{processor:"string",default:"emojis"}),o("emoticons_database_url",{processor:"string",default:`${e}/js/${b(t)}${t.suffix}.js`}),o("emoticons_database_id",{processor:"string",default:"tinymce.plugins.emoticons"}),o("emoticons_append",{processor:"object",default:{}}),o("emoticons_images_url",{processor:"string",default:"https://twemoji.maxcdn.com/v/13.0.1/72x72/"})})(t,e);const o=((t,e,o)=>{const n=p(),s=p(),r=C(t),i=t=>{return o="=o.length&&e.substr(0,0+o.length)===o?t.char.replace(/src="([^"]+)"/,((t,e)=>`src="${r}${e}"`)):t.char;var e,o};t.on("init",(()=>{y.load(o,e).then((e=>{const o=x(t);(t=>{const e={},o=[];g(t,((t,n)=>{const s={title:n,keywords:t.keywords,char:i(t),category:O(A,t.category)},r=void 0!==e[s.category]?e[s.category]:[];e[s.category]=r.concat([s]),o.push(s)})),n.set(e),s.set(o)})(h(e,o))}),(t=>{console.log(`Failed to load emojis: ${t}`),n.set({}),s.set([])}))}));const l=()=>s.get().getOr([]),u=()=>n.isSet()&&s.isSet();return{listCategories:()=>[k].concat(c(n.get().getOr({}))),hasLoaded:u,waitForLoad:()=>u()?Promise.resolve(!0):new Promise(((t,o)=>{let n=15;const s=setInterval((()=>{u()?(clearInterval(s),t(!0)):(n--,n<0&&(console.log("Could not load emojis from url: "+e),clearInterval(s),o(!1)))}),100)})),listAll:l,listCategory:t=>t===k?l():n.get().bind((e=>a.from(e[t]))).getOr([])}})(t,w(t),_(t));((t,e)=>{t.addCommand("mceEmoticons",(()=>E(t,e)))})(t,o),(t=>{const e=()=>t.execCommand("mceEmoticons");t.ui.registry.addButton("emoticons",{tooltip:"Emojis",icon:"emoji",onAction:e}),t.ui.registry.addMenuItem("emoticons",{text:"Emojis...",icon:"emoji",onAction:e})})(t),((t,e)=>{t.ui.registry.addAutocompleter("emoticons",{trigger:":",columns:"auto",minChars:2,fetch:(t,o)=>e.waitForLoad().then((()=>{const n=e.listAll();return T(n,t,a.some(o))})),onAction:(e,o,n)=>{t.selection.setRng(o),t.insertContent(n),e.hide()}})})(t,o),(t=>{t.on("PreInit",(()=>{t.parser.addAttributeFilter("data-emoticon",(t=>{((t,e)=>{for(let e=0,n=t.length;e{let t=e;return{get:()=>t,set:e=>{t=e}}};var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const n=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=r=e,(o=String).prototype.isPrototypeOf(n)||(null===(s=r.constructor)||void 0===s?void 0:s.name)===o.name)?"string":t;var n,r,o,s})(t)===e,r=e=>t=>typeof t===e,o=e=>t=>e===t,s=n("string"),i=n("array"),l=o(null),a=r("boolean"),c=o(void 0),u=e=>!(e=>null==e)(e),d=r("function"),m=r("number"),h=()=>{},g=e=>()=>e;function p(e,...t){return(...n)=>{const r=t.concat(n);return e.apply(null,r)}}const f=g(!1),v=g(!0);class w{constructor(e,t){this.tag=e,this.value=t}static some(e){return new w(!0,e)}static none(){return w.singletonNone}fold(e,t){return this.tag?t(this.value):e()}isSome(){return this.tag}isNone(){return!this.tag}map(e){return this.tag?w.some(e(this.value)):w.none()}bind(e){return this.tag?e(this.value):w.none()}exists(e){return this.tag&&e(this.value)}forall(e){return!this.tag||e(this.value)}filter(e){return!this.tag||e(this.value)?this:w.none()}getOr(e){return this.tag?this.value:e}or(e){return this.tag?this:e}getOrThunk(e){return this.tag?this.value:e()}orThunk(e){return this.tag?this:e()}getOrDie(e){if(this.tag)return this.value;throw new Error(null!=e?e:"Called getOrDie on None")}static from(e){return u(e)?w.some(e):w.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(e){this.tag&&e(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}w.singletonNone=new w(!1);const y=t=>{const n=e(w.none()),r=()=>n.get().each(t);return{clear:()=>{r(),n.set(w.none())},isSet:()=>n.get().isSome(),get:()=>n.get(),set:e=>{r(),n.set(w.some(e))}}},b=()=>y((e=>e.unbind())),S=Array.prototype.push,x=(e,t)=>{const n=e.length,r=new Array(n);for(let o=0;o{for(let n=0,r=e.length;n{const n=[];for(let r=0,o=e.length;r((e,t,n)=>{for(let r=0,o=e.length;r{const o=e.indexOf(t,n);return-1!==o&&(!!c(r)||o+t.length<=r)},C=e=>void 0!==e.style&&d(e.style.getPropertyValue),A=e=>{if(null==e)throw new Error("Node cannot be null or undefined");return{dom:e}},R=A;"undefined"!=typeof window?window:Function("return this;")();const L=e=>t=>(e=>e.dom.nodeType)(t)===e,M=L(1),N=L(3),P=L(9),D=L(11),W=(e,t)=>{const n=e.dom;if(1!==n.nodeType)return!1;{const e=n;if(void 0!==e.matches)return e.matches(t);if(void 0!==e.msMatchesSelector)return e.msMatchesSelector(t);if(void 0!==e.webkitMatchesSelector)return e.webkitMatchesSelector(t);if(void 0!==e.mozMatchesSelector)return e.mozMatchesSelector(t);throw new Error("Browser lacks native selectors")}},q=e=>R(e.dom.ownerDocument),H=e=>x(e.dom.childNodes,R),I=d(Element.prototype.attachShadow)&&d(Node.prototype.getRootNode),B=g(I),V=I?e=>R(e.dom.getRootNode()):e=>P(e)?e:q(e),_=e=>{const t=V(e);return D(n=t)&&u(n.dom.host)?w.some(t):w.none();var n},j=e=>R(e.dom.host),z=e=>{const t=N(e)?e.dom.parentNode:e.dom;if(null==t||null===t.ownerDocument)return!1;const n=t.ownerDocument;return _(R(t)).fold((()=>n.body.contains(t)),(r=z,o=j,e=>r(o(e))));var r,o},$=(e,t)=>{const n=e.dom.getAttribute(t);return null===n?void 0:n},U=(e,t)=>{e.dom.removeAttribute(t)},K=(e,t)=>{const n=e.dom;((e,t)=>{const n=T(e);for(let r=0,o=n.length;r{((e,t,n)=>{if(!s(n))throw console.error("Invalid call to CSS.set. Property ",t,":: Value ",n,":: Element ",e),new Error("CSS value must be a string: "+n);C(e)&&e.style.setProperty(t,n)})(n,t,e)}))},X=e=>{const t=R((e=>{if(B()&&u(e.target)){const t=R(e.target);if(M(t)&&u(t.dom.shadowRoot)&&e.composed&&e.composedPath){const t=e.composedPath();if(t)return((e,t)=>0e.stopPropagation(),r=()=>e.preventDefault(),o=(s=r,i=n,(...e)=>s(i.apply(null,e)));var s,i;return((e,t,n,r,o,s,i)=>({target:e,x:t,y:n,stop:r,prevent:o,kill:s,raw:i}))(t,e.clientX,e.clientY,n,r,o,e)},Y=(e,t,n,r)=>{e.dom.removeEventListener(t,n,r)},G=v,J=(e,t,n)=>((e,t,n,r)=>((e,t,n,r,o)=>{const s=((e,t)=>n=>{e(n)&&t(X(n))})(n,r);return e.dom.addEventListener(t,s,o),{unbind:p(Y,e,t,s,o)}})(e,t,n,r,!1))(e,t,G,n),Q=()=>Z(0,0),Z=(e,t)=>({major:e,minor:t}),ee={nu:Z,detect:(e,t)=>{const n=String(t).toLowerCase();return 0===e.length?Q():((e,t)=>{const n=((e,t)=>{for(let n=0;nNumber(t.replace(n,"$"+e));return Z(r(1),r(2))})(e,n)},unknown:Q},te=(e,t)=>{const n=String(t).toLowerCase();return O(e,(e=>e.search(n)))},ne=/.*?version\/\ ?([0-9]+)\.([0-9]+).*/,re=e=>t=>k(t,e),oe=[{name:"Edge",versionRegexes:[/.*?edge\/ ?([0-9]+)\.([0-9]+)$/],search:e=>k(e,"edge/")&&k(e,"chrome")&&k(e,"safari")&&k(e,"applewebkit")},{name:"Chromium",brand:"Chromium",versionRegexes:[/.*?chrome\/([0-9]+)\.([0-9]+).*/,ne],search:e=>k(e,"chrome")&&!k(e,"chromeframe")},{name:"IE",versionRegexes:[/.*?msie\ ?([0-9]+)\.([0-9]+).*/,/.*?rv:([0-9]+)\.([0-9]+).*/],search:e=>k(e,"msie")||k(e,"trident")},{name:"Opera",versionRegexes:[ne,/.*?opera\/([0-9]+)\.([0-9]+).*/],search:re("opera")},{name:"Firefox",versionRegexes:[/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/],search:re("firefox")},{name:"Safari",versionRegexes:[ne,/.*?cpu os ([0-9]+)_([0-9]+).*/],search:e=>(k(e,"safari")||k(e,"mobile/"))&&k(e,"applewebkit")}],se=[{name:"Windows",search:re("win"),versionRegexes:[/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/]},{name:"iOS",search:e=>k(e,"iphone")||k(e,"ipad"),versionRegexes:[/.*?version\/\ ?([0-9]+)\.([0-9]+).*/,/.*cpu os ([0-9]+)_([0-9]+).*/,/.*cpu iphone os ([0-9]+)_([0-9]+).*/]},{name:"Android",search:re("android"),versionRegexes:[/.*?android\ ?([0-9]+)\.([0-9]+).*/]},{name:"macOS",search:re("mac os x"),versionRegexes:[/.*?mac\ os\ x\ ?([0-9]+)_([0-9]+).*/]},{name:"Linux",search:re("linux"),versionRegexes:[]},{name:"Solaris",search:re("sunos"),versionRegexes:[]},{name:"FreeBSD",search:re("freebsd"),versionRegexes:[]},{name:"ChromeOS",search:re("cros"),versionRegexes:[/.*?chrome\/([0-9]+)\.([0-9]+).*/]}],ie={browsers:g(oe),oses:g(se)},le="Edge",ae="Chromium",ce="Opera",ue="Firefox",de="Safari",me=e=>{const t=e.current,n=e.version,r=e=>()=>t===e;return{current:t,version:n,isEdge:r(le),isChromium:r(ae),isIE:r("IE"),isOpera:r(ce),isFirefox:r(ue),isSafari:r(de)}},he=()=>me({current:void 0,version:ee.unknown()}),ge=me,pe=(g(le),g(ae),g("IE"),g(ce),g(ue),g(de),"Windows"),fe="Android",ve="Linux",we="macOS",ye="Solaris",be="FreeBSD",Se="ChromeOS",xe=e=>{const t=e.current,n=e.version,r=e=>()=>t===e;return{current:t,version:n,isWindows:r(pe),isiOS:r("iOS"),isAndroid:r(fe),isMacOS:r(we),isLinux:r(ve),isSolaris:r(ye),isFreeBSD:r(be),isChromeOS:r(Se)}},Ee=()=>xe({current:void 0,version:ee.unknown()}),Fe=xe,Oe=(g(pe),g("iOS"),g(fe),g(ve),g(we),g(ye),g(be),g(Se),(e,t,n)=>{const r=ie.browsers(),o=ie.oses(),s=t.bind((e=>((e,t)=>((e,t)=>{for(let n=0;n{const n=t.brand.toLowerCase();return O(e,(e=>{var t;return n===(null===(t=e.brand)||void 0===t?void 0:t.toLowerCase())})).map((e=>({current:e.name,version:ee.nu(parseInt(t.version,10),0)})))})))(r,e))).orThunk((()=>((e,t)=>te(e,t).map((e=>{const n=ee.detect(e.versionRegexes,t);return{current:e.name,version:n}})))(r,e))).fold(he,ge),i=((e,t)=>te(e,t).map((e=>{const n=ee.detect(e.versionRegexes,t);return{current:e.name,version:n}})))(o,e).fold(Ee,Fe),l=((e,t,n,r)=>{const o=e.isiOS()&&!0===/ipad/i.test(n),s=e.isiOS()&&!o,i=e.isiOS()||e.isAndroid(),l=i||r("(pointer:coarse)"),a=o||!s&&i&&r("(min-device-width:768px)"),c=s||i&&!a,u=t.isSafari()&&e.isiOS()&&!1===/safari/i.test(n),d=!c&&!a&&!u;return{isiPad:g(o),isiPhone:g(s),isTablet:g(a),isPhone:g(c),isTouch:g(l),isAndroid:e.isAndroid,isiOS:e.isiOS,isWebView:g(u),isDesktop:g(d)}})(i,s,e,n);return{browser:s,os:i,deviceType:l}}),Te=e=>window.matchMedia(e).matches;let ke=(e=>{let t,n=!1;return(...r)=>(n||(n=!0,t=e.apply(null,r)),t)})((()=>Oe(navigator.userAgent,w.from(navigator.userAgentData),Te)));const Ce=(e,t)=>({left:e,top:t,translate:(n,r)=>Ce(e+n,t+r)}),Ae=Ce,Re=e=>{const t=void 0===e?window:e;return ke().browser.isFirefox()?w.none():w.from(t.visualViewport)},Le=(e,t,n,r)=>({x:e,y:t,width:n,height:r,right:e+n,bottom:t+r}),Me=e=>{const t=void 0===e?window:e,n=t.document,r=(e=>{const t=void 0!==e?e.dom:document,n=t.body.scrollLeft||t.documentElement.scrollLeft,r=t.body.scrollTop||t.documentElement.scrollTop;return Ae(n,r)})(R(n));return Re(t).fold((()=>{const e=t.document.documentElement,n=e.clientWidth,o=e.clientHeight;return Le(r.left,r.top,n,o)}),(e=>Le(Math.max(e.pageLeft,r.left),Math.max(e.pageTop,r.top),e.width,e.height)))},Ne=(e,t,n)=>Re(n).map((n=>{const r=e=>t(X(e));return n.addEventListener(e,r),{unbind:()=>n.removeEventListener(e,r)}})).getOrThunk((()=>({unbind:h})));var Pe=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),De=tinymce.util.Tools.resolve("tinymce.Env");const We=(e,t)=>{e.dispatch("FullscreenStateChanged",{state:t}),e.dispatch("ResizeEditor")},qe=("fullscreen_native",e=>e.options.get("fullscreen_native"));const He=e=>{return e.dom===(void 0!==(t=q(e).dom).fullscreenElement?t.fullscreenElement:void 0!==t.msFullscreenElement?t.msFullscreenElement:void 0!==t.webkitFullscreenElement?t.webkitFullscreenElement:null);var t},Ie=(e,t,n)=>((e,t,n)=>F(((e,t)=>{const n=d(t)?t:f;let r=e.dom;const o=[];for(;null!==r.parentNode&&void 0!==r.parentNode;){const e=r.parentNode,t=R(e);if(o.push(t),!0===n(t))break;r=e}return o})(e,n),t))(e,(e=>W(e,t)),n),Be=(e,t)=>((e,n)=>{return F((e=>w.from(e.dom.parentNode).map(R))(r=e).map(H).map((e=>F(e,(e=>{return t=e,!(r.dom===t.dom);var t})))).getOr([]),(e=>W(e,t)));var r})(e),Ve="data-ephox-mobile-fullscreen-style",_e="position:absolute!important;",je="top:0!important;left:0!important;margin:0!important;padding:0!important;width:100%!important;height:100%!important;overflow:visible!important;",ze=De.os.isAndroid(),$e=e=>{const t=((e,t)=>{const n=e.dom,r=window.getComputedStyle(n).getPropertyValue(t);return""!==r||z(e)?r:((e,t)=>C(e)?e.style.getPropertyValue(t):"")(n,t)})(e,"background-color");return void 0!==t&&""!==t?"background-color:"+t+"!important":"background-color:rgb(255,255,255)!important;"},Ue=Pe.DOM,Ke=Re().fold((()=>({bind:h,unbind:h})),(e=>{const t=(()=>{const e=y(h);return{...e,on:t=>e.get().each(t)}})(),n=b(),r=b(),o=((e,t)=>{let n=null;return{cancel:()=>{l(n)||(clearTimeout(n),n=null)},throttle:(...t)=>{l(n)&&(n=setTimeout((()=>{n=null,e.apply(null,t)}),50))}}})((()=>{document.body.scrollTop=0,document.documentElement.scrollTop=0,window.requestAnimationFrame((()=>{t.on((t=>K(t,{top:e.offsetTop+"px",left:e.offsetLeft+"px",height:e.height+"px",width:e.width+"px"})))}))}));return{bind:e=>{t.set(e),o.throttle(),n.set(Ne("resize",o.throttle)),r.set(Ne("scroll",o.throttle))},unbind:()=>{t.on((()=>{n.clear(),r.clear()})),t.clear()}}})),Xe=(e,t)=>{const n=document.body,r=document.documentElement,o=e.getContainer(),l=R(o),c=(e=>{const t=R(e.getElement());return _(t).map(j).getOrThunk((()=>(e=>{const t=e.dom.body;if(null==t)throw new Error("Body is not available yet");return R(t)})(q(t))))})(e),u=t.get(),d=R(e.getBody()),h=De.deviceType.isTouch(),g=o.style,p=e.iframeElement,f=null==p?void 0:p.style,v=e=>{e(n,"tox-fullscreen"),e(r,"tox-fullscreen"),e(o,"tox-fullscreen"),_(l).map((e=>j(e).dom)).each((t=>{e(t,"tox-fullscreen"),e(t,"tox-shadowhost")}))},y=()=>{h&&(e=>{const t=((e,t)=>{const n=document;return 1!==(r=n).nodeType&&9!==r.nodeType&&11!==r.nodeType||0===r.childElementCount?[]:x(n.querySelectorAll(e),R);var r})("["+Ve+"]");E(t,(t=>{const n=$(t,Ve);n&&"no-styles"!==n?K(t,e.parseStyle(n)):U(t,"style"),U(t,Ve)}))})(e.dom),v(Ue.removeClass),Ke.unbind(),w.from(t.get()).each((e=>e.fullscreenChangeHandler.unbind()))};if(u)u.fullscreenChangeHandler.unbind(),qe(e)&&He(c)&&(e=>{const t=e.dom;t.exitFullscreen?t.exitFullscreen():t.msExitFullscreen?t.msExitFullscreen():t.webkitCancelFullScreen&&t.webkitCancelFullScreen()})(q(c)),f.width=u.iframeWidth,f.height=u.iframeHeight,g.width=u.containerWidth,g.height=u.containerHeight,g.top=u.containerTop,g.left=u.containerLeft,y(),b=u.scrollPos,window.scrollTo(b.x,b.y),t.set(null),We(e,!1),e.off("remove",y);else{const n=J(q(c),void 0!==document.fullscreenElement?"fullscreenchange":void 0!==document.msFullscreenElement?"MSFullscreenChange":void 0!==document.webkitFullscreenElement?"webkitfullscreenchange":"fullscreenchange",(n=>{qe(e)&&(He(c)||null===t.get()||Xe(e,t))})),r={scrollPos:Me(window),containerWidth:g.width,containerHeight:g.height,containerTop:g.top,containerLeft:g.left,iframeWidth:f.width,iframeHeight:f.height,fullscreenChangeHandler:n};h&&((e,t,n)=>{const r=t=>n=>{const r=$(n,"style"),o=void 0===r?"no-styles":r.trim();o!==t&&(((e,t,n)=>{((e,t,n)=>{if(!(s(n)||a(n)||m(n)))throw console.error("Invalid call to Attribute.set. Key ",t,":: Value ",n,":: Element ",e),new Error("Attribute value was not simple");e.setAttribute(t,n+"")})(e.dom,t,n)})(n,Ve,o),K(n,e.parseStyle(t)))},o=Ie(t,"*"),l=(e=>{const t=[];for(let n=0,r=e.length;nBe(e,"*:not(.tox-silver-sink)")))),c=$e(n);E(l,r("display:none!important;")),E(o,r(_e+je+c)),r((!0===ze?"":_e)+je+c)(t)})(e.dom,l,d),f.width=f.height="100%",g.width=g.height="",v(Ue.addClass),Ke.bind(l),e.on("remove",y),t.set(r),qe(e)&&(e=>{const t=e.dom;t.requestFullscreen?t.requestFullscreen():t.msRequestFullscreen?t.msRequestFullscreen():t.webkitRequestFullScreen&&t.webkitRequestFullScreen()})(c),We(e,!0)}var b},Ye=(e,t)=>n=>{n.setActive(null!==t.get());const r=e=>n.setActive(e.state);return e.on("FullscreenStateChanged",r),()=>e.off("FullscreenStateChanged",r)};t.add("fullscreen",(t=>{const n=e(null);return t.inline||((e=>{(0,e.options.register)("fullscreen_native",{processor:"boolean",default:!1})})(t),((e,t)=>{e.addCommand("mceFullScreen",(()=>{Xe(e,t)}))})(t,n),((e,t)=>{const n=()=>e.execCommand("mceFullScreen");e.ui.registry.addToggleMenuItem("fullscreen",{text:"Fullscreen",icon:"fullscreen",shortcut:"Meta+Shift+F",onAction:n,onSetup:Ye(e,t)}),e.ui.registry.addToggleButton("fullscreen",{tooltip:"Fullscreen",icon:"fullscreen",onAction:n,onSetup:Ye(e,t)})})(t,n),t.addShortcut("Meta+Shift+F","","mceFullScreen")),(e=>({isFullscreen:()=>null!==e.get()}))(n)}))}(); \ No newline at end of file diff --git a/static/js/tinymce/plugins/help/plugin.min.js b/static/js/tinymce/plugins/help/plugin.min.js new file mode 100644 index 0000000..f78120e --- /dev/null +++ b/static/js/tinymce/plugins/help/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.2.0 (2022-09-08) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");let t=0;const n=e=>{const n=(new Date).getTime(),o=Math.floor(1e9*Math.random());return t++,e+"_"+o+t+String(n)},o=e=>t=>t.options.get(e),a=o("help_tabs"),i=o("forced_plugins"),r=("string",e=>"string"===(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=o=e,(a=String).prototype.isPrototypeOf(n)||(null===(i=o.constructor)||void 0===i?void 0:i.name)===a.name)?"string":t;var n,o,a,i})(e));const s=(void 0,e=>undefined===e);const l=e=>"function"==typeof e,c=(!1,()=>false);class u{constructor(e,t){this.tag=e,this.value=t}static some(e){return new u(!0,e)}static none(){return u.singletonNone}fold(e,t){return this.tag?t(this.value):e()}isSome(){return this.tag}isNone(){return!this.tag}map(e){return this.tag?u.some(e(this.value)):u.none()}bind(e){return this.tag?e(this.value):u.none()}exists(e){return this.tag&&e(this.value)}forall(e){return!this.tag||e(this.value)}filter(e){return!this.tag||e(this.value)?this:u.none()}getOr(e){return this.tag?this.value:e}or(e){return this.tag?this:e}getOrThunk(e){return this.tag?this.value:e()}orThunk(e){return this.tag?this:e()}getOrDie(e){if(this.tag)return this.value;throw new Error(null!=e?e:"Called getOrDie on None")}static from(e){return null==e?u.none():u.some(e)}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(e){this.tag&&e(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}u.singletonNone=new u(!1);const m=Array.prototype.slice,h=Array.prototype.indexOf,p=(e,t)=>{const n=e.length,o=new Array(n);for(let a=0;a{const n=[];for(let o=0,a=e.length;o{const n=m.call(e,0);return n.sort(t),n},y=Object.keys,b=Object.hasOwnProperty,k=(e,t)=>b.call(e,t);var v=tinymce.util.Tools.resolve("tinymce.Env");const f=e=>{const t=v.os.isMacOS()||v.os.isiOS(),n=t?{alt:"⌥",ctrl:"⌃",shift:"⇧",meta:"⌘",access:"⌃⌥"}:{meta:"Ctrl ",access:"Shift + Alt "},o=e.split("+"),a=p(o,(e=>{const t=e.toLowerCase().trim();return k(n,t)?n[t]:e}));return t?a.join("").replace(/\s/,""):a.join("+")},w=[{shortcuts:["Meta + B"],action:"Bold"},{shortcuts:["Meta + I"],action:"Italic"},{shortcuts:["Meta + U"],action:"Underline"},{shortcuts:["Meta + A"],action:"Select all"},{shortcuts:["Meta + Y","Meta + Shift + Z"],action:"Redo"},{shortcuts:["Meta + Z"],action:"Undo"},{shortcuts:["Access + 1"],action:"Heading 1"},{shortcuts:["Access + 2"],action:"Heading 2"},{shortcuts:["Access + 3"],action:"Heading 3"},{shortcuts:["Access + 4"],action:"Heading 4"},{shortcuts:["Access + 5"],action:"Heading 5"},{shortcuts:["Access + 6"],action:"Heading 6"},{shortcuts:["Access + 7"],action:"Paragraph"},{shortcuts:["Access + 8"],action:"Div"},{shortcuts:["Access + 9"],action:"Address"},{shortcuts:["Alt + 0"],action:"Open help dialog"},{shortcuts:["Alt + F9"],action:"Focus to menubar"},{shortcuts:["Alt + F10"],action:"Focus to toolbar"},{shortcuts:["Alt + F11"],action:"Focus to element path"},{shortcuts:["Ctrl + F9"],action:"Focus to contextual toolbar"},{shortcuts:["Shift + Enter"],action:"Open popup menu for split buttons"},{shortcuts:["Meta + K"],action:"Insert link (if link plugin activated)"},{shortcuts:["Meta + S"],action:"Save (if save plugin activated)"},{shortcuts:["Meta + F"],action:"Find (if searchreplace plugin activated)"},{shortcuts:["Meta + Shift + F"],action:"Switch to or from fullscreen mode"}],A=()=>({name:"shortcuts",title:"Handy Shortcuts",items:[{type:"table",header:["Action","Shortcut"],cells:p(w,(e=>{const t=p(e.shortcuts,f).join(" or ");return[e.action,t]}))}]});var x=tinymce.util.Tools.resolve("tinymce.util.I18n");const T=p([{key:"advlist",name:"Advanced List"},{key:"anchor",name:"Anchor"},{key:"autolink",name:"Autolink"},{key:"autoresize",name:"Autoresize"},{key:"autosave",name:"Autosave"},{key:"charmap",name:"Character Map"},{key:"code",name:"Code"},{key:"codesample",name:"Code Sample"},{key:"colorpicker",name:"Color Picker"},{key:"directionality",name:"Directionality"},{key:"emoticons",name:"Emoticons"},{key:"fullscreen",name:"Full Screen"},{key:"help",name:"Help"},{key:"image",name:"Image"},{key:"importcss",name:"Import CSS"},{key:"insertdatetime",name:"Insert Date/Time"},{key:"link",name:"Link"},{key:"lists",name:"Lists"},{key:"media",name:"Media"},{key:"nonbreaking",name:"Nonbreaking"},{key:"pagebreak",name:"Page Break"},{key:"preview",name:"Preview"},{key:"quickbars",name:"Quick Toolbars"},{key:"save",name:"Save"},{key:"searchreplace",name:"Search and Replace"},{key:"table",name:"Table"},{key:"template",name:"Template"},{key:"textcolor",name:"Text Color"},{key:"visualblocks",name:"Visual Blocks"},{key:"visualchars",name:"Visual Characters"},{key:"wordcount",name:"Word Count"},{key:"a11ychecker",name:"Accessibility Checker",type:"premium"},{key:"advcode",name:"Advanced Code Editor",type:"premium"},{key:"advtable",name:"Advanced Tables",type:"premium"},{key:"casechange",name:"Case Change",type:"premium"},{key:"checklist",name:"Checklist",type:"premium"},{key:"editimage",name:"Enhanced Image Editing",type:"premium"},{key:"footnotes",name:"Footnotes",type:"premium"},{key:"mediaembed",name:"Enhanced Media Embed",type:"premium",slug:"introduction-to-mediaembed"},{key:"export",name:"Export",type:"premium"},{key:"formatpainter",name:"Format Painter",type:"premium"},{key:"linkchecker",name:"Link Checker",type:"premium"},{key:"mentions",name:"Mentions",type:"premium"},{key:"mergetags",name:"Merge Tags",type:"premium"},{key:"pageembed",name:"Page Embed",type:"premium"},{key:"permanentpen",name:"Permanent Pen",type:"premium"},{key:"powerpaste",name:"PowerPaste",type:"premium",slug:"introduction-to-powerpaste"},{key:"rtc",name:"Real-Time Collaboration",type:"premium",slug:"rtc-introduction"},{key:"tinymcespellchecker",name:"Spell Checker Pro",type:"premium",slug:"introduction-to-tiny-spellchecker"},{key:"autocorrect",name:"Spelling Autocorrect",type:"premium"},{key:"tinycomments",name:"Tiny Comments",type:"premium",slug:"introduction-to-tiny-comments"},{key:"tinydrive",name:"Tiny Drive",type:"premium",slug:"tinydrive-introduction"},{key:"tableofcontents",name:"Table of Contents",type:"premium"}],(e=>({...e,type:e.type||"opensource",slug:e.slug||e.key}))),M=e=>{const t=e=>`${e.name}`,n=(e,n)=>{return(o=T,a=e=>e.key===n,((e,t,n)=>{for(let o=0,a=e.length;o((e,n)=>{const o=e.plugins[n].getMetadata;if(l(o)){const e=o();return{name:e.name,html:t(e)}}return{name:n,html:n}})(e,n)),(e=>{const n="premium"===e.type?`${e.name}*`:e.name;return{name:n,html:t({name:n,url:`https://www.tiny.cloud/docs/tinymce/6/${e.slug}/`})}}));var o,a},o=e=>{const t=(e=>{const t=y(e.plugins),n=i(e);return s(n)?t:d(t,(e=>!(((e,t)=>h.call(e,t))(n,e)>-1)))})(e),o=g(p(t,(t=>n(e,t))),((e,t)=>e.name.localeCompare(t.name))),a=p(o,(e=>"
  • "+e.html+"
  • ")),r=a.length,l=a.join("");return"

    "+x.translate(["Plugins installed ({0}):",r])+"

      "+l+"
    "},a={type:"htmlpanel",presets:"document",html:[(e=>null==e?"":'
    '+o(e)+"
    ")(e),(()=>{const e=d(T,(({type:e})=>"premium"===e)),t=g(p(e,(e=>e.name)),((e,t)=>e.localeCompare(t))),n=p(t,(e=>`
  • ${e}
  • `)).join("");return'

    '+x.translate("Premium plugins:")+"

    "})()].join("")};return{name:"plugins",title:"Plugins",items:[a]}};var C=tinymce.util.Tools.resolve("tinymce.EditorManager");const F=(e,t)=>()=>{const{tabs:o,names:i}=((e,t)=>{const o=A(),i={name:"keyboardnav",title:"Keyboard Navigation",items:[{type:"htmlpanel",presets:"document",html:"

    Editor UI keyboard navigation

    \n\n

    Activating keyboard navigation

    \n\n

    The sections of the outer UI of the editor - the menubar, toolbar, sidebar and footer - are all keyboard navigable. As such, there are multiple ways to activate keyboard navigation:

    \n
      \n
    • Focus the menubar: Alt + F9 (Windows) or ⌥F9 (MacOS)
    • \n
    • Focus the toolbar: Alt + F10 (Windows) or ⌥F10 (MacOS)
    • \n
    • Focus the footer: Alt + F11 (Windows) or ⌥F11 (MacOS)
    • \n
    \n\n

    Focusing the menubar or toolbar will start keyboard navigation at the first item in the menubar or toolbar, which will be highlighted with a gray background. Focusing the footer will start keyboard navigation at the first item in the element path, which will be highlighted with an underline.

    \n\n

    Moving between UI sections

    \n\n

    When keyboard navigation is active, pressing tab will move the focus to the next major section of the UI, where applicable. These sections are:

    \n
      \n
    • the menubar
    • \n
    • each group of the toolbar
    • \n
    • the sidebar
    • \n
    • the element path in the footer
    • \n
    • the wordcount toggle button in the footer
    • \n
    • the branding link in the footer
    • \n
    • the editor resize handle in the footer
    • \n
    \n\n

    Pressing shift + tab will move backwards through the same sections, except when moving from the footer to the toolbar. Focusing the element path then pressing shift + tab will move focus to the first toolbar group, not the last.

    \n\n

    Moving within UI sections

    \n\n

    Keyboard navigation within UI sections can usually be achieved using the left and right arrow keys. This includes:

    \n
      \n
    • moving between menus in the menubar
    • \n
    • moving between buttons in a toolbar group
    • \n
    • moving between items in the element path
    • \n
    \n\n

    In all these UI sections, keyboard navigation will cycle within the section. For example, focusing the last button in a toolbar group then pressing right arrow will move focus to the first item in the same toolbar group.

    \n\n

    Executing buttons

    \n\n

    To execute a button, navigate the selection to the desired button and hit space or enter.

    \n\n

    Opening, navigating and closing menus

    \n\n

    When focusing a menubar button or a toolbar button with a menu, pressing space, enter or down arrow will open the menu. When the menu opens the first item will be selected. To move up or down the menu, press the up or down arrow key respectively. This is the same for submenus, which can also be opened and closed using the left and right arrow keys.

    \n\n

    To close any active menu, hit the escape key. When a menu is closed the selection will be restored to its previous selection. This also works for closing submenus.

    \n\n

    Context toolbars and menus

    \n\n

    To focus an open context toolbar such as the table context toolbar, press Ctrl + F9 (Windows) or ⌃F9 (MacOS).

    \n\n

    Context toolbar navigation is the same as toolbar navigation, and context menu navigation is the same as standard menu navigation.

    \n\n

    Dialog navigation

    \n\n

    There are two types of dialog UIs in TinyMCE: tabbed dialogs and non-tabbed dialogs.

    \n\n

    When a non-tabbed dialog is opened, the first interactive component in the dialog will be focused. Users can navigate between interactive components by pressing tab. This includes any footer buttons. Navigation will cycle back to the first dialog component if tab is pressed while focusing the last component in the dialog. Pressing shift + tab will navigate backwards.

    \n\n

    When a tabbed dialog is opened, the first button in the tab menu is focused. Pressing tab will navigate to the first interactive component in that tab, and will cycle through the tab\u2019s components, the footer buttons, then back to the tab button. To switch to another tab, focus the tab button for the current tab, then use the arrow keys to cycle through the tab buttons.

    "}]},s=M(e),l=(()=>{var e,t;const n='TinyMCE '+(e=C.majorVersion,t=C.minorVersion,(0===e.indexOf("@")?"X.X.X":e+"."+t)+"");return{name:"versions",title:"Version",items:[{type:"htmlpanel",html:"

    "+x.translate(["You are using {0}",n])+"

    ",presets:"document"}]}})(),c={[o.name]:o,[i.name]:i,[s.name]:s,[l.name]:l,...t.get()};return u.from(a(e)).fold((()=>(e=>{const t=y(e),n=t.indexOf("versions");return-1!==n&&(t.splice(n,1),t.push("versions")),{tabs:e,names:t}})(c)),(e=>((e,t)=>{const o={},a=p(e,(e=>{var a;if(r(e))return k(t,e)&&(o[e]=t[e]),e;{const t=null!==(a=e.name)&&void 0!==a?a:n("tab-name");return o[t]=e,t}}));return{tabs:o,names:a}})(e,c)))})(e,t),s={type:"tabpanel",tabs:(e=>{const t=[],n=e=>{t.push(e)};for(let t=0;t{return k(t=o,n=e)?u.from(t[n]):u.none();var t,n})))};e.windowManager.open({title:"Help",size:"medium",body:s,buttons:[{type:"cancel",name:"close",text:"Close",primary:!0}],initialData:{}})};e.add("help",(e=>{const t=(e=>{let t={};return{get:()=>t,set:e=>{t=e}}})(),o=(e=>({addTab:t=>{var o;const a=null!==(o=t.name)&&void 0!==o?o:n("tab-name"),i=e.get();i[a]=t,e.set(i)}}))(t);(e=>{(0,e.options.register)("help_tabs",{processor:"array"})})(e);const a=F(e,t);return((e,t)=>{e.ui.registry.addButton("help",{icon:"help",tooltip:"Help",onAction:t}),e.ui.registry.addMenuItem("help",{text:"Help",icon:"help",shortcut:"Alt+0",onAction:t})})(e,a),((e,t)=>{e.addCommand("mceHelp",t)})(e,a),e.shortcuts.add("Alt+0","Open help dialog","mceHelp"),o}))}(); \ No newline at end of file diff --git a/static/js/tinymce/plugins/image/plugin.min.js b/static/js/tinymce/plugins/image/plugin.min.js new file mode 100644 index 0000000..bdb7823 --- /dev/null +++ b/static/js/tinymce/plugins/image/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.2.0 (2022-09-08) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=Object.getPrototypeOf,a=(e,t,a)=>{var i;return!!a(e,t.prototype)||(null===(i=e.constructor)||void 0===i?void 0:i.name)===t.name},i=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&a(e,String,((e,t)=>t.isPrototypeOf(e)))?"string":t})(t)===e,s=e=>t=>typeof t===e,r=i("string"),o=i("object"),n=e=>((e,i)=>o(e)&&a(e,i,((e,a)=>t(e)===a)))(e,Object),l=i("array"),c=(null,e=>null===e);const m=s("boolean"),d=e=>!(e=>null==e)(e),g=s("function"),u=s("number"),p=()=>{};class h{constructor(e,t){this.tag=e,this.value=t}static some(e){return new h(!0,e)}static none(){return h.singletonNone}fold(e,t){return this.tag?t(this.value):e()}isSome(){return this.tag}isNone(){return!this.tag}map(e){return this.tag?h.some(e(this.value)):h.none()}bind(e){return this.tag?e(this.value):h.none()}exists(e){return this.tag&&e(this.value)}forall(e){return!this.tag||e(this.value)}filter(e){return!this.tag||e(this.value)?this:h.none()}getOr(e){return this.tag?this.value:e}or(e){return this.tag?this:e}getOrThunk(e){return this.tag?this.value:e()}orThunk(e){return this.tag?this:e()}getOrDie(e){if(this.tag)return this.value;throw new Error(null!=e?e:"Called getOrDie on None")}static from(e){return d(e)?h.some(e):h.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(e){this.tag&&e(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}h.singletonNone=new h(!1);const b=Object.keys,v=Object.hasOwnProperty,y=(e,t)=>v.call(e,t),f=Array.prototype.push,w=e=>{const t=[];for(let a=0,i=e.length;a{((e,t,a)=>{if(!(r(a)||m(a)||u(a)))throw console.error("Invalid call to Attribute.set. Key ",t,":: Value ",a,":: Element ",e),new Error("Attribute value was not simple");e.setAttribute(t,a+"")})(e.dom,t,a)},D=e=>{if(null==e)throw new Error("Node cannot be null or undefined");return{dom:e}},_=D;var C=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),I=tinymce.util.Tools.resolve("tinymce.util.URI");const U=e=>e.length>0,x=e=>t=>t.options.get(e),S=x("image_dimensions"),N=x("image_advtab"),T=x("image_uploadtab"),O=x("image_prepend_url"),L=x("image_class_list"),E=x("image_description"),j=x("image_title"),M=x("image_caption"),R=x("image_list"),k=x("a11y_advanced_options"),z=x("automatic_uploads"),P=(e,t)=>Math.max(parseInt(e,10),parseInt(t,10)),B=e=>(e&&(e=e.replace(/px$/,"")),e),F=e=>(e.length>0&&/^[0-9]+$/.test(e)&&(e+="px"),e),H=e=>"IMG"===e.nodeName&&(e.hasAttribute("data-mce-object")||e.hasAttribute("data-mce-placeholder")),G=(e,t)=>{const a=e.options.get;return I.isDomSafe(t,"img",{allow_html_data_urls:a("allow_html_data_urls"),allow_script_urls:a("allow_script_urls"),allow_svg_data_urls:a("allow_svg_data_urls")})},W=C.DOM,$=e=>e.style.marginLeft&&e.style.marginRight&&e.style.marginLeft===e.style.marginRight?B(e.style.marginLeft):"",V=e=>e.style.marginTop&&e.style.marginBottom&&e.style.marginTop===e.style.marginBottom?B(e.style.marginTop):"",K=e=>e.style.borderWidth?B(e.style.borderWidth):"",Z=(e,t)=>{var a;return e.hasAttribute(t)&&null!==(a=e.getAttribute(t))&&void 0!==a?a:""},q=e=>null!==e.parentNode&&"FIGURE"===e.parentNode.nodeName,J=(e,t,a)=>{""===a||null===a?e.removeAttribute(t):e.setAttribute(t,a)},Q=(e,t)=>{const a=e.getAttribute("style"),i=t(null!==a?a:"");i.length>0?(e.setAttribute("style",i),e.setAttribute("data-mce-style",i)):e.removeAttribute("style")},X=(e,t)=>(e,a,i)=>{const s=e.style;s[a]?(s[a]=F(i),Q(e,t)):J(e,a,i)},Y=(e,t)=>e.style[t]?B(e.style[t]):Z(e,t),ee=(e,t)=>{const a=F(t);e.style.marginLeft=a,e.style.marginRight=a},te=(e,t)=>{const a=F(t);e.style.marginTop=a,e.style.marginBottom=a},ae=(e,t)=>{const a=F(t);e.style.borderWidth=a},ie=(e,t)=>{e.style.borderStyle=t},se=e=>{var t;return null!==(t=e.style.borderStyle)&&void 0!==t?t:""},re=e=>d(e)&&"FIGURE"===e.nodeName,oe=e=>0===W.getAttrib(e,"alt").length&&"presentation"===W.getAttrib(e,"role"),ne=e=>oe(e)?"":Z(e,"alt"),le=(e,t)=>{var a;const i=document.createElement("img");return J(i,"style",t.style),($(i)||""!==t.hspace)&&ee(i,t.hspace),(V(i)||""!==t.vspace)&&te(i,t.vspace),(K(i)||""!==t.border)&&ae(i,t.border),(se(i)||""!==t.borderStyle)&&ie(i,t.borderStyle),e(null!==(a=i.getAttribute("style"))&&void 0!==a?a:"")},ce=(e,t)=>({src:Z(t,"src"),alt:ne(t),title:Z(t,"title"),width:Y(t,"width"),height:Y(t,"height"),class:Z(t,"class"),style:e(Z(t,"style")),caption:q(t),hspace:$(t),vspace:V(t),border:K(t),borderStyle:se(t),isDecorative:oe(t)}),me=(e,t,a,i,s)=>{a[i]!==t[i]&&s(e,i,String(a[i]))},de=(e,t,a)=>{if(a){W.setAttrib(e,"role","presentation");const t=_(e);A(t,"alt","")}else{if(c(t)){"alt",_(e).dom.removeAttribute("alt")}else{const a=_(e);A(a,"alt",t)}"presentation"===W.getAttrib(e,"role")&&W.setAttrib(e,"role","")}},ge=(e,t)=>(a,i,s)=>{e(a,s),Q(a,t)},ue=(e,t,a)=>{const i=ce(e,a);me(a,i,t,"caption",((e,t,a)=>(e=>{q(e)?(e=>{const t=e.parentNode;d(t)&&(W.insertAfter(e,t),W.remove(t))})(e):(e=>{const t=W.create("figure",{class:"image"});W.insertAfter(t,e),t.appendChild(e),t.appendChild(W.create("figcaption",{contentEditable:"true"},"Caption")),t.contentEditable="false"})(e)})(e))),me(a,i,t,"src",J),me(a,i,t,"title",J),me(a,i,t,"width",X(0,e)),me(a,i,t,"height",X(0,e)),me(a,i,t,"class",J),me(a,i,t,"style",ge(((e,t)=>J(e,"style",t)),e)),me(a,i,t,"hspace",ge(ee,e)),me(a,i,t,"vspace",ge(te,e)),me(a,i,t,"border",ge(ae,e)),me(a,i,t,"borderStyle",ge(ie,e)),((e,t,a)=>{a.alt===t.alt&&a.isDecorative===t.isDecorative||de(e,a.alt,a.isDecorative)})(a,i,t)},pe=(e,t)=>{const a=(e=>{if(e.margin){const t=String(e.margin).split(" ");switch(t.length){case 1:e["margin-top"]=e["margin-top"]||t[0],e["margin-right"]=e["margin-right"]||t[0],e["margin-bottom"]=e["margin-bottom"]||t[0],e["margin-left"]=e["margin-left"]||t[0];break;case 2:e["margin-top"]=e["margin-top"]||t[0],e["margin-right"]=e["margin-right"]||t[1],e["margin-bottom"]=e["margin-bottom"]||t[0],e["margin-left"]=e["margin-left"]||t[1];break;case 3:e["margin-top"]=e["margin-top"]||t[0],e["margin-right"]=e["margin-right"]||t[1],e["margin-bottom"]=e["margin-bottom"]||t[2],e["margin-left"]=e["margin-left"]||t[1];break;case 4:e["margin-top"]=e["margin-top"]||t[0],e["margin-right"]=e["margin-right"]||t[1],e["margin-bottom"]=e["margin-bottom"]||t[2],e["margin-left"]=e["margin-left"]||t[3]}delete e.margin}return e})(e.dom.styles.parse(t)),i=e.dom.styles.parse(e.dom.styles.serialize(a));return e.dom.styles.serialize(i)},he=e=>{const t=e.selection.getNode(),a=e.dom.getParent(t,"figure.image");return a?e.dom.select("img",a)[0]:t&&("IMG"!==t.nodeName||H(t))?null:t},be=(e,t)=>{var a;const i=e.dom,s=((t,a)=>{const i={};var s;return((e,t,a,i)=>{((e,t)=>{const a=b(e);for(let i=0,s=a.length;i{(t(e,s)?a:i)(e,s)}))})(t,((t,a)=>!e.schema.isValidChild(a,"figure")),(s=i,(e,t)=>{s[t]=e}),p),i})(e.schema.getTextBlockElements()),r=i.getParent(t.parentNode,(e=>{return t=s,a=e.nodeName,y(t,a)&&void 0!==t[a]&&null!==t[a];var t,a}),e.getBody());return r&&null!==(a=i.split(r,t))&&void 0!==a?a:t},ve=(e,t)=>{const a=((t,a)=>{const i=document.createElement("img");if(ue((t=>pe(e,t)),{...a,caption:!1},i),de(i,a.alt,a.isDecorative),a.caption){const e=W.create("figure",{class:"image"});return e.appendChild(i),e.appendChild(W.create("figcaption",{contentEditable:"true"},"Caption")),e.contentEditable="false",e}return i})(0,t);e.dom.setAttrib(a,"data-mce-id","__mcenew"),e.focus(),e.selection.setContent(a.outerHTML);const i=e.dom.select('*[data-mce-id="__mcenew"]')[0];if(e.dom.setAttrib(i,"data-mce-id",null),re(i)){const t=be(e,i);e.selection.select(t)}else e.selection.select(i)},ye=(e,t)=>{const a=he(e);if(a){const i={...ce((t=>pe(e,t)),a),...t},s=((e,t)=>{const a=t.src;return{...t,src:G(e,a)?a:""}})(e,i);i.src?((e,t)=>{const a=he(e);if(a)if(ue((t=>pe(e,t)),t,a),((e,t)=>{e.dom.setAttrib(t,"src",t.getAttribute("src"))})(e,a),re(a.parentNode)){const t=a.parentNode;be(e,t),e.selection.select(a.parentNode)}else e.selection.select(a),((e,t,a)=>{const i=()=>{a.onload=a.onerror=null,e.selection&&(e.selection.select(a),e.nodeChanged())};a.onload=()=>{t.width||t.height||!S(e)||e.dom.setAttribs(a,{width:String(a.clientWidth),height:String(a.clientHeight)}),i()},a.onerror=i})(e,t,a)})(e,s):((e,t)=>{if(t){const a=e.dom.is(t.parentNode,"figure.image")?t.parentNode:t;e.dom.remove(a),e.focus(),e.nodeChanged(),e.dom.isEmpty(e.getBody())&&(e.setContent(""),e.selection.setCursorLocation())}})(e,a)}else t.src&&ve(e,{src:"",alt:"",title:"",width:"",height:"",class:"",style:"",caption:!1,hspace:"",vspace:"",border:"",borderStyle:"",isDecorative:!1,...t})},fe=(we=(e,t)=>n(e)&&n(t)?fe(e,t):t,(...e)=>{if(0===e.length)throw new Error("Can't merge zero objects");const t={};for(let a=0;ar(e.value)?e.value:"",Ce=(e,t)=>{const a=[];return De.each(e,(e=>{const i=(e=>r(e.text)?e.text:r(e.title)?e.title:"")(e);if(void 0!==e.menu){const s=Ce(e.menu,t);a.push({text:i,items:s})}else{const s=t(e);a.push({text:i,value:s})}})),a},Ie=(e=_e)=>t=>t?h.from(t).map((t=>Ce(t,e))):h.none(),Ue=(e,t)=>((e,a)=>{for(let a=0;ay(e,"items"))(i=e[a])?Ue(i.items,t):i.value===t?h.some(i):h.none();if(s.isSome())return s}var i;return h.none()})(e),xe=Ie,Se=(e,t)=>e.bind((e=>Ue(e,t))),Ne=e=>{const t=xe((t=>e.convertURL(t.value||t.url||"","src"))),a=new Promise((a=>{((e,t)=>{const a=R(e);r(a)?fetch(a).then((e=>{e.ok&&e.json().then(t)})):g(a)?a(t):t(a)})(e,(e=>{a(t(e).map((e=>w([[{text:"None",value:""}],e]))))}))})),i=(A=L(e),Ie(_e)(A)),s=N(e),o=T(e),n=(e=>U(e.options.get("images_upload_url")))(e),l=(e=>d(e.options.get("images_upload_handler")))(e),c=(e=>{const t=he(e);return t?ce((t=>pe(e,t)),t):{src:"",alt:"",title:"",width:"",height:"",class:"",style:"",caption:!1,hspace:"",vspace:"",border:"",borderStyle:"",isDecorative:!1}})(e),m=E(e),u=j(e),p=S(e),b=M(e),v=k(e),y=z(e),f=h.some(O(e)).filter((e=>r(e)&&e.length>0));var A;return a.then((e=>({image:c,imageList:e,classList:i,hasAdvTab:s,hasUploadTab:o,hasUploadUrl:n,hasUploadHandler:l,hasDescription:m,hasImageTitle:u,hasDimensions:p,hasImageCaption:b,prependURL:f,hasAccessibilityOptions:v,automaticUploads:y})))},Te=e=>{const t=e.imageList.map((e=>({name:"images",type:"listbox",label:"Image list",items:e}))),a={name:"alt",type:"input",label:"Alternative description",enabled:!(e.hasAccessibilityOptions&&e.image.isDecorative)},i=e.classList.map((e=>({name:"classes",type:"listbox",label:"Class",items:e})));return w([[{name:"src",type:"urlinput",filetype:"image",label:"Source"}],t.toArray(),e.hasAccessibilityOptions&&e.hasDescription?[{type:"label",label:"Accessibility",items:[{name:"isDecorative",type:"checkbox",label:"Image is decorative"}]}]:[],e.hasDescription?[a]:[],e.hasImageTitle?[{name:"title",type:"input",label:"Image title"}]:[],e.hasDimensions?[{name:"dimensions",type:"sizeinput"}]:[],[{...(s=e.classList.isSome()&&e.hasImageCaption,s?{type:"grid",columns:2}:{type:"panel"}),items:w([i.toArray(),e.hasImageCaption?[{type:"label",label:"Caption",items:[{type:"checkbox",name:"caption",label:"Show caption"}]}]:[]])}]]);var s},Oe=e=>({title:"General",name:"general",items:Te(e)}),Le=Te,Ee=e=>({src:{value:e.src,meta:{}},images:e.src,alt:e.alt,title:e.title,dimensions:{width:e.width,height:e.height},classes:e.class,caption:e.caption,style:e.style,vspace:e.vspace,border:e.border,hspace:e.hspace,borderstyle:e.borderStyle,fileinput:[],isDecorative:e.isDecorative}),je=(e,t)=>({src:e.src.value,alt:null!==e.alt&&0!==e.alt.length||!t?e.alt:null,title:e.title,width:e.dimensions.width,height:e.dimensions.height,class:e.classes,style:e.style,caption:e.caption,hspace:e.hspace,vspace:e.vspace,border:e.border,borderStyle:e.borderstyle,isDecorative:e.isDecorative}),Me=(e,t,a,i)=>{((e,t)=>{const a=t.getData();((e,t)=>/^(?:[a-zA-Z]+:)?\/\//.test(t)?h.none():e.prependURL.bind((e=>t.substring(0,e.length)!==e?h.some(e+t):h.none())))(e,a.src.value).each((e=>{t.setData({src:{value:e,meta:a.src.meta}})}))})(t,i),((e,t)=>{const a=t.getData(),i=a.src.meta;if(void 0!==i){const s=fe({},a);((e,t,a)=>{e.hasDescription&&r(a.alt)&&(t.alt=a.alt),e.hasAccessibilityOptions&&(t.isDecorative=a.isDecorative||t.isDecorative||!1),e.hasImageTitle&&r(a.title)&&(t.title=a.title),e.hasDimensions&&(r(a.width)&&(t.dimensions.width=a.width),r(a.height)&&(t.dimensions.height=a.height)),r(a.class)&&Se(e.classList,a.class).each((e=>{t.classes=e.value})),e.hasImageCaption&&m(a.caption)&&(t.caption=a.caption),e.hasAdvTab&&(r(a.style)&&(t.style=a.style),r(a.vspace)&&(t.vspace=a.vspace),r(a.border)&&(t.border=a.border),r(a.hspace)&&(t.hspace=a.hspace),r(a.borderstyle)&&(t.borderstyle=a.borderstyle))})(e,s,i),t.setData(s)}})(t,i),((e,t,a,i)=>{const s=i.getData(),r=s.src.value,o=s.src.meta||{};o.width||o.height||!t.hasDimensions||(U(r)?e.imageSize(r).then((e=>{a.open&&i.setData({dimensions:e})})).catch((e=>console.error(e))):i.setData({dimensions:{width:"",height:""}}))})(e,t,a,i),((e,t,a)=>{const i=a.getData(),s=Se(e.imageList,i.src.value);t.prevImage=s,a.setData({images:s.map((e=>e.value)).getOr("")})})(t,a,i)},Re=(e,t,a,i)=>{const s=i.getData();var r;i.block("Uploading image"),(r=s.fileinput,((e,t)=>0{i.unblock()}),(s=>{const r=URL.createObjectURL(s),o=()=>{i.unblock(),URL.revokeObjectURL(r)},n=s=>{i.setData({src:{value:s,meta:{}}}),i.showTab("general"),Me(e,t,a,i)};var l;(l=s,new Promise(((e,t)=>{const a=new FileReader;a.onload=()=>{e(a.result)},a.onerror=()=>{var e;t(null===(e=a.error)||void 0===e?void 0:e.message)},a.readAsDataURL(l)}))).then((a=>{const l=e.createBlobCache(s,r,a);t.automaticUploads?e.uploadImage(l).then((e=>{n(e.url),o()})).catch((t=>{o(),e.alertErr(t)})):(e.addToBlobCache(l),n(l.blobUri()),i.unblock())}))}))},ke=(e,t,a)=>(i,s)=>{"src"===s.name?Me(e,t,a,i):"images"===s.name?((e,t,a,i)=>{const s=i.getData(),r=Se(t.imageList,s.images);r.each((e=>{const t=""===s.alt||a.prevImage.map((e=>e.text===s.alt)).getOr(!1);t?""===e.value?i.setData({src:e,alt:a.prevAlt}):i.setData({src:e,alt:e.text}):i.setData({src:e})})),a.prevImage=r,Me(e,t,a,i)})(e,t,a,i):"alt"===s.name?a.prevAlt=i.getData().alt:"fileinput"===s.name?Re(e,t,a,i):"isDecorative"===s.name&&i.setEnabled("alt",!i.getData().isDecorative)},ze=e=>()=>{e.open=!1},Pe=e=>e.hasAdvTab||e.hasUploadUrl||e.hasUploadHandler?{type:"tabpanel",tabs:w([[Oe(e)],e.hasAdvTab?[{title:"Advanced",name:"advanced",items:[{type:"grid",columns:2,items:[{type:"input",label:"Vertical space",name:"vspace",inputMode:"numeric"},{type:"input",label:"Horizontal space",name:"hspace",inputMode:"numeric"},{type:"input",label:"Border width",name:"border",inputMode:"numeric"},{type:"listbox",name:"borderstyle",label:"Border style",items:[{text:"Select...",value:""},{text:"Solid",value:"solid"},{text:"Dotted",value:"dotted"},{text:"Dashed",value:"dashed"},{text:"Double",value:"double"},{text:"Groove",value:"groove"},{text:"Ridge",value:"ridge"},{text:"Inset",value:"inset"},{text:"Outset",value:"outset"},{text:"None",value:"none"},{text:"Hidden",value:"hidden"}]}]}]}]:[],e.hasUploadTab&&(e.hasUploadUrl||e.hasUploadHandler)?[{title:"Upload",name:"upload",items:[{type:"dropzone",name:"fileinput"}]}]:[]])}:{type:"panel",items:Le(e)},Be=(e,t,a)=>i=>{const s=fe(Ee(t.image),i.getData()),r={...s,style:le(a.normalizeCss,je(s,!1))};e.execCommand("mceUpdateImage",!1,je(r,t.hasAccessibilityOptions)),e.editorUpload.uploadImagesAuto(),i.close()},Fe=e=>t=>G(e,t)?(e=>new Promise((t=>{const a=document.createElement("img"),i=e=>{a.onload=a.onerror=null,a.parentNode&&a.parentNode.removeChild(a),t(e)};a.onload=()=>{const e={width:P(a.width,a.clientWidth),height:P(a.height,a.clientHeight)};i(Promise.resolve(e))},a.onerror=()=>{i(Promise.reject(`Failed to get image dimensions for: ${e}`))};const s=a.style;s.visibility="hidden",s.position="fixed",s.bottom=s.left="0px",s.width=s.height="auto",document.body.appendChild(a),a.src=e})))(e.documentBaseURI.toAbsolute(t)).then((e=>({width:String(e.width),height:String(e.height)}))):Promise.resolve({width:"",height:""}),He=e=>(t,a,i)=>{var s;return e.editorUpload.blobCache.create({blob:t,blobUri:a,name:null===(s=t.name)||void 0===s?void 0:s.replace(/\.[^\.]+$/,""),filename:t.name,base64:i.split(",")[1]})},Ge=e=>t=>{e.editorUpload.blobCache.add(t)},We=e=>t=>{e.windowManager.alert(t)},$e=e=>t=>pe(e,t),Ve=e=>t=>e.dom.parseStyle(t),Ke=e=>(t,a)=>e.dom.serializeStyle(t,a),Ze=e=>t=>Ae(e).upload([t],!1).then((e=>{var t;return 0===e.length?Promise.reject("Failed to upload image"):!1===e[0].status?Promise.reject(null===(t=e[0].error)||void 0===t?void 0:t.message):e[0]})),qe=e=>{const t={imageSize:Fe(e),addToBlobCache:Ge(e),createBlobCache:He(e),alertErr:We(e),normalizeCss:$e(e),parseStyle:Ve(e),serializeStyle:Ke(e),uploadImage:Ze(e)};return{open:()=>{Ne(e).then((a=>{const i=(e=>({prevImage:Se(e.imageList,e.image.src),prevAlt:e.image.alt,open:!0}))(a);return{title:"Insert/Edit Image",size:"normal",body:Pe(a),buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:Ee(a.image),onSubmit:Be(e,a,t),onChange:ke(t,a,i),onClose:ze(i)}})).then(e.windowManager.open)}}},Je=e=>{const t=e.attr("class");return d(t)&&/\bimage\b/.test(t)},Qe=e=>t=>{let a=t.length;const i=t=>{t.attr("contenteditable",e?"true":null)};for(;a--;){const s=t[a];Je(s)&&(s.attr("contenteditable",e?"false":null),De.each(s.getAll("figcaption"),i))}};e.add("image",(e=>{(e=>{const t=e.options.register;t("image_dimensions",{processor:"boolean",default:!0}),t("image_advtab",{processor:"boolean",default:!1}),t("image_uploadtab",{processor:"boolean",default:!0}),t("image_prepend_url",{processor:"string",default:""}),t("image_class_list",{processor:"object[]"}),t("image_description",{processor:"boolean",default:!0}),t("image_title",{processor:"boolean",default:!1}),t("image_caption",{processor:"boolean",default:!1}),t("image_list",{processor:e=>{const t=!1===e||r(e)||((e,t)=>{if(l(e)){for(let a=0,i=e.length;a{e.on("PreInit",(()=>{e.parser.addNodeFilter("figure",Qe(!0)),e.serializer.addNodeFilter("figure",Qe(!1))}))})(e),(e=>{e.ui.registry.addToggleButton("image",{icon:"image",tooltip:"Insert/edit image",onAction:qe(e).open,onSetup:t=>(t.setActive(d(he(e))),e.selection.selectorChangedWithUnbind("img:not([data-mce-object]):not([data-mce-placeholder]),figure.image",t.setActive).unbind)}),e.ui.registry.addMenuItem("image",{icon:"image",text:"Image...",onAction:qe(e).open}),e.ui.registry.addContextMenu("image",{update:e=>re(e)||"IMG"===e.nodeName&&!H(e)?["image"]:[]})})(e),(e=>{e.addCommand("mceImage",qe(e).open),e.addCommand("mceUpdateImage",((t,a)=>{e.undoManager.transact((()=>ye(e,a)))}))})(e)}))}(); \ No newline at end of file diff --git a/static/js/tinymce/plugins/importcss/plugin.min.js b/static/js/tinymce/plugins/importcss/plugin.min.js new file mode 100644 index 0000000..abc7f5f --- /dev/null +++ b/static/js/tinymce/plugins/importcss/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.2.0 (2022-09-08) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(s=r=e,(o=String).prototype.isPrototypeOf(s)||(null===(n=r.constructor)||void 0===n?void 0:n.name)===o.name)?"string":t;var s,r,o,n})(t)===e,s=t("string"),r=t("object"),o=t("array"),n=("function",e=>"function"==typeof e);var c=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),i=tinymce.util.Tools.resolve("tinymce.EditorManager"),l=tinymce.util.Tools.resolve("tinymce.Env"),a=tinymce.util.Tools.resolve("tinymce.util.Tools");const p=e=>t=>t.options.get(e),u=p("importcss_merge_classes"),m=p("importcss_exclusive"),f=p("importcss_selector_converter"),y=p("importcss_selector_filter"),d=p("importcss_groups"),h=p("importcss_append"),_=p("importcss_file_filter"),g=p("skin"),v=p("skin_url"),b=Array.prototype.push,x=/^\.(?:ephox|tiny-pageembed|mce)(?:[.-]+\w+)+$/,T=e=>s(e)?t=>-1!==t.indexOf(e):e instanceof RegExp?t=>e.test(t):e,S=(e,t)=>{let s={};const r=/^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(t);if(!r)return;const o=r[1],n=r[2].substr(1).split(".").join(" "),c=a.makeMap("a,img");return r[1]?(s={title:t},e.schema.getTextBlockElements()[o]?s.block=o:e.schema.getBlockElements()[o]||c[o.toLowerCase()]?s.selector=o:s.inline=o):r[2]&&(s={inline:"span",title:t.substr(1),classes:n}),u(e)?s.classes=n:s.attributes={class:n},s},k=(e,t)=>null===t||m(e),w=e=>{e.on("init",(()=>{const t=(()=>{const e=[],t=[],s={};return{addItemToGroup:(e,r)=>{s[e]?s[e].push(r):(t.push(e),s[e]=[r])},addItem:t=>{e.push(t)},toFormats:()=>{return(r=t,n=e=>{const t=s[e];return 0===t.length?[]:[{title:e,items:t}]},(e=>{const t=[];for(let s=0,r=e.length;s{const s=e.length,r=new Array(s);for(let o=0;oa.map(e,(e=>a.extend({},e,{original:e,selectors:{},filter:T(e.filter)}))))(d(e)),u=(t,s)=>{if(((e,t,s,r)=>!(k(e,s)?t in r:t in s.selectors))(e,t,s,r)){((e,t,s,r)=>{k(e,s)?r[t]=!0:s.selectors[t]=!0})(e,t,s,r);const o=((e,t,s,r)=>{let o;const n=f(e);return o=r&&r.selector_converter?r.selector_converter:n||(()=>S(e,s)),o.call(t,s,r)})(e,e.plugins.importcss,t,s);if(o){const t=o.name||c.DOM.uniqueId();return e.formatter.register(t,o),{title:o.title,format:t}}}return null};a.each(((e,t,r)=>{const o=[],n={},c=(t,n)=>{let p,u=t.href;if(u=(e=>{const t=l.cacheSuffix;return s(e)&&(e=e.replace("?"+t,"").replace("&"+t,"")),e})(u),u&&(!r||r(u,n))&&!((e,t)=>{const s=g(e);if(s){const r=v(e),o=r?e.documentBaseURI.toAbsolute(r):i.baseURL+"/skins/ui/"+s,n=i.baseURL+"/skins/content/";return t===o+"/content"+(e.inline?".inline":"")+".min.css"||-1!==t.indexOf(n)}return!1})(e,u)){a.each(t.imports,(e=>{c(e,!0)}));try{p=t.cssRules||t.rules}catch(e){}a.each(p,(e=>{e.styleSheet?c(e.styleSheet,!0):e.selectorText&&a.each(e.selectorText.split(","),(e=>{o.push(a.trim(e))}))}))}};a.each(e.contentCSS,(e=>{n[e]=!0})),r||(r=(e,t)=>t||n[e]);try{a.each(t.styleSheets,(e=>{c(e)}))}catch(e){}return o})(e,e.getDoc(),T(_(e))),(e=>{if(!x.test(e)&&(!n||n(e))){const s=((e,t)=>a.grep(e,(e=>!e.filter||e.filter(t))))(p,e);if(s.length>0)a.each(s,(s=>{const r=u(e,s);r&&t.addItemToGroup(s.title,r)}));else{const s=u(e,null);s&&t.addItem(s)}}}));const m=t.toFormats();e.dispatch("addStyleModifications",{items:m,replace:!h(e)})}))};e.add("importcss",(e=>((e=>{const t=e.options.register,o=e=>s(e)||n(e)||r(e);t("importcss_merge_classes",{processor:"boolean",default:!0}),t("importcss_exclusive",{processor:"boolean",default:!0}),t("importcss_selector_converter",{processor:"function"}),t("importcss_selector_filter",{processor:o}),t("importcss_file_filter",{processor:o}),t("importcss_groups",{processor:"object[]"}),t("importcss_append",{processor:"boolean",default:!1})})(e),w(e),(e=>({convertSelectorToFormat:t=>S(e,t)}))(e))))}(); \ No newline at end of file diff --git a/static/js/tinymce/plugins/insertdatetime/plugin.min.js b/static/js/tinymce/plugins/insertdatetime/plugin.min.js new file mode 100644 index 0000000..7130a6d --- /dev/null +++ b/static/js/tinymce/plugins/insertdatetime/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.2.0 (2022-09-08) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>t.options.get(e),a=t("insertdatetime_dateformat"),r=t("insertdatetime_timeformat"),n=t("insertdatetime_formats"),s=t("insertdatetime_element"),i="Sun Mon Tue Wed Thu Fri Sat Sun".split(" "),o="Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" "),l="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),m="January February March April May June July August September October November December".split(" "),c=(e,t)=>{if((e=""+e).length(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=t.replace("%D","%m/%d/%Y")).replace("%r","%I:%M:%S %p")).replace("%Y",""+a.getFullYear())).replace("%y",""+a.getYear())).replace("%m",c(a.getMonth()+1,2))).replace("%d",c(a.getDate(),2))).replace("%H",""+c(a.getHours(),2))).replace("%M",""+c(a.getMinutes(),2))).replace("%S",""+c(a.getSeconds(),2))).replace("%I",""+((a.getHours()+11)%12+1))).replace("%p",a.getHours()<12?"AM":"PM")).replace("%B",""+e.translate(m[a.getMonth()]))).replace("%b",""+e.translate(l[a.getMonth()]))).replace("%A",""+e.translate(o[a.getDay()]))).replace("%a",""+e.translate(i[a.getDay()]))).replace("%%","%"),u=(e,t)=>{if(s(e)){const a=d(e,t);let r;r=/%[HMSIp]/.test(t)?d(e,"%Y-%m-%dT%H:%M"):d(e,"%Y-%m-%d");const n=e.dom.getParent(e.selection.getStart(),"time");n?((e,t,a,r)=>{const n=e.dom.create("time",{datetime:a},r);e.dom.replace(n,t),e.selection.select(n,!0),e.selection.collapse(!1)})(e,n,r,a):e.insertContent('")}else e.insertContent(d(e,t))};var p=tinymce.util.Tools.resolve("tinymce.util.Tools");e.add("insertdatetime",(e=>{(e=>{const t=e.options.register;t("insertdatetime_dateformat",{processor:"string",default:e.translate("%Y-%m-%d")}),t("insertdatetime_timeformat",{processor:"string",default:e.translate("%H:%M:%S")}),t("insertdatetime_formats",{processor:"string[]",default:["%H:%M:%S","%Y-%m-%d","%I:%M:%S %p","%D"]}),t("insertdatetime_element",{processor:"boolean",default:!1})})(e),(e=>{e.addCommand("mceInsertDate",((t,r)=>{u(e,null!=r?r:a(e))})),e.addCommand("mceInsertTime",((t,a)=>{u(e,null!=a?a:r(e))}))})(e),(e=>{const t=n(e),a=(e=>{let t=e;return{get:()=>t,set:e=>{t=e}}})((e=>{const t=n(e);return t.length>0?t[0]:r(e)})(e)),s=t=>e.execCommand("mceInsertDate",!1,t);e.ui.registry.addSplitButton("insertdatetime",{icon:"insert-time",tooltip:"Insert date/time",select:e=>e===a.get(),fetch:a=>{a(p.map(t,(t=>({type:"choiceitem",text:d(e,t),value:t}))))},onAction:e=>{s(a.get())},onItemAction:(e,t)=>{a.set(t),s(t)}});const i=e=>()=>{a.set(e),s(e)};e.ui.registry.addNestedMenuItem("insertdatetime",{icon:"insert-time",text:"Date/time",getSubmenuItems:()=>p.map(t,(t=>({type:"menuitem",text:d(e,t),onAction:i(t)})))})})(e)}))}(); \ No newline at end of file diff --git a/static/js/tinymce/plugins/link/plugin.min.js b/static/js/tinymce/plugins/link/plugin.min.js new file mode 100644 index 0000000..62927c0 --- /dev/null +++ b/static/js/tinymce/plugins/link/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.2.0 (2022-09-08) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=o=e,(r=String).prototype.isPrototypeOf(n)||(null===(l=o.constructor)||void 0===l?void 0:l.name)===r.name)?"string":t;var n,o,r,l})(t)===e,n=e=>t=>typeof t===e,o=t("string"),r=t("object"),l=t("array"),a=(null,e=>null===e);const i=n("boolean"),s=e=>!(e=>null==e)(e),c=n("function"),u=(e,t)=>{if(l(e)){for(let n=0,o=e.length;n{},d=(e,t)=>e===t;class m{constructor(e,t){this.tag=e,this.value=t}static some(e){return new m(!0,e)}static none(){return m.singletonNone}fold(e,t){return this.tag?t(this.value):e()}isSome(){return this.tag}isNone(){return!this.tag}map(e){return this.tag?m.some(e(this.value)):m.none()}bind(e){return this.tag?e(this.value):m.none()}exists(e){return this.tag&&e(this.value)}forall(e){return!this.tag||e(this.value)}filter(e){return!this.tag||e(this.value)?this:m.none()}getOr(e){return this.tag?this.value:e}or(e){return this.tag?this:e}getOrThunk(e){return this.tag?this.value:e()}orThunk(e){return this.tag?this:e()}getOrDie(e){if(this.tag)return this.value;throw new Error(null!=e?e:"Called getOrDie on None")}static from(e){return s(e)?m.some(e):m.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(e){this.tag&&e(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}m.singletonNone=new m(!1);const h=Array.prototype.indexOf,f=Array.prototype.push,p=e=>{const t=[];for(let n=0,o=e.length;n{for(let n=0;ne.exists((e=>n(e,t))),y=e=>{const t=[],n=e=>{t.push(e)};for(let t=0;te?m.some(t):m.none(),b=e=>t=>t.options.get(e),_=b("link_assume_external_targets"),w=b("link_context_toolbar"),C=b("link_list"),O=b("link_default_target"),N=b("link_default_protocol"),A=b("link_target_list"),S=b("link_rel_list"),T=b("link_class_list"),E=b("link_title"),P=b("allow_unsafe_link_target"),R=b("link_quicklink");var L=tinymce.util.Tools.resolve("tinymce.util.Tools");const M=e=>o(e.value)?e.value:"",D=(e,t)=>{const n=[];return L.each(e,(e=>{const r=(e=>o(e.text)?e.text:o(e.title)?e.title:"")(e);if(void 0!==e.menu){const o=D(e.menu,t);n.push({text:r,items:o})}else{const o=t(e);n.push({text:r,value:o})}})),n},B=(e=M)=>t=>m.from(t).map((t=>D(t,e))),I=e=>B(M)(e),j=B,K=(e,t)=>n=>({name:e,type:"listbox",label:t,items:n}),U=M,q=Object.keys,F=Object.hasOwnProperty,V=(e,t)=>F.call(e,t);var $=tinymce.util.Tools.resolve("tinymce.dom.TreeWalker"),z=tinymce.util.Tools.resolve("tinymce.util.URI");const G=e=>s(e)&&"a"===e.nodeName.toLowerCase(),H=e=>G(e)&&!!Q(e),J=(e,t)=>{if(e.collapsed)return[];{const n=e.cloneContents(),o=n.firstChild,r=new $(o,n),l=[];let a=o;do{t(a)&&l.push(a)}while(a=r.next());return l}},W=e=>/^\w+:/i.test(e),Q=e=>{var t,n;return null!==(n=null!==(t=e.getAttribute("data-mce-href"))&&void 0!==t?t:e.getAttribute("href"))&&void 0!==n?n:""},X=(e,t)=>{const n=["noopener"],o=e?e.split(/\s+/):[],r=e=>e.filter((e=>-1===L.inArray(n,e))),l=t?(e=>(e=r(e)).length>0?e.concat(n):n)(o):r(o);return l.length>0?(e=>L.trim(e.sort().join(" ")))(l):""},Y=(e,t)=>(t=t||e.selection.getNode(),oe(t)?m.from(e.dom.select("a[href]",t)[0]):m.from(e.dom.getParent(t,"a[href]"))),Z=(e,t)=>Y(e,t).isSome(),ee=(e,t)=>t.fold((()=>e.getContent({format:"text"})),(e=>e.innerText||e.textContent||"")).replace(/\uFEFF/g,""),te=e=>L.grep(e,H).length>0,ne=e=>{const t=e.schema.getTextInlineElements();return 0===J(e.selection.getRng(),(e=>1===e.nodeType&&!G(e)&&!V(t,e.nodeName.toLowerCase()))).length},oe=e=>s(e)&&"FIGURE"===e.nodeName&&/\bimage\b/i.test(e.className),re=(e,t,n)=>{const o=e.selection.getNode(),r=Y(e,o),l=((e,t)=>{const n={...t};if(0===S(e).length&&!P(e)){const e=X(n.rel,"_blank"===n.target);n.rel=e||null}return m.from(n.target).isNone()&&!1===A(e)&&(n.target=O(e)),n.href=((e,t)=>"http"!==t&&"https"!==t||W(e)?e:t+"://"+e)(n.href,_(e)),n})(e,(e=>{return t=["title","rel","class","target"],n=(t,n)=>(e[n].each((e=>{t[n]=e.length>0?e:null})),t),o={href:e.href},((e,t)=>{for(let n=0,o=e.length;n{o=n(o,e)})),o;var t,n,o})(n));e.undoManager.transact((()=>{n.href===t.href&&t.attach(),r.fold((()=>{((e,t,n,o)=>{const r=e.dom;oe(t)?ce(r,t,o):n.fold((()=>{e.execCommand("mceInsertLink",!1,o)}),(t=>{e.insertContent(r.createHTML("a",o,r.encode(t)))}))})(e,o,n.text,l)}),(t=>{e.focus(),((e,t,n,o)=>{n.each((e=>{V(t,"innerText")?t.innerText=e:t.textContent=e})),e.dom.setAttribs(t,o),e.selection.select(t)})(e,t,n.text,l)}))}))},le=e=>{const{class:t,href:n,rel:o,target:r,text:l,title:i}=e;return((e,t)=>{const n={};var o;return((e,t,n,o)=>{((e,t)=>{const n=q(e);for(let o=0,r=n.length;o{(t(e,r)?n:o)(e,r)}))})(e,((e,t)=>!1===a(e)),(o=n,(e,t)=>{o[t]=e}),g),n})({class:t.getOrNull(),href:n,rel:o.getOrNull(),target:r.getOrNull(),text:l.getOrNull(),title:i.getOrNull()})},ae=(e,t,n)=>{const o=((e,t)=>{const n=e.options.get,o={allow_html_data_urls:n("allow_html_data_urls"),allow_script_urls:n("allow_script_urls"),allow_svg_data_urls:n("allow_svg_data_urls")},r=t.href;return{...t,href:z.isDomSafe(r,"a",o)?r:""}})(e,n);e.hasPlugin("rtc",!0)?e.execCommand("createlink",!1,le(o)):re(e,t,o)},ie=e=>{e.hasPlugin("rtc",!0)?e.execCommand("unlink"):(e=>{e.undoManager.transact((()=>{const t=e.selection.getNode();oe(t)?se(e,t):(e=>{const t=e.dom,n=e.selection,o=n.getBookmark(),r=n.getRng().cloneRange(),l=t.getParent(r.startContainer,"a[href]",e.getBody()),a=t.getParent(r.endContainer,"a[href]",e.getBody());l&&r.setStartBefore(l),a&&r.setEndAfter(a),n.setRng(r),e.execCommand("unlink"),n.moveToBookmark(o)})(e),e.focus()}))})(e)},se=(e,t)=>{var n;const o=e.dom.select("img",t)[0];if(o){const r=e.dom.getParents(o,"a[href]",t)[0];r&&(null===(n=r.parentNode)||void 0===n||n.insertBefore(o,r),e.dom.remove(r))}},ce=(e,t,n)=>{var o;const r=e.select("img",t)[0];if(r){const t=e.create("a",n);null===(o=r.parentNode)||void 0===o||o.insertBefore(t,r),t.appendChild(r)}},ue=(e,t)=>k(t,(t=>(e=>{return V(t=e,n="items")&&void 0!==t[n]&&null!==t[n];var t,n})(t)?ue(e,t.items):x(t.value===e,t))),ge=(e,t)=>{const n={text:e.text,title:e.title},o=(e,o)=>{const r=(l=t,a=o,"link"===a?l.link:"anchor"===a?l.anchor:m.none()).getOr([]);var l,a;return((e,t,n,o)=>{const r=o[t],l=e.length>0;return void 0!==r?ue(r,n).map((t=>({url:{value:t.value,meta:{text:l?e:t.text,attach:g}},text:l?e:t.text}))):m.none()})(n.text,o,r,e)};return{onChange:(e,t)=>{const r=t.name;return"url"===r?(e=>{const t=(o=e.url,x(n.text.length<=0,m.from(null===(r=o.meta)||void 0===r?void 0:r.text).getOr(o.value)));var o,r;const l=(e=>{var t;return x(n.title.length<=0,m.from(null===(t=e.meta)||void 0===t?void 0:t.title).getOr(""))})(e.url);return t.isSome()||l.isSome()?m.some({...t.map((e=>({text:e}))).getOr({}),...l.map((e=>({title:e}))).getOr({})}):m.none()})(e()):((e,t)=>h.call(e,t))(["anchor","link"],r)>-1?o(e(),r):"text"===r||"title"===r?(n[r]=e()[r],m.none()):m.none()}}};var de=tinymce.util.Tools.resolve("tinymce.util.Delay");const me=e=>{const t=e.href;return t.indexOf("@")>0&&-1===t.indexOf("/")&&-1===t.indexOf("mailto:")?m.some({message:"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?",preprocess:e=>({...e,href:"mailto:"+t})}):m.none()},he=(e,t)=>n=>{const o=n.href;return 1===e&&!W(o)||0===e&&/^\s*www(\.|\d\.)/i.test(o)?m.some({message:`The URL you entered seems to be an external link. Do you want to add the required ${t}:// prefix?`,preprocess:e=>({...e,href:t+"://"+o})}):m.none()},fe=e=>{const t=e.dom.select("a:not([href])"),n=p(((e,t)=>{const n=e.length,o=new Array(n);for(let r=0;r{const t=e.name||e.id;return t?[{text:t,value:"#"+t}]:[]})));return n.length>0?m.some([{text:"None",value:""}].concat(n)):m.none()},pe=e=>{const t=T(e);return t.length>0?I(t):m.none()},ke=e=>{try{return m.some(JSON.parse(e))}catch(e){return m.none()}},ve=(e,t)=>{const n=S(e);if(n.length>0){const o=v(t,"_blank"),r=e=>X(U(e),o);return(!1===P(e)?j(r):I)(n)}return m.none()},ye=[{text:"Current window",value:""},{text:"New window",value:"_blank"}],xe=e=>{const t=A(e);return l(t)?I(t).orThunk((()=>m.some(ye))):!1===t?m.none():m.some(ye)},be=(e,t,n)=>{const o=e.getAttrib(t,n);return null!==o&&o.length>0?m.some(o):m.none()},_e=(e,t)=>(e=>{const t=t=>e.convertURL(t.value||t.url||"","href"),n=C(e);return new Promise((e=>{o(n)?fetch(n).then((e=>e.ok?e.text().then(ke):Promise.reject())).then(e,(()=>e(m.none()))):c(n)?n((t=>e(m.some(t)))):e(m.from(n))})).then((e=>e.bind(j(t)).map((e=>e.length>0?[{text:"None",value:""}].concat(e):e))))})(e).then((n=>{const o=((e,t)=>{const n=e.dom,o=ne(e)?m.some(ee(e.selection,t)):m.none(),r=t.bind((e=>m.from(n.getAttrib(e,"href")))),l=t.bind((e=>m.from(n.getAttrib(e,"target")))),a=t.bind((e=>be(n,e,"rel"))),i=t.bind((e=>be(n,e,"class")));return{url:r,text:o,title:t.bind((e=>be(n,e,"title"))),target:l,rel:a,linkClass:i}})(e,t);return{anchor:o,catalogs:{targets:xe(e),rels:ve(e,o.target),classes:pe(e),anchor:fe(e),link:n},optNode:t,flags:{titleEnabled:E(e)}}})),we=e=>{const t=(e=>{const t=Y(e);return _e(e,t)})(e);t.then((t=>{const n=((e,t)=>n=>{const o=n.getData();if(!o.url.value)return ie(e),void n.close();const r=e=>m.from(o[e]).filter((n=>!v(t.anchor[e],n))),l={href:o.url.value,text:r("text"),target:r("target"),rel:r("rel"),class:r("linkClass"),title:r("title")},a={href:o.url.value,attach:void 0!==o.url.meta&&o.url.meta.attach?o.url.meta.attach:g};((e,t)=>k([me,he(_(e),N(e))],(e=>e(t))).fold((()=>Promise.resolve(t)),(n=>new Promise((o=>{((e,t,n)=>{const o=e.selection.getRng();de.setEditorTimeout(e,(()=>{e.windowManager.confirm(t,(t=>{e.selection.setRng(o),n(t)}))}))})(e,n.message,(e=>{o(e?n.preprocess(t):t)}))})))))(e,l).then((t=>{ae(e,a,t)})),n.close()})(e,t);return((e,t,n)=>{const o=e.anchor.text.map((()=>({name:"text",type:"input",label:"Text to display"}))).toArray(),r=e.flags.titleEnabled?[{name:"title",type:"input",label:"Title"}]:[],l=((e,t)=>{const n=e.anchor,o=n.url.getOr("");return{url:{value:o,meta:{original:{value:o}}},text:n.text.getOr(""),title:n.title.getOr(""),anchor:o,link:o,rel:n.rel.getOr(""),target:n.target.or(t).getOr(""),linkClass:n.linkClass.getOr("")}})(e,m.from(O(n))),a=e.catalogs,i=ge(l,a);return{title:"Insert/Edit Link",size:"normal",body:{type:"panel",items:p([[{name:"url",type:"urlinput",filetype:"file",label:"URL"}],o,r,y([a.anchor.map(K("anchor","Anchors")),a.rels.map(K("rel","Rel")),a.targets.map(K("target","Open link in...")),a.link.map(K("link","Link list")),a.classes.map(K("linkClass","Class"))])])},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:l,onChange:(e,{name:t})=>{i.onChange(e.getData,{name:t}).each((t=>{e.setData(t)}))},onSubmit:t}})(t,n,e)})).then((t=>{e.windowManager.open(t)}))};var Ce=tinymce.util.Tools.resolve("tinymce.util.VK");const Oe=(e,t)=>e.dom.getParent(t,"a[href]"),Ne=e=>Oe(e,e.selection.getStart()),Ae=(e,t)=>{if(t){const n=Q(t);if(/^#/.test(n)){const t=e.dom.select(n);t.length&&e.selection.scrollIntoView(t[0],!0)}else(e=>{const t=document.createElement("a");t.target="_blank",t.href=e,t.rel="noreferrer noopener";const n=document.createEvent("MouseEvents");n.initMouseEvent("click",!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),((e,t)=>{document.body.appendChild(e),e.dispatchEvent(t),document.body.removeChild(e)})(t,n)})(t.href)}},Se=e=>()=>{e.execCommand("mceLink",!1,{dialog:!0})},Te=e=>()=>{Ae(e,Ne(e))},Ee=(e,t)=>(e.on("NodeChange",t),()=>e.off("NodeChange",t)),Pe=e=>t=>{const n=()=>t.setActive(!e.mode.isReadOnly()&&Z(e,e.selection.getNode()));return n(),Ee(e,n)},Re=e=>t=>{const n=()=>t.setEnabled(Z(e,e.selection.getNode()));return n(),Ee(e,n)},Le=e=>t=>{const n=t=>{return te(t)||(n=e.selection.getRng(),J(n,H).length>0);var n},o=e.dom.getParents(e.selection.getStart());return t.setEnabled(n(o)),Ee(e,(e=>t.setEnabled(n(e.parents))))};e.add("link",(e=>{(e=>{const t=e.options.register;t("link_assume_external_targets",{processor:e=>{const t=o(e)||i(e);return t?!0===e?{value:1,valid:t}:"http"===e||"https"===e?{value:e,valid:t}:{value:0,valid:t}:{valid:!1,message:"Must be a string or a boolean."}},default:!1}),t("link_context_toolbar",{processor:"boolean",default:!1}),t("link_list",{processor:e=>o(e)||c(e)||u(e,r)}),t("link_default_target",{processor:"string"}),t("link_default_protocol",{processor:"string",default:"https"}),t("link_target_list",{processor:e=>i(e)||u(e,r),default:!0}),t("link_rel_list",{processor:"object[]",default:[]}),t("link_class_list",{processor:"object[]",default:[]}),t("link_title",{processor:"boolean",default:!0}),t("allow_unsafe_link_target",{processor:"boolean",default:!1}),t("link_quicklink",{processor:"boolean",default:!1})})(e),(e=>{e.ui.registry.addToggleButton("link",{icon:"link",tooltip:"Insert/edit link",onAction:Se(e),onSetup:Pe(e)}),e.ui.registry.addButton("openlink",{icon:"new-tab",tooltip:"Open link",onAction:Te(e),onSetup:Re(e)}),e.ui.registry.addButton("unlink",{icon:"unlink",tooltip:"Remove link",onAction:()=>ie(e),onSetup:Le(e)})})(e),(e=>{e.ui.registry.addMenuItem("openlink",{text:"Open link",icon:"new-tab",onAction:Te(e),onSetup:Re(e)}),e.ui.registry.addMenuItem("link",{icon:"link",text:"Link...",shortcut:"Meta+K",onAction:Se(e)}),e.ui.registry.addMenuItem("unlink",{icon:"unlink",text:"Remove link",onAction:()=>ie(e),onSetup:Le(e)})})(e),(e=>{e.ui.registry.addContextMenu("link",{update:t=>te(e.dom.getParents(t,"a"))?"link unlink openlink":"link"})})(e),(e=>{const t=t=>{const n=e.selection.getNode();return t.setEnabled(Z(e,n)),g};e.ui.registry.addContextForm("quicklink",{launch:{type:"contextformtogglebutton",icon:"link",tooltip:"Link",onSetup:Pe(e)},label:"Link",predicate:t=>w(e)&&Z(e,t),initValue:()=>Y(e).fold((()=>""),Q),commands:[{type:"contextformtogglebutton",icon:"link",tooltip:"Link",primary:!0,onSetup:t=>{const n=e.selection.getNode();return t.setActive(Z(e,n)),Pe(e)(t)},onAction:t=>{const n=t.getValue(),o=(t=>{const n=Y(e),o=ne(e);if(n.isNone()&&o){const o=ee(e.selection,n);return m.some(o.length>0?o:t)}return m.none()})(n);ae(e,{href:n,attach:g},{href:n,text:o,title:m.none(),rel:m.none(),target:m.none(),class:m.none()}),(e=>{e.selection.collapse(!1)})(e),t.hide()}},{type:"contextformbutton",icon:"unlink",tooltip:"Remove link",onSetup:t,onAction:t=>{ie(e),t.hide()}},{type:"contextformbutton",icon:"new-tab",tooltip:"Open link",onSetup:t,onAction:t=>{Te(e)(),t.hide()}}]})})(e),(e=>{e.on("click",(t=>{const n=Oe(e,t.target);n&&Ce.metaKeyPressed(t)&&(t.preventDefault(),Ae(e,n))})),e.on("keydown",(t=>{if(!t.isDefaultPrevented()&&13===t.keyCode&&(e=>!0===e.altKey&&!1===e.shiftKey&&!1===e.ctrlKey&&!1===e.metaKey)(t)){const n=Ne(e);n&&(t.preventDefault(),Ae(e,n))}}))})(e),(e=>{e.addCommand("mceLink",((t,n)=>{!0!==(null==n?void 0:n.dialog)&&R(e)?e.dispatch("contexttoolbar-show",{toolbarKey:"quicklink"}):we(e)}))})(e),(e=>{e.addShortcut("Meta+K","",(()=>{e.execCommand("mceLink")}))})(e)}))}(); \ No newline at end of file diff --git a/static/js/tinymce/plugins/lists/plugin.min.js b/static/js/tinymce/plugins/lists/plugin.min.js new file mode 100644 index 0000000..7a7d148 --- /dev/null +++ b/static/js/tinymce/plugins/lists/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.2.0 (2022-09-08) + */ +!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=t=>e=>(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(n=r=t,(o=String).prototype.isPrototypeOf(n)||(null===(s=r.constructor)||void 0===s?void 0:s.name)===o.name)?"string":e;var n,r,o,s})(e)===t,n=t=>e=>typeof e===t,r=e("string"),o=e("object"),s=e("array"),i=n("boolean"),a=t=>!(t=>null==t)(t),l=n("function"),d=n("number"),c=()=>{},u=(t,e)=>t===e,m=t=>e=>!t(e),p=(!1,()=>false);class g{constructor(t,e){this.tag=t,this.value=e}static some(t){return new g(!0,t)}static none(){return g.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?g.some(t(this.value)):g.none()}bind(t){return this.tag?t(this.value):g.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:g.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return a(t)?g.some(t):g.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}g.singletonNone=new g(!1);const h=Array.prototype.slice,f=Array.prototype.indexOf,y=Array.prototype.push,v=(t,e)=>{return n=t,r=e,f.call(n,r)>-1;var n,r},C=(t,e)=>{for(let n=0,r=t.length;n{const n=t.length,r=new Array(n);for(let o=0;o{for(let n=0,r=t.length;n{const n=[];for(let r=0,o=t.length;r(S(t,((t,r)=>{n=e(n,t,r)})),n),O=(t,e,n)=>{for(let r=0,o=t.length;rO(t,e,p),T=(t,e)=>(t=>{const e=[];for(let n=0,r=t.length;n{const e=h.call(t,0);return e.reverse(),e},w=(t,e)=>e>=0&&ew(t,0),E=t=>w(t,t.length-1),B=(t,e)=>{const n=[],r=l(e)?t=>C(n,(n=>e(n,t))):t=>v(n,t);for(let e=0,o=t.length;et.exists((t=>n(t,e))),I=(t,e,n)=>t.isSome()&&e.isSome()?g.some(n(t.getOrDie(),e.getOrDie())):g.none(),P=t=>{if(null==t)throw new Error("Node cannot be null or undefined");return{dom:t}},M=(t,e)=>{const n=(e||document).createElement(t);return P(n)},R=P,U=(t,e)=>t.dom===e.dom;"undefined"!=typeof window?window:Function("return this;")();const $=t=>t.dom.nodeName.toLowerCase(),_=(1,t=>1===(t=>t.dom.nodeType)(t));const H=t=>e=>_(e)&&$(e)===t,j=t=>g.from(t.dom.parentNode).map(R),F=t=>b(t.dom.childNodes,R),K=(t,e)=>{const n=t.dom.childNodes;return g.from(n[e]).map(R)},V=t=>K(t,0),z=t=>K(t,t.dom.childNodes.length-1),Q=(t,e,n)=>{let r=t.dom;const o=l(n)?n:p;for(;r.parentNode;){r=r.parentNode;const t=R(r);if(e(t))return g.some(t);if(o(t))break}return g.none()},q=(t,e,n)=>((t,e,n,r,o)=>r(n)?g.some(n):l(o)&&o(n)?g.none():e(n,r,o))(0,Q,t,e,n),W=(t,e)=>{j(t).each((n=>{n.dom.insertBefore(e.dom,t.dom)}))},Z=(t,e)=>{t.dom.appendChild(e.dom)},G=(t,e)=>{S(e,(e=>{Z(t,e)}))},J=t=>{t.dom.textContent="",S(F(t),(t=>{X(t)}))},X=t=>{const e=t.dom;null!==e.parentNode&&e.parentNode.removeChild(e)};var Y=tinymce.util.Tools.resolve("tinymce.dom.RangeUtils"),tt=tinymce.util.Tools.resolve("tinymce.dom.TreeWalker"),et=tinymce.util.Tools.resolve("tinymce.util.VK");const nt=t=>b(t,R),rt=Object.keys,ot=(t,e)=>{const n=rt(t);for(let r=0,o=n.length;r{const n=t.dom;ot(e,((t,e)=>{((t,e,n)=>{if(!(r(n)||i(n)||d(n)))throw console.error("Invalid call to Attribute.set. Key ",e,":: Value ",n,":: Element ",t),new Error("Attribute value was not simple");t.setAttribute(e,n+"")})(n,e,t)}))},it=t=>L(t.dom.attributes,((t,e)=>(t[e.name]=e.value,t)),{}),at=t=>((t,e)=>R(t.dom.cloneNode(!0)))(t),lt=(t,e)=>{const n=((t,e)=>{const n=M(e),r=it(t);return st(n,r),n})(t,e);((t,e)=>{const n=(t=>g.from(t.dom.nextSibling).map(R))(t);n.fold((()=>{j(t).each((t=>{Z(t,e)}))}),(t=>{W(t,e)}))})(t,n);const r=F(t);return G(n,r),X(t),n};var dt=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),ct=tinymce.util.Tools.resolve("tinymce.util.Tools");const ut=t=>e=>a(e)&&e.nodeName.toLowerCase()===t,mt=t=>e=>a(e)&&t.test(e.nodeName),pt=t=>a(t)&&3===t.nodeType,gt=t=>a(t)&&1===t.nodeType,ht=mt(/^(OL|UL|DL)$/),ft=mt(/^(OL|UL)$/),yt=ut("ol"),vt=mt(/^(LI|DT|DD)$/),Ct=mt(/^(DT|DD)$/),bt=mt(/^(TH|TD)$/),St=ut("br"),Nt=(t,e)=>a(e)&&e.nodeName in t.schema.getTextBlockElements(),Lt=(t,e)=>a(t)&&t.nodeName in e,Ot=(t,e,n)=>{const r=t.isEmpty(e);return!(n&&t.select("span[data-mce-type=bookmark]",e).length>0)&&r},kt=(t,e)=>t.isChildOf(e,t.getRoot()),Tt=t=>e=>e.options.get(t),At=Tt("lists_indent_on_tab"),wt=Tt("forced_root_block"),Dt=Tt("forced_root_block_attrs"),Et=(t,e)=>{const n=t.dom,r=t.schema.getBlockElements(),o=n.createFragment(),s=wt(t),i=Dt(t);let a,l,d=!1;for(l=n.create(s,i),Lt(e.firstChild,r)||o.appendChild(l);a=e.firstChild;){const t=a.nodeName;d||"SPAN"===t&&"bookmark"===a.getAttribute("data-mce-type")||(d=!0),Lt(a,r)?(o.appendChild(a),l=null):(l||(l=n.create(s,i),o.appendChild(l)),l.appendChild(a))}return!d&&l&&l.appendChild(n.create("br",{"data-mce-bogus":"1"})),o},Bt=dt.DOM,xt=H("dd"),It=H("dt"),Pt=(t,e)=>{var n;xt(e)?lt(e,"dt"):It(e)&&(n=e,g.from(n.dom.parentElement).map(R)).each((n=>((t,e,n)=>{const r=Bt.select('span[data-mce-type="bookmark"]',e),o=Et(t,n),s=Bt.createRng();s.setStartAfter(n),s.setEndAfter(e);const i=s.extractContents();for(let e=i.firstChild;e;e=e.firstChild)if("LI"===e.nodeName&&t.dom.isEmpty(e)){Bt.remove(e);break}t.dom.isEmpty(i)||Bt.insertAfter(i,e),Bt.insertAfter(o,e);const a=n.parentElement;a&&Ot(t.dom,a)&&(t=>{const e=t.parentNode;e&&ct.each(r,(t=>{e.insertBefore(t,n.parentNode)})),Bt.remove(t)})(a),Bt.remove(n),Ot(t.dom,e)&&Bt.remove(e)})(t,n.dom,e.dom)))},Mt=t=>{It(t)&<(t,"dd")},Rt=(t,e)=>{if(pt(t))return{container:t,offset:e};const n=Y.getNode(t,e);return pt(n)?{container:n,offset:e>=t.childNodes.length?n.data.length:0}:n.previousSibling&&pt(n.previousSibling)?{container:n.previousSibling,offset:n.previousSibling.data.length}:n.nextSibling&&pt(n.nextSibling)?{container:n.nextSibling,offset:0}:{container:t,offset:e}},Ut=t=>{const e=t.cloneRange(),n=Rt(t.startContainer,t.startOffset);e.setStart(n.container,n.offset);const r=Rt(t.endContainer,t.endOffset);return e.setEnd(r.container,r.offset),e},$t=["OL","UL","DL"],_t=$t.join(","),Ht=(t,e)=>{const n=e||t.selection.getStart(!0);return t.dom.getParent(n,_t,Kt(t,n))},jt=t=>{const e=t.selection.getSelectedBlocks();return N(((t,e)=>{const n=ct.map(e,(e=>t.dom.getParent(e,"li,dd,dt",Kt(t,e))||e));return B(n)})(t,e),vt)},Ft=(t,e)=>{const n=t.dom.getParents(e,"TD,TH");return n.length>0?n[0]:t.getBody()},Kt=(t,e)=>{const n=t.dom.getParents(e,t.dom.isBlock),r=k(n,(e=>{return n=t.schema,!ht(r=e)&&!vt(r)&&C($t,(t=>n.isValidChild(r.nodeName,t)));var n,r}));return r.getOr(t.getBody())},Vt=(t,e)=>{const n=t.dom.getParents(e,"ol,ul",Kt(t,e));return E(n)},zt=(t,e)=>{const n=b(e,(e=>Vt(t,e).getOr(e)));return B(n)},Qt=t=>/\btox\-/.test(t.className),qt=(t,e)=>O(t,ht,bt).exists((t=>t.nodeName===e&&!Qt(t))),Wt=(t,e)=>null!==e&&"false"===t.dom.getContentEditableParent(e),Zt=(t,e)=>{const n=t.dom.getParent(e,"ol,ul,dl");return Wt(t,n)},Gt=(t,e)=>{const n=t.selection.getNode();return e({parents:t.dom.getParents(n),element:n}),t.on("NodeChange",e),()=>t.off("NodeChange",e)},Jt=(t,e,n)=>t.dispatch("ListMutation",{action:e,element:n}),Xt=(Yt=/^\s+|\s+$/g,t=>t.replace(Yt,""));var Yt;const te=(t,e,n)=>{((t,e,n)=>{if(!r(n))throw console.error("Invalid call to CSS.set. Property ",e,":: Value ",n,":: Element ",t),new Error("CSS value must be a string: "+n);(t=>void 0!==t.style&&l(t.style.getPropertyValue))(t)&&t.style.setProperty(e,n)})(t.dom,e,n)},ee=(t,e)=>{Z(t.item,e.list)},ne=(t,e)=>{const n={list:M(e,t),item:M("li",t)};return Z(n.list,n.item),n},re=t=>((t,e)=>{const n=t.dom;if(1!==n.nodeType)return!1;{const t=n;if(void 0!==t.matches)return t.matches(e);if(void 0!==t.msMatchesSelector)return t.msMatchesSelector(e);if(void 0!==t.webkitMatchesSelector)return t.webkitMatchesSelector(e);if(void 0!==t.mozMatchesSelector)return t.mozMatchesSelector(e);throw new Error("Browser lacks native selectors")}})(t,"OL,UL"),oe=t=>V(t).exists(re),se=t=>t.depth>0,ie=t=>t.isSelected,ae=t=>{const e=F(t),n=z(t).exists(re)?e.slice(0,-1):e;return b(n,at)},le=t=>(S(t,((e,n)=>{((t,e)=>{const n=t[e].depth,r=t=>t.depth===n&&!t.dirty,o=t=>t.depthO(t.slice(e+1),r,o)))})(t,n).fold((()=>{e.dirty&&(t=>{t.listAttributes=((t,e)=>{const n={};var r;return((t,e,n,r)=>{ot(t,((t,o)=>{(e(t,o)?n:r)(t,o)}))})(t,e,(r=n,(t,e)=>{r[e]=t}),c),n})(t.listAttributes,((t,e)=>"start"!==e))})(e)}),(t=>{return r=t,(n=e).listType=r.listType,void(n.listAttributes={...r.listAttributes});var n,r}))})),t),de=(t,e,n,r)=>V(r).filter(re).fold((()=>{e.each((t=>{U(t.start,r)&&n.set(!0)}));const o=((t,e,n)=>j(t).filter(_).map((r=>({depth:e,dirty:!1,isSelected:n,content:ae(t),itemAttributes:it(t),listAttributes:it(r),listType:$(r)}))))(r,t,n.get());e.each((t=>{U(t.end,r)&&n.set(!1)}));const s=z(r).filter(re).map((r=>ce(t,e,n,r))).getOr([]);return o.toArray().concat(s)}),(r=>ce(t,e,n,r))),ce=(t,e,n,r)=>T(F(r),(r=>(re(r)?ce:de)(t+1,e,n,r))),ue=(t,e)=>{const n=le(e);return((t,e)=>{const n=L(e,((e,n)=>n.depth>e.length?((t,e,n)=>{const r=((t,e,n)=>{const r=[];for(let o=0;o{for(let e=1;e{for(let e=0;e{st(t.list,e.listAttributes),st(t.item,e.itemAttributes),G(t.item,e.content)}))})(r,n),o=r,I(E(e),D(o),ee),e.concat(r)})(t,e,n):((t,e,n)=>{const r=e.slice(0,n.depth);return E(r).each((e=>{const r=((t,e,n)=>{const r=M("li",t);return st(r,e),G(r,n),r})(t,n.itemAttributes,n.content);((t,e)=>{Z(t.list,e),t.item=e})(e,r),((t,e)=>{$(t.list)!==e.listType&&(t.list=lt(t.list,e.listType)),st(t.list,e.listAttributes)})(e,n)})),r})(t,e,n)),[]);return D(n).map((t=>t.list))})(t.contentDocument,n).toArray()},me=(t,e,n)=>{const r=((t,e)=>{const n=(t=>{let e=!1;return{get:()=>e,set:t=>{e=t}}})();return b(t,(t=>({sourceList:t,entries:ce(0,e,n,t)})))})(e,(t=>{const e=b(jt(t),R);return I(k(e,m(oe)),k(A(e),m(oe)),((t,e)=>({start:t,end:e})))})(t));S(r,(e=>{((t,e)=>{S(N(t,ie),(t=>((t,e)=>{switch(t){case"Indent":e.depth++;break;case"Outdent":e.depth--;break;case"Flatten":e.depth=0}e.dirty=!0})(e,t)))})(e.entries,n);const r=((t,e)=>T(((t,e)=>{if(0===t.length)return[];{let n=e(t[0]);const r=[];let o=[];for(let s=0,i=t.length;sD(e).exists(se)?ue(t,e):((t,e)=>{const n=le(e);return b(n,(e=>{const n=((t,e)=>{const n=document.createDocumentFragment();return S(t,(t=>{n.appendChild(t.dom)})),R(n)})(e.content);return R(Et(t,n.dom))}))})(t,e))))(t,e.entries);var o;S(r,(e=>{Jt(t,"Indent"===n?"IndentList":"OutdentList",e.dom)})),o=e.sourceList,S(r,(t=>{W(o,t)})),X(e.sourceList)}))},pe=(t,e)=>{const n=nt((t=>{const e=(t=>{const e=Vt(t,t.selection.getStart()),n=N(t.selection.getSelectedBlocks(),ft);return e.toArray().concat(n)})(t);return zt(t,e)})(t)),r=nt((t=>N(jt(t),Ct))(t));let o=!1;if(n.length||r.length){const s=t.selection.getBookmark();me(t,n,e),((t,e,n)=>{S(n,"Indent"===e?Mt:e=>Pt(t,e))})(t,e,r),t.selection.moveToBookmark(s),t.selection.setRng(Ut(t.selection.getRng())),t.nodeChanged(),o=!0}return o},ge=(t,e)=>!(t=>{const e=Ht(t);return Wt(t,e)})(t)&&pe(t,e),he=t=>ge(t,"Indent"),fe=t=>ge(t,"Outdent"),ye=t=>ge(t,"Flatten");var ve=tinymce.util.Tools.resolve("tinymce.dom.BookmarkManager");const Ce=dt.DOM,be=t=>{const e={},n=n=>{let r=t[n?"startContainer":"endContainer"],o=t[n?"startOffset":"endOffset"];if(gt(r)){const t=Ce.create("span",{"data-mce-type":"bookmark"});r.hasChildNodes()?(o=Math.min(o,r.childNodes.length-1),n?r.insertBefore(t,r.childNodes[o]):Ce.insertAfter(t,r.childNodes[o])):r.appendChild(t),r=t,o=0}e[n?"startContainer":"endContainer"]=r,e[n?"startOffset":"endOffset"]=o};return n(!0),t.collapsed||n(),e},Se=t=>{const e=e=>{let n=t[e?"startContainer":"endContainer"],r=t[e?"startOffset":"endOffset"];if(n){if(gt(n)&&n.parentNode){const t=n;r=(t=>{var e;let n=null===(e=t.parentNode)||void 0===e?void 0:e.firstChild,r=0;for(;n;){if(n===t)return r;gt(n)&&"bookmark"===n.getAttribute("data-mce-type")||r++,n=n.nextSibling}return-1})(n),n=n.parentNode,Ce.remove(t),!n.hasChildNodes()&&Ce.isBlock(n)&&n.appendChild(Ce.create("br"))}t[e?"startContainer":"endContainer"]=n,t[e?"startOffset":"endOffset"]=r}};e(!0),e();const n=Ce.createRng();return n.setStart(t.startContainer,t.startOffset),t.endContainer&&n.setEnd(t.endContainer,t.endOffset),Ut(n)},Ne=t=>{switch(t){case"UL":return"ToggleUlList";case"OL":return"ToggleOlList";case"DL":return"ToggleDLList"}},Le=(t,e)=>{ct.each(e,((e,n)=>{t.setAttribute(n,e)}))},Oe=(t,e,n)=>{((t,e,n)=>{const r=n["list-style-type"]?n["list-style-type"]:null;t.setStyle(e,"list-style-type",r)})(t,e,n),((t,e,n)=>{Le(e,n["list-attributes"]),ct.each(t.select("li",e),(t=>{Le(t,n["list-item-attributes"])}))})(t,e,n)},ke=(t,e,n,r)=>{let o=e[n?"startContainer":"endContainer"];const s=e[n?"startOffset":"endOffset"];for(gt(o)&&(o=o.childNodes[Math.min(s,o.childNodes.length-1)]||o),!n&&St(o.nextSibling)&&(o=o.nextSibling);o.parentNode!==r;){const e=o.parentNode;if(Nt(t,o))return o;if(/^(TD|TH)$/.test(e.nodeName))return o;o=e}return o},Te=(t,e,n)=>{const r=t.selection.getRng();let o="LI";const s=Kt(t,t.selection.getStart(!0)),i=t.dom;if("false"===i.getContentEditable(t.selection.getNode()))return;"DL"===(e=e.toUpperCase())&&(o="DT");const a=be(r),l=((t,e,n)=>{const r=[],o=t.dom,s=ke(t,e,!0,n),i=ke(t,e,!1,n);let a;const l=[];for(let t=s;t&&(l.push(t),t!==i);t=t.nextSibling);return ct.each(l,(e=>{var s;if(Nt(t,e))return r.push(e),void(a=null);if(o.isBlock(e)||St(e))return St(e)&&o.remove(e),void(a=null);const i=e.nextSibling;ve.isBookmarkNode(e)&&(ht(i)||Nt(t,i)||!i&&e.parentNode===n)?a=null:(a||(a=o.create("p"),null===(s=e.parentNode)||void 0===s||s.insertBefore(a,e),r.push(a)),a.appendChild(e))})),r})(t,r,s);ct.each(l,(r=>{let s;const a=r.previousSibling,l=r.parentNode;vt(l)||(a&&ht(a)&&a.nodeName===e&&((t,e,n)=>{const r=t.getStyle(e,"list-style-type");let o=n?n["list-style-type"]:"";return o=null===o?"":o,r===o})(i,a,n)?(s=a,r=i.rename(r,o),a.appendChild(r)):(s=i.create(e),l.insertBefore(s,r),s.appendChild(r),r=i.rename(r,o)),((t,e,n)=>{ct.each(["margin","margin-right","margin-bottom","margin-left","margin-top","padding","padding-right","padding-bottom","padding-left","padding-top"],(n=>t.setStyle(e,n,"")))})(i,r),Oe(i,s,n),we(t.dom,s))})),t.selection.setRng(Se(a))},Ae=(t,e,n)=>{return((t,e)=>ht(t)&&t.nodeName===(null==e?void 0:e.nodeName))(e,n)&&((t,e,n)=>t.getStyle(e,"list-style-type",!0)===t.getStyle(n,"list-style-type",!0))(t,e,n)&&(r=n,e.className===r.className);var r},we=(t,e)=>{let n,r=e.nextSibling;if(Ae(t,e,r)){const o=r;for(;n=o.firstChild;)e.appendChild(n);t.remove(o)}if(r=e.previousSibling,Ae(t,e,r)){const o=r;for(;n=o.lastChild;)e.insertBefore(n,e.firstChild);t.remove(o)}},De=t=>"list-style-type"in t,Ee=(t,e,n)=>{const r=Ht(t);if(Zt(t,r))return;const s=(t=>{const e=Ht(t),n=t.selection.getSelectedBlocks();return((t,e)=>a(t)&&1===e.length&&e[0]===t)(e,n)?(t=>N(t.querySelectorAll(_t),ht))(e):N(n,(t=>ht(t)&&e!==t))})(t),i=o(n)?n:{};s.length>0?((t,e,n,r,o)=>{const s=ht(e);if(s&&e.nodeName===r&&!De(o))ye(t);else{Te(t,r,o);const i=be(t.selection.getRng()),a=s?[e,...n]:n;ct.each(a,(e=>{((t,e,n,r)=>{if(e.nodeName!==n){const o=t.dom.rename(e,n);Oe(t.dom,o,r),Jt(t,Ne(n),o)}else Oe(t.dom,e,r),Jt(t,Ne(n),e)})(t,e,r,o)})),t.selection.setRng(Se(i))}})(t,r,s,e,i):((t,e,n,r)=>{if(e!==t.getBody())if(e)if(e.nodeName!==n||De(r)||Qt(e)){const o=be(t.selection.getRng());Oe(t.dom,e,r);const s=t.dom.rename(e,n);we(t.dom,s),t.selection.setRng(Se(o)),Te(t,n,r),Jt(t,Ne(n),s)}else ye(t);else Te(t,n,r),Jt(t,Ne(n),e)})(t,r,e,i)},Be=dt.DOM,xe=(t,e)=>{const n=ct.grep(t.select("ol,ul",e));ct.each(n,(e=>{((t,e)=>{const n=e.parentElement;if(n&&"LI"===n.nodeName&&n.firstChild===e){const r=n.previousSibling;r&&"LI"===r.nodeName?(r.appendChild(e),Ot(t,n)&&Be.remove(n)):Be.setStyle(n,"listStyleType","none")}if(ht(n)){const t=n.previousSibling;t&&"LI"===t.nodeName&&t.appendChild(e)}})(t,e)}))},Ie=(t,e,n,r)=>{let o=e.startContainer;const s=e.startOffset;if(pt(o)&&(n?s0))return o;const i=t.schema.getNonEmptyElements();gt(o)&&(o=Y.getNode(o,s));const a=new tt(o,r);n&&((t,e)=>!!St(e)&&t.isBlock(e.nextSibling)&&!St(e.previousSibling))(t.dom,o)&&a.next();const l=n?a.next.bind(a):a.prev2.bind(a);for(;o=l();){if("LI"===o.nodeName&&!o.hasChildNodes())return o;if(i[o.nodeName])return o;if(pt(o)&&o.data.length>0)return o}return null},Pe=(t,e)=>{const n=e.childNodes;return 1===n.length&&!ht(n[0])&&t.isBlock(n[0])},Me=(t,e,n)=>{let r;const o=e.parentNode;if(!kt(t,e)||!kt(t,n))return;ht(n.lastChild)&&(r=n.lastChild),o===n.lastChild&&St(o.previousSibling)&&t.remove(o.previousSibling);const s=n.lastChild;s&&St(s)&&e.hasChildNodes()&&t.remove(s),Ot(t,n,!0)&&J(R(n)),((t,e,n)=>{let r;const o=Pe(t,n)?n.firstChild:n;if(((t,e)=>{Pe(t,e)&&t.remove(e.firstChild,!0)})(t,e),!Ot(t,e,!0))for(;r=e.firstChild;)o.appendChild(r)})(t,e,n),r&&n.appendChild(r);const i=((t,e)=>{const n=t.dom,r=e.dom;return n!==r&&n.contains(r)})(R(n),R(e))?t.getParents(e,ht,n):[];t.remove(e),S(i,(e=>{Ot(t,e)&&e!==t.getRoot()&&t.remove(e)}))},Re=(t,e)=>{const n=t.dom,r=t.selection,o=r.getStart(),s=Ft(t,o),i=n.getParent(r.getStart(),"LI",s);if(i){const o=i.parentElement;if(o===t.getBody()&&Ot(n,o))return!0;const a=Ut(r.getRng()),l=n.getParent(Ie(t,a,e,s),"LI",s);if(l&&l!==i)return t.undoManager.transact((()=>{var n,r;e?((t,e,n,r)=>{const o=t.dom;if(o.isEmpty(r))((t,e,n)=>{J(R(n)),Me(t.dom,e,n),t.selection.setCursorLocation(n,0)})(t,n,r);else{const s=be(e);Me(o,n,r),t.selection.setRng(Se(s))}})(t,a,l,i):(null===(r=(n=i).parentNode)||void 0===r?void 0:r.firstChild)===n?fe(t):((t,e,n,r)=>{const o=be(e);Me(t.dom,n,r);const s=Se(o);t.selection.setRng(s)})(t,a,i,l)})),!0;if(!l&&!e&&0===a.startOffset&&0===a.endOffset)return t.undoManager.transact((()=>{ye(t)})),!0}return!1},Ue=t=>{const e=t.selection.getStart(),n=Ft(t,e);return t.dom.getParent(e,"LI,DT,DD",n)||jt(t).length>0},$e=(t,e)=>{const n=t.selection;return!Zt(t,n.getNode())&&(n.isCollapsed()?((t,e)=>Re(t,e)||((t,e)=>{const n=t.dom,r=t.selection.getStart(),o=Ft(t,r),s=n.getParent(r,n.isBlock,o);if(s&&n.isEmpty(s)){const r=Ut(t.selection.getRng()),i=n.getParent(Ie(t,r,e,o),"LI",o);if(i){const a=t=>v(["td","th","caption"],$(t)),l=t=>t.dom===o;return!!((t,e,n=u)=>I(t,e,n).getOr(t.isNone()&&e.isNone()))(q(R(i),a,l),q(R(r.startContainer),a,l),U)&&(t.undoManager.transact((()=>{((t,e,n)=>{const r=t.getParent(e.parentNode,t.isBlock,n);t.remove(e),r&&t.isEmpty(r)&&t.remove(r)})(n,s,o),we(n,i.parentNode),t.selection.select(i,!0),t.selection.collapse(e)})),!0)}}return!1})(t,e))(t,e):(t=>!!Ue(t)&&(t.undoManager.transact((()=>{t.execCommand("Delete"),xe(t.dom,t.getBody())})),!0))(t))},_e=t=>{const e=A(Xt(t).split("")),n=b(e,((t,e)=>{const n=t.toUpperCase().charCodeAt(0)-"A".charCodeAt(0)+1;return Math.pow(26,e)*n}));return L(n,((t,e)=>t+e),0)},He=t=>{if(--t<0)return"";{const e=t%26,n=Math.floor(t/26);return He(n)+String.fromCharCode("A".charCodeAt(0)+e)}},je=t=>{const e=parseInt(t.start,10);return x(t.listStyleType,"upper-alpha")?He(e):x(t.listStyleType,"lower-alpha")?He(e).toLowerCase():t.start},Fe=(t,e)=>()=>{const n=Ht(t);return a(n)&&n.nodeName===e},Ke=t=>{t.addCommand("mceListProps",(()=>{(t=>{const e=Ht(t);yt(e)&&!Zt(t,e)&&t.windowManager.open({title:"List Properties",body:{type:"panel",items:[{type:"input",name:"start",label:"Start list at number",inputMode:"numeric"}]},initialData:{start:je({start:t.dom.getAttrib(e,"start","1"),listStyleType:g.from(t.dom.getStyle(e,"list-style-type"))})},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],onSubmit:e=>{(t=>{switch((t=>/^[0-9]+$/.test(t)?2:/^[A-Z]+$/.test(t)?0:/^[a-z]+$/.test(t)?1:t.length>0?4:3)(t)){case 2:return g.some({listStyleType:g.none(),start:t});case 0:return g.some({listStyleType:g.some("upper-alpha"),start:_e(t).toString()});case 1:return g.some({listStyleType:g.some("lower-alpha"),start:_e(t).toString()});case 3:return g.some({listStyleType:g.none(),start:""});case 4:return g.none()}})(e.getData().start).each((e=>{t.execCommand("mceListUpdate",!1,{attrs:{start:"1"===e.start?"":e.start},styles:{"list-style-type":e.listStyleType.getOr("")}})})),e.close()}})})(t)}))},Ve=(t,e)=>n=>Gt(t,(r=>{n.setActive(qt(r.parents,e)),n.setEnabled(!Zt(t,r.element))})),ze=(t,e)=>n=>Gt(t,(r=>n.setEnabled(qt(r.parents,e)&&!Zt(t,r.element))));t.add("lists",(t=>((t=>{(0,t.options.register)("lists_indent_on_tab",{processor:"boolean",default:!0})})(t),t.hasPlugin("rtc",!0)?Ke(t):((t=>{At(t)&&(t=>{t.on("keydown",(e=>{e.keyCode!==et.TAB||et.metaKeyPressed(e)||t.undoManager.transact((()=>{(e.shiftKey?fe(t):he(t))&&e.preventDefault()}))}))})(t),(t=>{t.on("ExecCommand",(e=>{const n=e.command.toLowerCase();"delete"!==n&&"forwarddelete"!==n||!Ue(t)||xe(t.dom,t.getBody())})),t.on("keydown",(e=>{e.keyCode===et.BACKSPACE?$e(t,!1)&&e.preventDefault():e.keyCode===et.DELETE&&$e(t,!0)&&e.preventDefault()}))})(t)})(t),(t=>{t.on("BeforeExecCommand",(e=>{const n=e.command.toLowerCase();"indent"===n?he(t):"outdent"===n&&fe(t)})),t.addCommand("InsertUnorderedList",((e,n)=>{Ee(t,"UL",n)})),t.addCommand("InsertOrderedList",((e,n)=>{Ee(t,"OL",n)})),t.addCommand("InsertDefinitionList",((e,n)=>{Ee(t,"DL",n)})),t.addCommand("RemoveList",(()=>{ye(t)})),Ke(t),t.addCommand("mceListUpdate",((e,n)=>{o(n)&&((t,e)=>{const n=Ht(t);null===n||Zt(t,n)||t.undoManager.transact((()=>{o(e.styles)&&t.dom.setStyles(n,e.styles),o(e.attrs)&&ot(e.attrs,((e,r)=>t.dom.setAttrib(n,r,e)))}))})(t,n)})),t.addQueryStateHandler("InsertUnorderedList",Fe(t,"UL")),t.addQueryStateHandler("InsertOrderedList",Fe(t,"OL")),t.addQueryStateHandler("InsertDefinitionList",Fe(t,"DL"))})(t)),(t=>{const e=e=>()=>t.execCommand(e);t.hasPlugin("advlist")||(t.ui.registry.addToggleButton("numlist",{icon:"ordered-list",active:!1,tooltip:"Numbered list",onAction:e("InsertOrderedList"),onSetup:Ve(t,"OL")}),t.ui.registry.addToggleButton("bullist",{icon:"unordered-list",active:!1,tooltip:"Bullet list",onAction:e("InsertUnorderedList"),onSetup:Ve(t,"UL")}))})(t),(t=>{const e={text:"List properties...",icon:"ordered-list",onAction:()=>t.execCommand("mceListProps"),onSetup:ze(t,"OL")};t.ui.registry.addMenuItem("listprops",e),t.ui.registry.addContextMenu("lists",{update:e=>{const n=Ht(t,e);return yt(n)?["listprops"]:[]}})})(t),(t=>({backspaceDelete:e=>{$e(t,e)}}))(t))))}(); \ No newline at end of file diff --git a/static/js/tinymce/plugins/media/plugin.min.js b/static/js/tinymce/plugins/media/plugin.min.js new file mode 100644 index 0000000..bcd600b --- /dev/null +++ b/static/js/tinymce/plugins/media/plugin.min.js @@ -0,0 +1,4 @@ +/** + * TinyMCE version 6.2.0 (2022-09-08) + */ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(r=a=e,(o=String).prototype.isPrototypeOf(r)||(null===(s=a.constructor)||void 0===s?void 0:s.name)===o.name)?"string":t;var r,a,o,s})(t)===e,r=t("string"),a=t("object"),o=t("array"),s=e=>!(e=>null==e)(e);class i{constructor(e,t){this.tag=e,this.value=t}static some(e){return new i(!0,e)}static none(){return i.singletonNone}fold(e,t){return this.tag?t(this.value):e()}isSome(){return this.tag}isNone(){return!this.tag}map(e){return this.tag?i.some(e(this.value)):i.none()}bind(e){return this.tag?e(this.value):i.none()}exists(e){return this.tag&&e(this.value)}forall(e){return!this.tag||e(this.value)}filter(e){return!this.tag||e(this.value)?this:i.none()}getOr(e){return this.tag?this.value:e}or(e){return this.tag?this:e}getOrThunk(e){return this.tag?this.value:e()}orThunk(e){return this.tag?this:e()}getOrDie(e){if(this.tag)return this.value;throw new Error(null!=e?e:"Called getOrDie on None")}static from(e){return s(e)?i.some(e):i.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(e){this.tag&&e(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}i.singletonNone=new i(!1);const n=Array.prototype.push,c=(e,t)=>{for(let r=0,a=e.length;r{const t=[];for(let r=0,a=e.length;rh(e,t)?i.from(e[t]):i.none(),h=(e,t)=>u.call(e,t),p=e=>t=>t.options.get(e),g=p("audio_template_callback"),b=p("video_template_callback"),w=p("iframe_template_callback"),v=p("media_live_embeds"),f=p("media_filter_html"),y=p("media_url_resolver"),x=p("media_alt_source"),_=p("media_poster"),j=p("media_dimensions");var k=tinymce.util.Tools.resolve("tinymce.util.Tools"),O=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),A=tinymce.util.Tools.resolve("tinymce.html.DomParser");const S=O.DOM,C=e=>e.replace(/px$/,""),D=e=>{const t=e.attr("style"),r=t?S.parseStyle(t):{};return{type:"ephox-embed-iri",source:e.attr("data-ephox-embed-iri"),altsource:"",poster:"",width:d(r,"max-width").map(C).getOr(""),height:d(r,"max-height").map(C).getOr("")}},T=(e,t)=>{let r={};for(let a=A({validate:!1,forced_root_block:!1},t).parse(e);a;a=a.walk())if(1===a.type){const e=a.name;if(a.attr("data-ephox-embed-iri")){r=D(a);break}r.source||"param"!==e||(r.source=a.attr("movie")),"iframe"!==e&&"object"!==e&&"embed"!==e&&"video"!==e&&"audio"!==e||(r.type||(r.type=e),r=k.extend(a.attributes.map,r)),"script"===e&&(r={type:"script",source:a.attr("src")}),"source"===e&&(r.source?r.altsource||(r.altsource=a.attr("src")):r.source=a.attr("src")),"img"!==e||r.poster||(r.poster=a.attr("src"))}return r.source=r.source||r.src||"",r.altsource=r.altsource||"",r.poster=r.poster||"",r},$=e=>{var t;const r=null!==(t=e.toLowerCase().split(".").pop())&&void 0!==t?t:"";return d({mp3:"audio/mpeg",m4a:"audio/x-m4a",wav:"audio/wav",mp4:"video/mp4",webm:"video/webm",ogg:"video/ogg",swf:"application/x-shockwave-flash"},r).getOr("")};var z=tinymce.util.Tools.resolve("tinymce.html.Node"),M=tinymce.util.Tools.resolve("tinymce.html.Serializer");const F=(e,t={})=>A({forced_root_block:!1,validate:!1,allow_conditional_comments:!0,...t},e),N=O.DOM,R=e=>/^[0-9.]+$/.test(e)?e+"px":e,U=(e,t)=>{const r=t.attr("style"),a=r?N.parseStyle(r):{};s(e.width)&&(a["max-width"]=R(e.width)),s(e.height)&&(a["max-height"]=R(e.height)),t.attr("style",N.serializeStyle(a))},P=["source","altsource"],E=(e,t,r,a)=>{let o=0,s=0;const i=F(a);i.addNodeFilter("source",(e=>o=e.length));const n=i.parse(e);for(let e=n;e;e=e.walk())if(1===e.type){const a=e.name;if(e.attr("data-ephox-embed-iri")){U(t,e);break}switch(a){case"video":case"object":case"embed":case"img":case"iframe":void 0!==t.height&&void 0!==t.width&&(e.attr("width",t.width),e.attr("height",t.height))}if(r)switch(a){case"video":e.attr("poster",t.poster),e.attr("src",null);for(let r=o;r<2;r++)if(t[P[r]]){const a=new z("source",1);a.attr("src",t[P[r]]),a.attr("type",t[P[r]+"mime"]||null),e.append(a)}break;case"iframe":e.attr("src",t.source);break;case"object":const r=e.getAll("img").length>0;if(t.poster&&!r){e.attr("src",t.poster);const r=new z("img",1);r.attr("src",t.poster),r.attr("width",t.width),r.attr("height",t.height),e.append(r)}break;case"source":if(s<2&&(e.attr("src",t[P[s]]),e.attr("type",t[P[s]+"mime"]||null),!t[P[s]])){e.remove();continue}s++;break;case"img":t.poster||e.remove()}}return M({},a).serialize(n)},L=[{regex:/youtu\.be\/([\w\-_\?&=.]+)/i,type:"iframe",w:560,h:314,url:"www.youtube.com/embed/$1",allowFullscreen:!0},{regex:/youtube\.com(.+)v=([^&]+)(&([a-z0-9&=\-_]+))?/i,type:"iframe",w:560,h:314,url:"www.youtube.com/embed/$2?$4",allowFullscreen:!0},{regex:/youtube.com\/embed\/([a-z0-9\?&=\-_]+)/i,type:"iframe",w:560,h:314,url:"www.youtube.com/embed/$1",allowFullscreen:!0},{regex:/vimeo\.com\/([0-9]+)/,type:"iframe",w:425,h:350,url:"player.vimeo.com/video/$1?title=0&byline=0&portrait=0&color=8dc7dc",allowFullscreen:!0},{regex:/vimeo\.com\/(.*)\/([0-9]+)/,type:"iframe",w:425,h:350,url:"player.vimeo.com/video/$2?title=0&byline=0",allowFullscreen:!0},{regex:/maps\.google\.([a-z]{2,3})\/maps\/(.+)msid=(.+)/,type:"iframe",w:425,h:350,url:'maps.google.com/maps/ms?msid=$2&output=embed"',allowFullscreen:!1},{regex:/dailymotion\.com\/video\/([^_]+)/,type:"iframe",w:480,h:270,url:"www.dailymotion.com/embed/video/$1",allowFullscreen:!0},{regex:/dai\.ly\/([^_]+)/,type:"iframe",w:480,h:270,url:"www.dailymotion.com/embed/video/$1",allowFullscreen:!0}],I=(e,t)=>{const r=(e=>{const t=e.match(/^(https?:\/\/|www\.)(.+)$/i);return t&&t.length>1?"www."===t[1]?"https://":t[1]:"https://"})(t),a=e.regex.exec(t);let o=r+e.url;if(s(a))for(let e=0;ea[e]?a[e]:""));return o.replace(/\?$/,"")},B=(e,t)=>{var r;const a=k.extend({},t);if(!a.source&&(k.extend(a,T(null!==(r=a.embed)&&void 0!==r?r:"",e.schema)),!a.source))return"";a.altsource||(a.altsource=""),a.poster||(a.poster=""),a.source=e.convertURL(a.source,"source"),a.altsource=e.convertURL(a.altsource,"source"),a.sourcemime=$(a.source),a.altsourcemime=$(a.altsource),a.poster=e.convertURL(a.poster,"poster");const o=(e=>{const t=L.filter((t=>t.regex.test(e)));return t.length>0?k.extend({},t[0],{url:I(t[0],e)}):null})(a.source);if(o&&(a.source=o.url,a.type=o.type,a.allowfullscreen=o.allowFullscreen,a.width=a.width||String(o.w),a.height=a.height||String(o.h)),a.embed)return E(a.embed,a,!0,e.schema);{const t=g(e),r=b(e),o=w(e);return a.width=a.width||"300",a.height=a.height||"150",k.each(a,((t,r)=>{a[r]=e.dom.encode(""+t)})),"iframe"===a.type?((e,t)=>{if(t)return t(e);{const t=e.allowfullscreen?' allowFullscreen="1"':"";return'"}})(a,o):"application/x-shockwave-flash"===a.sourcemime?(e=>{let t='';return e.poster&&(t+=''),t+="",t})(a):-1!==a.sourcemime.indexOf("audio")?((e,t)=>t?t(e):'")(a,t):"script"===a.type?(e=>' + + + + +{% endblock %} diff --git a/templates/archive.html b/templates/archive.html new file mode 100644 index 0000000..9eb02cb --- /dev/null +++ b/templates/archive.html @@ -0,0 +1,25 @@ +{% extends "layouts/default.html" %} +{% block title %}{{system-data.first.site-name}}: Archive Index{% endblock %} +{% block content %} +
    +

    Archive Index

    + + + +
      + {% for entry in archive-entries %} +
    • + + {{entry.title}} + +

      + {{entry.month}} {{entry.year}} +

      +
    • + {% endfor %} +
    +
    + +{% endblock %} diff --git a/templates/danger/manage-db-entries.html b/templates/danger/manage-db-entries.html new file mode 100644 index 0000000..53ac12d --- /dev/null +++ b/templates/danger/manage-db-entries.html @@ -0,0 +1,111 @@ +{% extends "layouts/default.html" %} +{% block title %}Nicola Ellis & Ritherdon Archive{% endblock %} +{% block content %} +
    +

    Delete Database Entries

    +

    + Warning: Deleting entries from the database might leave + the site's in an un-recoverable state. +

    +

    Archive Files

    +
    + {% for item in archive-entries %} +
    + {% if roles.administrator %} +
    + + + + +
    +

    {{item.title}}

    + {% endif %} +
    + {% endfor %} +
    + +

    Pages Files

    +
    + {% for item in pages-entries %} +
    + {% if roles.administrator %} + {% if item.can-delete == 1 %} +
    + + + + +
    +

    {{item.title}}

    + {% endif %} + {% endif %} +
    + {% endfor %} +
    + +

    Storage Files

    +
    + {% for item in storage-entries %} +
    + {% if roles.administrator %} +
    + + + + +
    +

    {{item.name}}

    + {% endif %} +
    + {% endfor %} +
    +
    +{% endblock %} diff --git a/templates/danger/manage-files.html b/templates/danger/manage-files.html new file mode 100644 index 0000000..767946f --- /dev/null +++ b/templates/danger/manage-files.html @@ -0,0 +1,109 @@ +{% extends "layouts/default.html" %} +{% block title %}Nicola Ellis & Ritherdon Archive{% endblock %} +{% block content %} +
    +

    Delete Files

    +

    + Warning: Deleting files here might leave the site's database + out-of-sync. with the files stored on the server and corrupt the system. +

    +

    Archive Files

    +
    + {% for item in archive-files %} +
    + {% if roles.administrator %} +
    + + + + +
    +

    {{item}}

    + {% endif %} +
    + {% endfor %} +
    + +

    Pages Files

    +
    + {% for item in pages-files %} +
    + {% if roles.administrator %} +
    + + + + +
    +

    {{item}}

    + {% endif %} +
    + {% endfor %} +
    + +

    Storage Files

    +
    + {% for item in media-files %} +
    + {% if roles.administrator %} +
    + + + + +
    +

    {{item}}

    + {% endif %} +
    + {% endfor %} +
    +
    +{% endblock %} diff --git a/templates/danger/snapshots.html b/templates/danger/snapshots.html new file mode 100644 index 0000000..e5e6675 --- /dev/null +++ b/templates/danger/snapshots.html @@ -0,0 +1,143 @@ +{% extends "layouts/default.html" %} +{% block title %}Nicola Ellis & Ritherdon Archive{% endblock %} +{% block content %} +
    +

    Snapshots (not Back-ups)

    +

    + Warning: Restoring the website from a snapshot will + delete all data added to the website after the Snapshot was taken. +

    +

    + Below is a collection of Snapshots taken of the website's data (database, + Pages, Archive Entries and Storage Files). You can download them or + restore the website from a snapshot. +

    +

    + Note: + These Snapshots are not a back-up. If the server goes down, the + Snapshots go with it. I recommend you download the Snapshots at regular + intervals and use those as the site's back-ups. +

    +
    + + +
    + +
    +
    + + + +
    +
    + +

    + Note: + + If you see a 'successful upload' alert message, after using the + Multi-File Upload box above, you might not see any Snapshots + appear down below. This is because you can upload multiple files + at once. + + + The website will ignore any files which have the same name + as any of the Snapshots below or are not a .zip file. + + + The system is relaying how the upload went and not the + validity of the files you uploaded. In other words, the website + recognised the files you uploaded and their file-types; It just + ignored the 'irrelevant' ones. + +

    + +
    + {% for item in snapshots %} +
    +
    + + + +
    + +
    + + + +
    + +

    {{item}}

    + +
    + + + +
    +
    + {% endfor %} +
    +
    +{% endblock %} diff --git a/templates/index.html b/templates/index.html index 6a3c687..1e12b2d 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1,7 +1,7 @@ {% extends "layouts/default.html" %} -{% block title %}Welcome to Caveman2{% endblock %} +{% block title %}{{system-data.first.site-name}}{% endblock %} {% block content %} -
    - Welcome to Caveman2! -
    +
    + {{content | safe }} +
    {% endblock %} diff --git a/templates/initial-setup.html b/templates/initial-setup.html new file mode 100644 index 0000000..3f2378a --- /dev/null +++ b/templates/initial-setup.html @@ -0,0 +1,153 @@ + + + + + Set-up your new website. + + + + + + + + + +
    +
    + First Run +

    Let's get your new site up and running...

    +
    +

    + It looks like this is the first time you've started this + website. Fill out the form below and start uploading stuff. +

    +
    +
    + + + +

    + This name will be displayed in the site's header. You + can change this after you've completed this initial + set-up. +

    + + +
    + + +

    + This refers to the URL used by the seach instance this + website calls out to for its search features. If you're + running this on your local dev. machine, use + http://localhost:7700 (this is the + default for port for Meilisearch. +

    + + +
    + +
    + + +
    +

    + Enabling this feature will allow anyone to create an account with + this website, upload files and create 'Archive Entries' and + 'Pages'. You can turn this feature on and off in the site's + settings after this initial set-up. +

    + +
    + +
    + + +
    +

    + Enabling this feature will make the website display the + site's logo in the header, alongside the site's + name. You can turn this feature on and off in the + site's settings, after completing this initial set-up, + and replace the default one with your own. +

    + +
    + +

    Account Details

    +

    + This account is the site's 'admin' (or 'super-user') + account. This gives you complete access to all the + site's features. No other account will have this + ability. +

    + +

    + This is the name you will use to log-in to the + website. It cannot be changed after you finish this + set-up. You can use your email address or a typical + username like 'neo' or 'the_milkman_3000'. Each account + must have a unique username. +

    + + + +

    + This is the name the website will refer to you as when + you log-in. Feel free to use your actual name here and + change it as often as you want. +

    + + + + + + + + +
    +
    +
    + + diff --git a/templates/layouts/default.html b/templates/layouts/default.html index 6dba578..cc23af0 100644 --- a/templates/layouts/default.html +++ b/templates/layouts/default.html @@ -1,11 +1,32 @@ - - - {% block title %}{% endblock %} - - - - {% block content %}{% endblock %} - + + + {% block title %}{% endblock %} + + + + + + + + + {% lisp (insert-snippet "site-wide-snippet.html") %} + + + {% include "/layouts/header.html" %} + {% block content %}{% endblock %} + {% include "/layouts/footer.html" %} + diff --git a/templates/layouts/footer.html b/templates/layouts/footer.html new file mode 100644 index 0000000..5e80a97 --- /dev/null +++ b/templates/layouts/footer.html @@ -0,0 +1,4 @@ +
    +

    © {% lisp (local-time:timestamp-year (local-time:now)) %} Nicola Ellis

    +
    + diff --git a/templates/layouts/header.html b/templates/layouts/header.html new file mode 100644 index 0000000..d283b26 --- /dev/null +++ b/templates/layouts/header.html @@ -0,0 +1,165 @@ +{% if roles.logged-in %} +
    + + + +
    +{% endif %} + +{% if roles.logged-in %} +
    + +
    +

    Accounts and Settings

    + + Edit Profile + My Account Details + + {% if roles.administrator %} + + Manage Accounts + Manage Accounts + + + Site Settings + Site Settings + + {% endif %} +
    +
    +
    + + +
    +
    +
    +{% endif %} + +
    + {% if alert %} +
    + {{alert | safe}} + +
    + {% endif %} + + + + diff --git a/templates/page.html b/templates/page.html new file mode 100644 index 0000000..3faebeb --- /dev/null +++ b/templates/page.html @@ -0,0 +1,71 @@ +{% extends "layouts/default.html" %} +{% block title %}View page.{% endblock %} +{% block content %} +{% if roles.logged-in %} + +{% endif %} + +
    + +
    +
    + +
    + {{data | safe}} +
    + + + + + + + +{% endblock %} diff --git a/templates/pages.html b/templates/pages.html new file mode 100644 index 0000000..d783352 --- /dev/null +++ b/templates/pages.html @@ -0,0 +1,22 @@ +{% extends "layouts/default.html" %} +{% block title %}{{system-data.first.site-name}}: Pages Index{% endblock %} +{% block content %} +
    +

    Pages Index

    + + + +
      + {% for page in pages %} + {% if page.can-delete == 1 %} +
    • + {{page.title}} +
    • + {% endif %} + {% endfor %} +
    +
    + +{% endblock %} diff --git a/templates/search.html b/templates/search.html new file mode 100644 index 0000000..17948f2 --- /dev/null +++ b/templates/search.html @@ -0,0 +1,42 @@ +{% extends "layouts/default.html" %} +{% block title %}Search the Archive{% endblock %} +{% block content %} +
    + +
    + + + +
    +
    +
    + + +

    Year

    +
    +

    Month

    +
    +

    Keywords

    +
    +
    + +
    +
    + +
    +
    +
    + +
    + + + + + + + + +{% endblock %} diff --git a/templates/sign-up.html b/templates/sign-up.html new file mode 100644 index 0000000..57ba89c --- /dev/null +++ b/templates/sign-up.html @@ -0,0 +1,54 @@ +{% extends "layouts/default.html" %} +{% block title %}Create a new account{% endblock %} +{% block content %} +
    +

    Create Your New Account

    +
    + + +

    + Enter your email address or create a unique name to log into the + website. You can not change this after you've created your + account. +

    + + +

    + Your display name is how the website will refer to you whilst + logged-in. You can change this after you've logged into the + website. +

    + + + + +

    + Re-enter your password here to make sure you haven't misspelt it. +

    + + +
    +
    +{% endblock %} diff --git a/templates/user/archive.html b/templates/user/archive.html new file mode 100644 index 0000000..a3526a1 --- /dev/null +++ b/templates/user/archive.html @@ -0,0 +1,83 @@ +{% extends "layouts/default.html" %} +{% block title %}Manage the site's archive.{% endblock %} +{% block content %} +
    +
    +

    Archive Index

    + + + +
    + {% for entry in archive-entries %} +
    +
    + {{entry.title}} +

    {{entry.title}}

    +
    +
    + + {{entry.title}} + + + {{entry.title}} + + {% if roles.administrator %} +
    + + + +
    + {% endif %} +
    +
    + {% endfor %} +
    +
    +
    +{% endblock %} diff --git a/templates/user/create-archive.html b/templates/user/create-archive.html new file mode 100644 index 0000000..cd9a93e --- /dev/null +++ b/templates/user/create-archive.html @@ -0,0 +1,123 @@ +{% extends "layouts/default.html" %} +{% block title %}Create a new archive entry{% endblock %} +{% block content %} +
    +

    Create Archive Entry

    + + + + + + + +
    + + + +
    + + + + +
    +
    + +

    + Use a comma to seperate keywords (E.G. 'art,welding,green paint,metal'). + Words seperated by a space and not a comma are marked as one keyword. + So, 'green paint' is one keyword not two in this example. +

    + + + + + +
    +
    +{% endblock %} diff --git a/templates/user/create-page.html b/templates/user/create-page.html new file mode 100644 index 0000000..f5d9850 --- /dev/null +++ b/templates/user/create-page.html @@ -0,0 +1,77 @@ +{% extends "layouts/default.html" %} +{% block title %}Users{% endblock %} +{% block content %} +
    +

    Create Page

    + + + + + + + +
    + + + + + +
    +
    +{% endblock %} diff --git a/templates/user/dashboard.html b/templates/user/dashboard.html new file mode 100644 index 0000000..522d4aa --- /dev/null +++ b/templates/user/dashboard.html @@ -0,0 +1,248 @@ +{% extends "layouts/default.html" %} +{% block title %}Manage you archive.{% endblock %} +{% block content %} +
    +
    +
    + profile Cat +

    {{user.display-name}}

    +
    +

    + Total: {{disk-info.fourth}} | + Free: {{disk-info.sixth}} | + Available: {{disk-info.eighth}} | + Used: {{disk-info.tenth}}% +

    +
    + + + +
    +

    Storage

    + +
    +
    +
    + + + +
    +
    +
    + +
    + {% for item in storage-files %} +
    +
    + {{item.name}} +

    {{item.name | safe}}

    +
    +
    + + {{item.name}} + + {% if roles.administrator %} +
    + + +
    + {% endif %} +
    +
    + {% endfor %} +
    +
    + +
    +

    Archive

    + +
    + {% for entry in archive-entries %} +
    +

    {{entry.title | safe}}

    +
    + + {{entry.title}} + + + Edit {{entry.title}} + + {% if roles.administrator %} +
    + + + +
    + {% endif %} +
    +
    + {% endfor %} +
    +
    + +
    +

    Pages

    + +
    + {% for page in pages %} + {% if page.can-delete == 1 %} +
    +

    {{page.title | safe}}

    +
    + + {{page.title}} + + + Edit {{page.title}} + + {% if roles.administrator %} +
    + + + +
    + {% endif %} +
    +
    + {% endif %} + {% endfor %} +
    +
    + +
    +
    +

    Accounts and Settings

    + + Edit Profile + My Account Details + + {% if roles.administrator %} + + Manage Accounts + Manage Accounts + + + Site Settings + Site Settings + + {% endif %} +
    +
    +
    +{% endblock %} diff --git a/templates/user/edit-archive.html b/templates/user/edit-archive.html new file mode 100644 index 0000000..0f76110 --- /dev/null +++ b/templates/user/edit-archive.html @@ -0,0 +1,222 @@ +{% extends "layouts/default.html" %} +{% block title %}Edit: {{db-data.title}}{% endblock %} +{% block content %} +
    +

    Edit Archive Entry

    + + + + + + + +
    + + +
    + {{db-data.title}} + + +
    +
    + +
    + + + + +
    + + +
    +
    + +
    + + +
    + + + + + +
    +
    + +
    + + + +

    + Use a comma to seperate keywords (E.G. 'art,welding,green paint,metal'). + Words seperated by a space and not a comma are marked as one keyword. + So, 'green paint' is one keyword not two in this example. +

    +
    + + +
    +
    + +
    + + + +
    +
    +{% endblock %} diff --git a/templates/user/edit-page.html b/templates/user/edit-page.html new file mode 100644 index 0000000..8d84479 --- /dev/null +++ b/templates/user/edit-page.html @@ -0,0 +1,147 @@ +{% extends "layouts/default.html" %} +{% block title %}Edit: {{title}}{% endblock %} +{% block content %} +
    +

    Edit Page

    + + + + + + + +
    + + +
    + + + +
    +
    + +
    + + + + +
    + + +
    +
    + +
    + + + +
    +
    +{% endblock %} diff --git a/templates/user/edit.html b/templates/user/edit.html new file mode 100644 index 0000000..85038d1 --- /dev/null +++ b/templates/user/edit.html @@ -0,0 +1,104 @@ +{% extends "layouts/default.html" %} +{% block title%}Edit your accout settings.{%endblock%} +{% block content %} +
    +

    Edit Account

    + +
    + + View Dashboard + View Dashboard + + {% if roles.administrator %} + + Manage Accounts + Manage Accounts + + {% endif %} +
    + +
    + + +

    + Your 'username' is what you use to login to the + website. That cannot be changed. Your 'display name' is + the name used in places like your Dashboard. +

    + + +
    + +
    + + + + + + +
    + +

    Delete Account

    +

    + Warning: This cannot be undone. Enter '{{user.username}}' in + the text box below before clicking 'Delete Account' to confirm + deletion. +

    +
    + + + +
    + +
    +{% endblock %} diff --git a/templates/user/index.html b/templates/user/index.html new file mode 100644 index 0000000..a749141 --- /dev/null +++ b/templates/user/index.html @@ -0,0 +1,118 @@ +{% extends "layouts/default.html" %} +{% block title %}Users{% endblock %} +{% block content %} +
    + +

    Account Management

    + + + +

    Create New Account

    +

    + New users can only create 'pages' and 'archive entries'. They + cannot edit or delete them. +

    +
    + + + + + + + + + + +
    + +

    User Acccounts

    + {% for account in users %} + {% if account.username != user.username %} +
    +
    + + + +

    + {{account.username}} +
    + {{account.display-name}} +

    +
    + +
    + + + + + +
    + +
    + + {% endif %} + {% endfor %} +
    +{% endblock %} diff --git a/templates/user/log-in.html b/templates/user/log-in.html new file mode 100644 index 0000000..d546b61 --- /dev/null +++ b/templates/user/log-in.html @@ -0,0 +1,31 @@ +{% extends "layouts/default.html" %} +{% block title%}Log-in and start doing stuff.{%endblock%} +{% block content %} +
    + +
    +{% endblock %} diff --git a/templates/user/pages.html b/templates/user/pages.html new file mode 100644 index 0000000..88e08ca --- /dev/null +++ b/templates/user/pages.html @@ -0,0 +1,84 @@ +{% extends "layouts/default.html" %} +{% block title %}A list of the site's pages.{% endblock %} +{% block content %} +
    +
    +

    Pages Index

    + + + +
    + {% for page in pages %} + {% if page.can-delete == 1 %} +
    +

    {{page.title}}

    +
    + + {{page.title}} + + + {{entry.title}} + + {% if roles.administrator %} +
    + + + +
    + {% endif %} +
    +
    + {% endif %} + {% endfor %} +
    +
    +
    +{% endblock %} diff --git a/templates/user/site-settings.html b/templates/user/site-settings.html new file mode 100644 index 0000000..7a1efd6 --- /dev/null +++ b/templates/user/site-settings.html @@ -0,0 +1,403 @@ +{% extends "layouts/default.html" %} +{% block title %}Nicola Ellis & Ritherdon Archive{% endblock %} +{% block content %} +
    +

    Site Settings

    + +
    + + Dashboard + View Dashboard + + + My Account + My Account + + {% if roles.administrator %} + + Manage Accounts + Manage Accounts + + {% endif %} +
    + +

    Site Name

    +
    + +
    + + +
    +
    + +
    + +

    Search URL

    +
    + +

    + This is the URL for the search service used by this + website. The default URL is http://localhost:7700. You + would normally use that when on running this website on your + local dev. machine. +

    +
    + + +
    +
    + +
    + +

    Home Page

    +

    + Only 'Pages' can be used for the Home page. 'Archive Entries' + cannot be used because of how the website is designed. +

    +
    + +

    Currently set to: {{settings.home-page}}

    +
    + + +
    +
    + +
    + +

    Site Logo

    +
    + +
    + Site Logo + + +
    +
    + +
    + +
    + + + +
    +
    + +
    + +

    Sign-Up

    +

    + Enabling this setting allows anyone to create account. If this + setting is disabled you can still create accounts via the + 'Manage Accounts' link above. +

    +
    + +
    + + + +
    +
    + +
    + +

    Navigation Menu

    +

    + This is the list of links at the top of the page and is viewable by + everyone. The nav. menu can only consist of 'Pages', no 'Archive + Entries' can be selected for this menu. +

    +
    + + {% for page in pages %} +
    + + + +
    + {% endfor %} +
    + +
    + +
    + +

    Favicon

    +

    + A Favicon is the little image in the browser tab. You might need to + press 'Shift + F5' if you cannot see the new file. +

    +
    + +
    + Favicon + + +
    +
    + +
    + +

    Site-Wide Code Snippet

    +

    + Enter HTML and JavaScript in the text box below and it will be added to + each Page and Archive Entry automatically. The intended use-case for + this is adding a snippet provided by Umami to track page views, device + types and which country the viewer is in. If you are unsure what any of + that means, just ignore this section. +

    +
    + + + +
    + +
    + + {% if roles.administrator %} +
    +

    Danger Zone

    +

    + Be careful here. You can break the website and lose data. +

    + +

    + This is a link -- nothing is deleted if you press this. Use + this to rename/delete files which are out-of-sync. with the site's + database. +

    + + Manage files + Manage Files + + +
    + +

    + This is a link -- nothing is deleted if you press this. Use + this to delete Archive Entries and Pages stored in the database when + the files it is tracking cannot be found. +

    + + Delete DB entries + Delete Database Entries + + +
    + +

    + If you find Archive Entry thumbnails are no longer loading or + you're seeing '404' errors when clicking throught to an Archive + Entry, click the button below to re-sync. this website's + database with the 'Search Service' database. +

    + +
    + +
    + +

    + This deletes all the User Accounts, Pages, Archive Entries and + files you've uploaded to Storage. Use this if you want to wipe + the site clean and start again. It, also, clears the 'Search + Service' database. +

    + +
    + +

    + + This is a link -- nothing is deleted if you press + this. + + Use this to manage the website's Snapshots (a versioned copy of the + website's data). + + Do not treat these as back-ups until they are off the server. + +

    + + Manage Snapshots + Manage Snapshots + +
    + {% endif %} +
    +{% endblock %} diff --git a/templates/user/storage.html b/templates/user/storage.html new file mode 100644 index 0000000..79ae35b --- /dev/null +++ b/templates/user/storage.html @@ -0,0 +1,114 @@ +{% extends "layouts/default.html" %} +{% block title %}Manage you archive.{% endblock %} +{% block content %} +
    +

    Storage Index

    + + + +
    +
    + + + +
    +
    + +
    + {% for item in files %} +
    + {{item.name}} + + {{entry.title}} + +
    + + Copied + + +
    + {% if roles.administrator %} +
    + + + +
    +
    + + +
    + {% endif %} +
    + {% endfor %} +
    +
    +{% endblock %} diff --git a/tests/ritherdon-archive.lisp b/tests/ritherdon-archive.lisp deleted file mode 100644 index c3504a8..0000000 --- a/tests/ritherdon-archive.lisp +++ /dev/null @@ -1,12 +0,0 @@ -(in-package :cl-user) -(defpackage ritherdon-archive-test - (:use :cl - :ritherdon-archive - :prove)) -(in-package :ritherdon-archive-test) - -(plan nil) - -;; blah blah blah. - -(finalize) diff --git a/tests/tests.lisp b/tests/tests.lisp new file mode 100644 index 0000000..d07b2b4 --- /dev/null +++ b/tests/tests.lisp @@ -0,0 +1,18 @@ +(defpackage #:tests + (:use #:cl + #:parachute)) +(in-package #:tests) +#| parachute: https://shinmera.github.io/parachute/ +================================================================================ +Use the URL to access the documentation for parachute. +|# + +;; This was an example taken from the doc's for parachute. I'm going to keep it +;; here as a reference until I get comfortable with parachute. +(define-test reference-tests + (of-type integer 5) + (true (numberp 2/3)) + (false (numberp :keyword)) + (is-values (values 0 "1") + (= 0) + (equal "1")))