Merge branch 'friendica:develop' into feature-openwebauth
This commit is contained in:
commit
2a98e71b16
29 changed files with 15170 additions and 153 deletions
11
src/App.php
11
src/App.php
|
|
@ -335,7 +335,13 @@ class App
|
|||
*/
|
||||
protected function load(DbaDefinition $dbaDefinition, ViewDefinition $viewDefinition)
|
||||
{
|
||||
set_time_limit(0);
|
||||
if ($this->config->get('system', 'ini_max_execution_time') !== false) {
|
||||
set_time_limit((int)$this->config->get('system', 'ini_max_execution_time'));
|
||||
}
|
||||
|
||||
if ($this->config->get('system', 'ini_pcre_backtrack_limit') !== false) {
|
||||
ini_set('pcre.backtrack_limit', (int)$this->config->get('system', 'ini_pcre_backtrack_limit'));
|
||||
}
|
||||
|
||||
// Normally this constant is defined - but not if "pcntl" isn't installed
|
||||
if (!defined('SIGTERM')) {
|
||||
|
|
@ -345,9 +351,6 @@ class App
|
|||
// Ensure that all "strtotime" operations do run timezone independent
|
||||
date_default_timezone_set('UTC');
|
||||
|
||||
// This has to be quite large to deal with embedded private photos
|
||||
ini_set('pcre.backtrack_limit', 500000);
|
||||
|
||||
set_include_path(
|
||||
get_include_path() . PATH_SEPARATOR
|
||||
. $this->getBasePath() . DIRECTORY_SEPARATOR . 'include' . PATH_SEPARATOR
|
||||
|
|
|
|||
|
|
@ -365,6 +365,7 @@ class Conversation
|
|||
'$editalic' => $this->l10n->t('Italic'),
|
||||
'$eduline' => $this->l10n->t('Underline'),
|
||||
'$edquote' => $this->l10n->t('Quote'),
|
||||
'$edemojis' => $this->l10n->t('Add emojis'),
|
||||
'$edcode' => $this->l10n->t('Code'),
|
||||
'$edimg' => $this->l10n->t('Image'),
|
||||
'$edurl' => $this->l10n->t('Link'),
|
||||
|
|
|
|||
|
|
@ -3021,6 +3021,7 @@ class Item
|
|||
if (!$is_preview) {
|
||||
$item['body'] = preg_replace("#\s*\[attachment .*?].*?\[/attachment]\s*#ism", "\n", $item['body']);
|
||||
$item['body'] = Post\Media::removeFromEndOfBody($item['body'] ?? '');
|
||||
$item['body'] = Post\Media::replaceImage($item['body']);
|
||||
}
|
||||
|
||||
$body = $item['body'];
|
||||
|
|
@ -3038,6 +3039,7 @@ class Item
|
|||
if (!empty($shared['post'])) {
|
||||
$shared_item = $shared['post'];
|
||||
$shared_item['body'] = Post\Media::removeFromEndOfBody($shared_item['body']);
|
||||
$shared_item['body'] = Post\Media::replaceImage($shared_item['body']);
|
||||
$quote_uri_id = $shared['post']['uri-id'];
|
||||
$shared_links[] = strtolower($shared['post']['uri']);
|
||||
$item['body'] = BBCode::removeSharedData($item['body']);
|
||||
|
|
@ -3141,12 +3143,14 @@ class Item
|
|||
}
|
||||
|
||||
if (!empty($shared_attachments)) {
|
||||
$s = self::addGallery($s, $shared_attachments, $item['uri-id']);
|
||||
$s = self::addVisualAttachments($shared_attachments, $shared_item, $s, true);
|
||||
$s = self::addLinkAttachment($shared_uri_id ?: $item['uri-id'], $shared_attachments, $body, $s, true, $quote_shared_links);
|
||||
$s = self::addNonVisualAttachments($shared_attachments, $item, $s, true);
|
||||
$body = BBCode::removeSharedData($body);
|
||||
}
|
||||
|
||||
$s = self::addGallery($s, $attachments, $item['uri-id']);
|
||||
$s = self::addVisualAttachments($attachments, $item, $s, false);
|
||||
$s = self::addLinkAttachment($item['uri-id'], $attachments, $body, $s, false, $shared_links);
|
||||
$s = self::addNonVisualAttachments($attachments, $item, $s, false);
|
||||
|
|
@ -3196,6 +3200,24 @@ class Item
|
|||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify links to pictures to links for the "Fancybox" gallery
|
||||
*
|
||||
* @param string $s
|
||||
* @param array $attachments
|
||||
* @param integer $uri_id
|
||||
* @return string
|
||||
*/
|
||||
private static function addGallery(string $s, array $attachments, int $uri_id): string
|
||||
{
|
||||
foreach ($attachments['visual'] as $attachment) {
|
||||
if (empty($attachment['preview']) || ($attachment['type'] != Post\Media::IMAGE)) {
|
||||
continue;
|
||||
}
|
||||
$s = str_replace('<a href="' . $attachment['url'] . '"', '<a data-fancybox="' . $uri_id . '" href="' . $attachment['url'] . '"', $s);
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the body contains a link
|
||||
|
|
@ -3259,12 +3281,18 @@ class Item
|
|||
|
||||
foreach ($attachments['visual'] as $attachment) {
|
||||
if (!empty($attachment['preview'])) {
|
||||
if (Network::isLocalLink($attachment['preview'])) {
|
||||
continue;
|
||||
}
|
||||
$proxy = Post\Media::getPreviewUrlForId($attachment['id'], Proxy::SIZE_LARGE);
|
||||
$search = ['[img=' . $attachment['preview'] . ']', ']' . $attachment['preview'] . '[/img]'];
|
||||
$replace = ['[img=' . $proxy . ']', ']' . $proxy . '[/img]'];
|
||||
|
||||
$body = str_replace($search, $replace, $body);
|
||||
} elseif ($attachment['filetype'] == 'image') {
|
||||
if (Network::isLocalLink($attachment['url'])) {
|
||||
continue;
|
||||
}
|
||||
$proxy = Post\Media::getUrlForId($attachment['id']);
|
||||
$search = ['[img=' . $attachment['url'] . ']', ']' . $attachment['url'] . '[/img]'];
|
||||
$replace = ['[img=' . $proxy . ']', ']' . $proxy . '[/img]'];
|
||||
|
|
@ -3344,7 +3372,7 @@ class Item
|
|||
if (self::containsLink($item['body'], $src_url)) {
|
||||
continue;
|
||||
}
|
||||
$images[] = ['src' => $src_url, 'preview' => $preview_url, 'attachment' => $attachment];
|
||||
$images[] = ['src' => $src_url, 'preview' => $preview_url, 'attachment' => $attachment, 'uri_id' => $item['uri-id']];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -478,6 +478,33 @@ class Media
|
|||
return preg_match('#/photos/.*/image/#ism', $page) && preg_match('#/photo/.*-[01]\.#ism', $preview);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the image link in Friendica image posts with a link to the image
|
||||
*
|
||||
* @param string $body
|
||||
* @return string
|
||||
*/
|
||||
public static function replaceImage(string $body): string
|
||||
{
|
||||
if (preg_match_all("#\[url=([^\]]+?)\]\s*\[img=([^\[\]]*)\]([^\[\]]*)\[\/img\]\s*\[/url\]#ism", $body, $pictures, PREG_SET_ORDER)) {
|
||||
foreach ($pictures as $picture) {
|
||||
if (self::isLinkToImagePage($picture[1], $picture[2])) {
|
||||
$body = str_replace($picture[0], '[url=' . str_replace('-1.', '-0.', $picture[2]) . '][img=' . $picture[2] . ']' . $picture[3] . '[/img][/url]', $body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (preg_match_all("#\[url=([^\]]+?)\]\s*\[img\]([^\[]+?)\[/img\]\s*\[/url\]#ism", $body, $pictures, PREG_SET_ORDER)) {
|
||||
foreach ($pictures as $picture) {
|
||||
if (self::isLinkToImagePage($picture[1], $picture[2])) {
|
||||
$body = str_replace($picture[0], '[url=' . str_replace('-1.', '-0.', $picture[2]) . '][img]' . $picture[2] . '[/img][/url]', $body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add media links and remove them from the body
|
||||
*
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ class Edit extends BaseModule
|
|||
'$editalic' => $this->t('Italic'),
|
||||
'$eduline' => $this->t('Underline'),
|
||||
'$edquote' => $this->t('Quote'),
|
||||
'$edemojis' => $this->t('Add emojis'),
|
||||
'$edcode' => $this->t('Code'),
|
||||
'$edurl' => $this->t('Link'),
|
||||
'$edattach' => $this->t('Link or Media'),
|
||||
|
|
|
|||
|
|
@ -1066,6 +1066,7 @@ class Post
|
|||
'$editalic' => DI::l10n()->t('Italic'),
|
||||
'$eduline' => DI::l10n()->t('Underline'),
|
||||
'$edquote' => DI::l10n()->t('Quote'),
|
||||
'$edemojis' => DI::l10n()->t('Add emojis'),
|
||||
'$edcode' => DI::l10n()->t('Code'),
|
||||
'$edimg' => DI::l10n()->t('Image'),
|
||||
'$edurl' => DI::l10n()->t('Link'),
|
||||
|
|
|
|||
|
|
@ -341,6 +341,14 @@ return [
|
|||
// Resolve IPV4 addresses only. Don't resolve to IPV6.
|
||||
'ipv4_resolve' => false,
|
||||
|
||||
// ini_max_execution_time (False|Integer)
|
||||
// Set the number of seconds a script is allowed to run. Default unlimited for Friendica, false to use the system value.
|
||||
'ini_max_execution_time' => 0,
|
||||
|
||||
// ini_pcre_backtrack_limit (False|Integer)
|
||||
// This has to be quite large to deal with embedded private photos. False to use the system value.
|
||||
'ini_pcre_backtrack_limit' => 500000,
|
||||
|
||||
// invitation_only (Boolean)
|
||||
// If set true registration is only possible after a current member of the node has sent an invitation.
|
||||
'invitation_only' => false,
|
||||
|
|
|
|||
62
view/js/fancybox/README.md
Normal file
62
view/js/fancybox/README.md
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# fancyBox 3.5.7
|
||||
|
||||
jQuery lightbox script for displaying images, videos and more.
|
||||
Touch enabled, responsive and fully customizable.
|
||||
|
||||
See the [project page](http://fancyapps.com/fancybox/3/) for documentation and a demonstration.
|
||||
|
||||
Follow [@thefancyapps](//twitter.com/thefancyapps) for updates.
|
||||
|
||||
|
||||
## Quick start
|
||||
|
||||
1\. Add latest jQuery and fancyBox files
|
||||
|
||||
```html
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
|
||||
|
||||
<link href="/path/to/jquery.fancybox.min.css" rel="stylesheet">
|
||||
<script src="/path/to/jquery.fancybox.min.js"></script>
|
||||
```
|
||||
|
||||
|
||||
2\. Create links
|
||||
|
||||
```html
|
||||
<a data-fancybox="gallery" href="big_1.jpg">
|
||||
<img src="small_1.jpg">
|
||||
</a>
|
||||
|
||||
<a data-fancybox="gallery" href="big_2.jpg">
|
||||
<img src="small_2.jpg">
|
||||
</a>
|
||||
```
|
||||
|
||||
|
||||
3\. Enjoy!
|
||||
|
||||
|
||||
## License
|
||||
|
||||
fancyBox is licensed under the [GPLv3](http://choosealicense.com/licenses/gpl-3.0) license for all open source applications.
|
||||
A commercial license is required for all commercial applications (including sites, themes and apps you plan to sell).
|
||||
|
||||
[Read more about fancyBox license](http://fancyapps.com/fancybox/3/#license).
|
||||
|
||||
## Bugs and feature requests
|
||||
|
||||
If you find a bug, please report it [here on Github](https://github.com/fancyapps/fancybox/issues).
|
||||
|
||||
Guidelines for bug reports:
|
||||
|
||||
1. Use the GitHub issue search — check if the issue has already been reported.
|
||||
2. Check if the issue has been fixed — try to reproduce it using the latest master or development branch in the repository.
|
||||
3. Isolate the problem — create a reduced test case and a live example. You can use CodePen to fork any demo found on documentation to use it as a template.
|
||||
|
||||
A good bug report shouldn't leave others needing to chase you up for more information.
|
||||
Please try to be as detailed as possible in your report.
|
||||
|
||||
|
||||
Feature requests are welcome. Please look for existing ones and use GitHub's "reactions" feature to vote.
|
||||
|
||||
Please do not use the issue tracker for personal support requests - use Stack Overflow ([fancybox-3](http://stackoverflow.com/questions/tagged/fancybox-3) tag) instead.
|
||||
13
view/js/fancybox/fancybox.config.js
Normal file
13
view/js/fancybox/fancybox.config.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
$(document).ready(function() {
|
||||
$.fancybox.defaults.loop = "true";
|
||||
// this disables the colorbox hook found in frio/js/modal.js:34
|
||||
$("body").off("click", ".wall-item-body a img");
|
||||
|
||||
// Adds ALT/TITLE text to fancybox
|
||||
$('a[data-fancybox').fancybox({
|
||||
afterLoad : function(instance, current) {
|
||||
current.$image.attr('alt', current.opts.$orig.find('img').attr('alt') );
|
||||
current.$image.attr('title', current.opts.$orig.find('img').attr('title') );
|
||||
}
|
||||
});
|
||||
});
|
||||
895
view/js/fancybox/jquery.fancybox.css
vendored
Normal file
895
view/js/fancybox/jquery.fancybox.css
vendored
Normal file
|
|
@ -0,0 +1,895 @@
|
|||
body.compensate-for-scrollbar {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fancybox-active {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.fancybox-is-hidden {
|
||||
left: -9999px;
|
||||
margin: 0;
|
||||
position: absolute !important;
|
||||
top: -9999px;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.fancybox-container {
|
||||
-webkit-backface-visibility: hidden;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
outline: none;
|
||||
position: fixed;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
top: 0;
|
||||
-ms-touch-action: manipulation;
|
||||
touch-action: manipulation;
|
||||
transform: translateZ(0);
|
||||
width: 100%;
|
||||
z-index: 99992;
|
||||
}
|
||||
|
||||
.fancybox-container * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.fancybox-outer,
|
||||
.fancybox-inner,
|
||||
.fancybox-bg,
|
||||
.fancybox-stage {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.fancybox-outer {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.fancybox-bg {
|
||||
background: rgb(30, 30, 30);
|
||||
opacity: 0;
|
||||
transition-duration: inherit;
|
||||
transition-property: opacity;
|
||||
transition-timing-function: cubic-bezier(.47, 0, .74, .71);
|
||||
}
|
||||
|
||||
.fancybox-is-open .fancybox-bg {
|
||||
opacity: .9;
|
||||
transition-timing-function: cubic-bezier(.22, .61, .36, 1);
|
||||
}
|
||||
|
||||
.fancybox-infobar,
|
||||
.fancybox-toolbar,
|
||||
.fancybox-caption,
|
||||
.fancybox-navigation .fancybox-button {
|
||||
direction: ltr;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
transition: opacity .25s ease, visibility 0s ease .25s;
|
||||
visibility: hidden;
|
||||
z-index: 99997;
|
||||
}
|
||||
|
||||
.fancybox-show-infobar .fancybox-infobar,
|
||||
.fancybox-show-toolbar .fancybox-toolbar,
|
||||
.fancybox-show-caption .fancybox-caption,
|
||||
.fancybox-show-nav .fancybox-navigation .fancybox-button {
|
||||
opacity: 1;
|
||||
transition: opacity .25s ease 0s, visibility 0s ease 0s;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.fancybox-infobar {
|
||||
color: #ccc;
|
||||
font-size: 13px;
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
height: 44px;
|
||||
left: 0;
|
||||
line-height: 44px;
|
||||
min-width: 44px;
|
||||
mix-blend-mode: difference;
|
||||
padding: 0 10px;
|
||||
pointer-events: none;
|
||||
top: 0;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.fancybox-toolbar {
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.fancybox-stage {
|
||||
direction: ltr;
|
||||
overflow: visible;
|
||||
transform: translateZ(0);
|
||||
z-index: 99994;
|
||||
}
|
||||
|
||||
.fancybox-is-open .fancybox-stage {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fancybox-slide {
|
||||
-webkit-backface-visibility: hidden;
|
||||
/* Using without prefix would break IE11 */
|
||||
display: none;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
outline: none;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
padding: 44px;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: 0;
|
||||
transition-property: transform, opacity;
|
||||
white-space: normal;
|
||||
width: 100%;
|
||||
z-index: 99994;
|
||||
}
|
||||
|
||||
.fancybox-slide::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
font-size: 0;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.fancybox-is-sliding .fancybox-slide,
|
||||
.fancybox-slide--previous,
|
||||
.fancybox-slide--current,
|
||||
.fancybox-slide--next {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.fancybox-slide--image {
|
||||
overflow: hidden;
|
||||
padding: 44px 0;
|
||||
}
|
||||
|
||||
.fancybox-slide--image::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.fancybox-slide--html {
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.fancybox-content {
|
||||
background: #fff;
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
max-width: 100%;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
padding: 44px;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.fancybox-slide--image .fancybox-content {
|
||||
animation-timing-function: cubic-bezier(.5, 0, .14, 1);
|
||||
-webkit-backface-visibility: hidden;
|
||||
background: transparent;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%;
|
||||
left: 0;
|
||||
max-width: none;
|
||||
overflow: visible;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
-ms-transform-origin: top left;
|
||||
transform-origin: top left;
|
||||
transition-property: transform, opacity;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
z-index: 99995;
|
||||
}
|
||||
|
||||
.fancybox-can-zoomOut .fancybox-content {
|
||||
cursor: zoom-out;
|
||||
}
|
||||
|
||||
.fancybox-can-zoomIn .fancybox-content {
|
||||
cursor: zoom-in;
|
||||
}
|
||||
|
||||
.fancybox-can-swipe .fancybox-content,
|
||||
.fancybox-can-pan .fancybox-content {
|
||||
cursor: -webkit-grab;
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
.fancybox-is-grabbing .fancybox-content {
|
||||
cursor: -webkit-grabbing;
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.fancybox-container [data-selectable='true'] {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.fancybox-image,
|
||||
.fancybox-spaceball {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
max-height: none;
|
||||
max-width: none;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fancybox-spaceball {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.fancybox-slide--video .fancybox-content,
|
||||
.fancybox-slide--map .fancybox-content,
|
||||
.fancybox-slide--pdf .fancybox-content,
|
||||
.fancybox-slide--iframe .fancybox-content {
|
||||
height: 100%;
|
||||
overflow: visible;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fancybox-slide--video .fancybox-content {
|
||||
background: #000;
|
||||
}
|
||||
|
||||
.fancybox-slide--map .fancybox-content {
|
||||
background: #e5e3df;
|
||||
}
|
||||
|
||||
.fancybox-slide--iframe .fancybox-content {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.fancybox-video,
|
||||
.fancybox-iframe {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
display: block;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Fix iOS */
|
||||
.fancybox-iframe {
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.fancybox-error {
|
||||
background: #fff;
|
||||
cursor: default;
|
||||
max-width: 400px;
|
||||
padding: 40px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fancybox-error p {
|
||||
color: #444;
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
|
||||
.fancybox-button {
|
||||
background: rgba(30, 30, 30, .6);
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
height: 44px;
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
position: relative;
|
||||
transition: color .2s;
|
||||
vertical-align: top;
|
||||
visibility: inherit;
|
||||
width: 44px;
|
||||
}
|
||||
|
||||
.fancybox-button,
|
||||
.fancybox-button:visited,
|
||||
.fancybox-button:link {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.fancybox-button:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.fancybox-button:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.fancybox-button.fancybox-focus {
|
||||
outline: 1px dotted;
|
||||
}
|
||||
|
||||
.fancybox-button[disabled],
|
||||
.fancybox-button[disabled]:hover {
|
||||
color: #888;
|
||||
cursor: default;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Fix IE11 */
|
||||
.fancybox-button div {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.fancybox-button svg {
|
||||
display: block;
|
||||
height: 100%;
|
||||
overflow: visible;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fancybox-button svg path {
|
||||
fill: currentColor;
|
||||
stroke-width: 0;
|
||||
}
|
||||
|
||||
.fancybox-button--play svg:nth-child(2),
|
||||
.fancybox-button--fsenter svg:nth-child(2) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.fancybox-button--pause svg:nth-child(1),
|
||||
.fancybox-button--fsexit svg:nth-child(1) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.fancybox-progress {
|
||||
background: #ff5268;
|
||||
height: 2px;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
-ms-transform: scaleX(0);
|
||||
transform: scaleX(0);
|
||||
-ms-transform-origin: 0;
|
||||
transform-origin: 0;
|
||||
transition-property: transform;
|
||||
transition-timing-function: linear;
|
||||
z-index: 99998;
|
||||
}
|
||||
|
||||
/* Close button on the top right corner of html content */
|
||||
|
||||
.fancybox-close-small {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
color: #ccc;
|
||||
cursor: pointer;
|
||||
opacity: .8;
|
||||
padding: 8px;
|
||||
position: absolute;
|
||||
right: -12px;
|
||||
top: -44px;
|
||||
z-index: 401;
|
||||
}
|
||||
|
||||
.fancybox-close-small:hover {
|
||||
color: #fff;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.fancybox-slide--html .fancybox-close-small {
|
||||
color: currentColor;
|
||||
padding: 10px;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.fancybox-slide--image.fancybox-is-scaling .fancybox-content {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fancybox-is-scaling .fancybox-close-small,
|
||||
.fancybox-is-zoomable.fancybox-can-pan .fancybox-close-small {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Navigation arrows */
|
||||
|
||||
.fancybox-navigation .fancybox-button {
|
||||
background-clip: content-box;
|
||||
height: 100px;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
top: calc(50% - 50px);
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
.fancybox-navigation .fancybox-button div {
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
.fancybox-navigation .fancybox-button--arrow_left {
|
||||
left: 0;
|
||||
left: env(safe-area-inset-left);
|
||||
padding: 31px 26px 31px 6px;
|
||||
}
|
||||
|
||||
.fancybox-navigation .fancybox-button--arrow_right {
|
||||
padding: 31px 6px 31px 26px;
|
||||
right: 0;
|
||||
right: env(safe-area-inset-right);
|
||||
}
|
||||
|
||||
/* Caption */
|
||||
|
||||
.fancybox-caption {
|
||||
background: linear-gradient(to top,
|
||||
rgba(0, 0, 0, .85) 0%,
|
||||
rgba(0, 0, 0, .3) 50%,
|
||||
rgba(0, 0, 0, .15) 65%,
|
||||
rgba(0, 0, 0, .075) 75.5%,
|
||||
rgba(0, 0, 0, .037) 82.85%,
|
||||
rgba(0, 0, 0, .019) 88%,
|
||||
rgba(0, 0, 0, 0) 100%);
|
||||
bottom: 0;
|
||||
color: #eee;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
left: 0;
|
||||
line-height: 1.5;
|
||||
padding: 75px 44px 25px 44px;
|
||||
pointer-events: none;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
z-index: 99996;
|
||||
}
|
||||
|
||||
@supports (padding: max(0px)) {
|
||||
.fancybox-caption {
|
||||
padding: 75px max(44px, env(safe-area-inset-right)) max(25px, env(safe-area-inset-bottom)) max(44px, env(safe-area-inset-left));
|
||||
}
|
||||
}
|
||||
|
||||
.fancybox-caption--separate {
|
||||
margin-top: -50px;
|
||||
}
|
||||
|
||||
.fancybox-caption__body {
|
||||
max-height: 50vh;
|
||||
overflow: auto;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.fancybox-caption a,
|
||||
.fancybox-caption a:link,
|
||||
.fancybox-caption a:visited {
|
||||
color: #ccc;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.fancybox-caption a:hover {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Loading indicator */
|
||||
|
||||
.fancybox-loading {
|
||||
animation: fancybox-rotate 1s linear infinite;
|
||||
background: transparent;
|
||||
border: 4px solid #888;
|
||||
border-bottom-color: #fff;
|
||||
border-radius: 50%;
|
||||
height: 50px;
|
||||
left: 50%;
|
||||
margin: -25px 0 0 -25px;
|
||||
opacity: .7;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: 50px;
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
@keyframes fancybox-rotate {
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Transition effects */
|
||||
|
||||
.fancybox-animated {
|
||||
transition-timing-function: cubic-bezier(0, 0, .25, 1);
|
||||
}
|
||||
|
||||
/* transitionEffect: slide */
|
||||
|
||||
.fancybox-fx-slide.fancybox-slide--previous {
|
||||
opacity: 0;
|
||||
transform: translate3d(-100%, 0, 0);
|
||||
}
|
||||
|
||||
.fancybox-fx-slide.fancybox-slide--next {
|
||||
opacity: 0;
|
||||
transform: translate3d(100%, 0, 0);
|
||||
}
|
||||
|
||||
.fancybox-fx-slide.fancybox-slide--current {
|
||||
opacity: 1;
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
/* transitionEffect: fade */
|
||||
|
||||
.fancybox-fx-fade.fancybox-slide--previous,
|
||||
.fancybox-fx-fade.fancybox-slide--next {
|
||||
opacity: 0;
|
||||
transition-timing-function: cubic-bezier(.19, 1, .22, 1);
|
||||
}
|
||||
|
||||
.fancybox-fx-fade.fancybox-slide--current {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* transitionEffect: zoom-in-out */
|
||||
|
||||
.fancybox-fx-zoom-in-out.fancybox-slide--previous {
|
||||
opacity: 0;
|
||||
transform: scale3d(1.5, 1.5, 1.5);
|
||||
}
|
||||
|
||||
.fancybox-fx-zoom-in-out.fancybox-slide--next {
|
||||
opacity: 0;
|
||||
transform: scale3d(.5, .5, .5);
|
||||
}
|
||||
|
||||
.fancybox-fx-zoom-in-out.fancybox-slide--current {
|
||||
opacity: 1;
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
|
||||
/* transitionEffect: rotate */
|
||||
|
||||
.fancybox-fx-rotate.fancybox-slide--previous {
|
||||
opacity: 0;
|
||||
-ms-transform: rotate(-360deg);
|
||||
transform: rotate(-360deg);
|
||||
}
|
||||
|
||||
.fancybox-fx-rotate.fancybox-slide--next {
|
||||
opacity: 0;
|
||||
-ms-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
|
||||
.fancybox-fx-rotate.fancybox-slide--current {
|
||||
opacity: 1;
|
||||
-ms-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
/* transitionEffect: circular */
|
||||
|
||||
.fancybox-fx-circular.fancybox-slide--previous {
|
||||
opacity: 0;
|
||||
transform: scale3d(0, 0, 0) translate3d(-100%, 0, 0);
|
||||
}
|
||||
|
||||
.fancybox-fx-circular.fancybox-slide--next {
|
||||
opacity: 0;
|
||||
transform: scale3d(0, 0, 0) translate3d(100%, 0, 0);
|
||||
}
|
||||
|
||||
.fancybox-fx-circular.fancybox-slide--current {
|
||||
opacity: 1;
|
||||
transform: scale3d(1, 1, 1) translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
/* transitionEffect: tube */
|
||||
|
||||
.fancybox-fx-tube.fancybox-slide--previous {
|
||||
transform: translate3d(-100%, 0, 0) scale(.1) skew(-10deg);
|
||||
}
|
||||
|
||||
.fancybox-fx-tube.fancybox-slide--next {
|
||||
transform: translate3d(100%, 0, 0) scale(.1) skew(10deg);
|
||||
}
|
||||
|
||||
.fancybox-fx-tube.fancybox-slide--current {
|
||||
transform: translate3d(0, 0, 0) scale(1);
|
||||
}
|
||||
|
||||
/* Styling for Small-Screen Devices */
|
||||
@media all and (max-height: 576px) {
|
||||
.fancybox-slide {
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
}
|
||||
|
||||
.fancybox-slide--image {
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
.fancybox-close-small {
|
||||
right: -6px;
|
||||
}
|
||||
|
||||
.fancybox-slide--image .fancybox-close-small {
|
||||
background: #4e4e4e;
|
||||
color: #f2f4f6;
|
||||
height: 36px;
|
||||
opacity: 1;
|
||||
padding: 6px;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 36px;
|
||||
}
|
||||
|
||||
.fancybox-caption {
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
@supports (padding: max(0px)) {
|
||||
.fancybox-caption {
|
||||
padding-left: max(12px, env(safe-area-inset-left));
|
||||
padding-right: max(12px, env(safe-area-inset-right));
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Share */
|
||||
|
||||
.fancybox-share {
|
||||
background: #f4f4f4;
|
||||
border-radius: 3px;
|
||||
max-width: 90%;
|
||||
padding: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.fancybox-share h1 {
|
||||
color: #222;
|
||||
font-size: 35px;
|
||||
font-weight: 700;
|
||||
margin: 0 0 20px 0;
|
||||
}
|
||||
|
||||
.fancybox-share p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.fancybox-share__button {
|
||||
border: 0;
|
||||
border-radius: 3px;
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
line-height: 40px;
|
||||
margin: 0 5px 10px 5px;
|
||||
min-width: 130px;
|
||||
padding: 0 15px;
|
||||
text-decoration: none;
|
||||
transition: all .2s;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.fancybox-share__button:visited,
|
||||
.fancybox-share__button:link {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.fancybox-share__button:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.fancybox-share__button--fb {
|
||||
background: #3b5998;
|
||||
}
|
||||
|
||||
.fancybox-share__button--fb:hover {
|
||||
background: #344e86;
|
||||
}
|
||||
|
||||
.fancybox-share__button--pt {
|
||||
background: #bd081d;
|
||||
}
|
||||
|
||||
.fancybox-share__button--pt:hover {
|
||||
background: #aa0719;
|
||||
}
|
||||
|
||||
.fancybox-share__button--tw {
|
||||
background: #1da1f2;
|
||||
}
|
||||
|
||||
.fancybox-share__button--tw:hover {
|
||||
background: #0d95e8;
|
||||
}
|
||||
|
||||
.fancybox-share__button svg {
|
||||
height: 25px;
|
||||
margin-right: 7px;
|
||||
position: relative;
|
||||
top: -1px;
|
||||
vertical-align: middle;
|
||||
width: 25px;
|
||||
}
|
||||
|
||||
.fancybox-share__button svg path {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
.fancybox-share__input {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #d7d7d7;
|
||||
border-radius: 0;
|
||||
color: #5d5b5b;
|
||||
font-size: 14px;
|
||||
margin: 10px 0 0 0;
|
||||
outline: none;
|
||||
padding: 10px 15px;
|
||||
width: 100%;
|
||||
}
|
||||
/* Thumbs */
|
||||
|
||||
.fancybox-thumbs {
|
||||
background: #ddd;
|
||||
bottom: 0;
|
||||
display: none;
|
||||
margin: 0;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
-ms-overflow-style: -ms-autohiding-scrollbar;
|
||||
padding: 2px 2px 4px 2px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
top: 0;
|
||||
width: 212px;
|
||||
z-index: 99995;
|
||||
}
|
||||
|
||||
.fancybox-thumbs-x {
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.fancybox-show-thumbs .fancybox-thumbs {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.fancybox-show-thumbs .fancybox-inner {
|
||||
right: 212px;
|
||||
}
|
||||
|
||||
.fancybox-thumbs__list {
|
||||
font-size: 0;
|
||||
height: 100%;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fancybox-thumbs-x .fancybox-thumbs__list {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fancybox-thumbs-y .fancybox-thumbs__list::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
}
|
||||
|
||||
.fancybox-thumbs-y .fancybox-thumbs__list::-webkit-scrollbar-track {
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
box-shadow: inset 0 0 6px rgba(0, 0, 0, .3);
|
||||
}
|
||||
|
||||
.fancybox-thumbs-y .fancybox-thumbs__list::-webkit-scrollbar-thumb {
|
||||
background: #2a2a2a;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.fancybox-thumbs__list a {
|
||||
-webkit-backface-visibility: hidden;
|
||||
backface-visibility: hidden;
|
||||
background-color: rgba(0, 0, 0, .1);
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
cursor: pointer;
|
||||
float: left;
|
||||
height: 75px;
|
||||
margin: 2px;
|
||||
max-height: calc(100% - 8px);
|
||||
max-width: calc(50% - 4px);
|
||||
outline: none;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.fancybox-thumbs__list a::before {
|
||||
border: 6px solid #ff5268;
|
||||
bottom: 0;
|
||||
content: '';
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
transition: all .2s cubic-bezier(.25, .46, .45, .94);
|
||||
z-index: 99991;
|
||||
}
|
||||
|
||||
.fancybox-thumbs__list a:focus::before {
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.fancybox-thumbs__list a.fancybox-thumbs-active::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Styling for Small-Screen Devices */
|
||||
@media all and (max-width: 576px) {
|
||||
.fancybox-thumbs {
|
||||
width: 110px;
|
||||
}
|
||||
|
||||
.fancybox-show-thumbs .fancybox-inner {
|
||||
right: 110px;
|
||||
}
|
||||
|
||||
.fancybox-thumbs__list a {
|
||||
max-width: calc(100% - 10px);
|
||||
}
|
||||
}
|
||||
5632
view/js/fancybox/jquery.fancybox.js
vendored
Normal file
5632
view/js/fancybox/jquery.fancybox.js
vendored
Normal file
|
|
@ -0,0 +1,5632 @@
|
|||
// ==================================================
|
||||
// fancyBox v3.5.7
|
||||
//
|
||||
// Licensed GPLv3 for open source use
|
||||
// or fancyBox Commercial License for commercial use
|
||||
//
|
||||
// http://fancyapps.com/fancybox/
|
||||
// Copyright 2019 fancyApps
|
||||
//
|
||||
// ==================================================
|
||||
(function (window, document, $, undefined) {
|
||||
"use strict";
|
||||
|
||||
window.console = window.console || {
|
||||
info: function (stuff) {}
|
||||
};
|
||||
|
||||
// If there's no jQuery, fancyBox can't work
|
||||
// =========================================
|
||||
|
||||
if (!$) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if fancyBox is already initialized
|
||||
// ========================================
|
||||
|
||||
if ($.fn.fancybox) {
|
||||
console.info("fancyBox already initialized");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Private default settings
|
||||
// ========================
|
||||
|
||||
var defaults = {
|
||||
// Close existing modals
|
||||
// Set this to false if you do not need to stack multiple instances
|
||||
closeExisting: false,
|
||||
|
||||
// Enable infinite gallery navigation
|
||||
loop: false,
|
||||
|
||||
// Horizontal space between slides
|
||||
gutter: 50,
|
||||
|
||||
// Enable keyboard navigation
|
||||
keyboard: true,
|
||||
|
||||
// Should allow caption to overlap the content
|
||||
preventCaptionOverlap: true,
|
||||
|
||||
// Should display navigation arrows at the screen edges
|
||||
arrows: true,
|
||||
|
||||
// Should display counter at the top left corner
|
||||
infobar: true,
|
||||
|
||||
// Should display close button (using `btnTpl.smallBtn` template) over the content
|
||||
// Can be true, false, "auto"
|
||||
// If "auto" - will be automatically enabled for "html", "inline" or "ajax" items
|
||||
smallBtn: "auto",
|
||||
|
||||
// Should display toolbar (buttons at the top)
|
||||
// Can be true, false, "auto"
|
||||
// If "auto" - will be automatically hidden if "smallBtn" is enabled
|
||||
toolbar: "auto",
|
||||
|
||||
// What buttons should appear in the top right corner.
|
||||
// Buttons will be created using templates from `btnTpl` option
|
||||
// and they will be placed into toolbar (class="fancybox-toolbar"` element)
|
||||
buttons: [
|
||||
"zoom",
|
||||
//"share",
|
||||
"slideShow",
|
||||
//"fullScreen",
|
||||
//"download",
|
||||
"thumbs",
|
||||
"close"
|
||||
],
|
||||
|
||||
// Detect "idle" time in seconds
|
||||
idleTime: 3,
|
||||
|
||||
// Disable right-click and use simple image protection for images
|
||||
protect: false,
|
||||
|
||||
// Shortcut to make content "modal" - disable keyboard navigtion, hide buttons, etc
|
||||
modal: false,
|
||||
|
||||
image: {
|
||||
// Wait for images to load before displaying
|
||||
// true - wait for image to load and then display;
|
||||
// false - display thumbnail and load the full-sized image over top,
|
||||
// requires predefined image dimensions (`data-width` and `data-height` attributes)
|
||||
preload: false
|
||||
},
|
||||
|
||||
ajax: {
|
||||
// Object containing settings for ajax request
|
||||
settings: {
|
||||
// This helps to indicate that request comes from the modal
|
||||
// Feel free to change naming
|
||||
data: {
|
||||
fancybox: true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
iframe: {
|
||||
// Iframe template
|
||||
tpl: '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" allowfullscreen="allowfullscreen" allow="autoplay; fullscreen" src=""></iframe>',
|
||||
|
||||
// Preload iframe before displaying it
|
||||
// This allows to calculate iframe content width and height
|
||||
// (note: Due to "Same Origin Policy", you can't get cross domain data).
|
||||
preload: true,
|
||||
|
||||
// Custom CSS styling for iframe wrapping element
|
||||
// You can use this to set custom iframe dimensions
|
||||
css: {},
|
||||
|
||||
// Iframe tag attributes
|
||||
attr: {
|
||||
scrolling: "auto"
|
||||
}
|
||||
},
|
||||
|
||||
// For HTML5 video only
|
||||
video: {
|
||||
tpl: '<video class="fancybox-video" controls controlsList="nodownload" poster="{{poster}}">' +
|
||||
'<source src="{{src}}" type="{{format}}" />' +
|
||||
'Sorry, your browser doesn\'t support embedded videos, <a href="{{src}}">download</a> and watch with your favorite video player!' +
|
||||
"</video>",
|
||||
format: "", // custom video format
|
||||
autoStart: true
|
||||
},
|
||||
|
||||
// Default content type if cannot be detected automatically
|
||||
defaultType: "image",
|
||||
|
||||
// Open/close animation type
|
||||
// Possible values:
|
||||
// false - disable
|
||||
// "zoom" - zoom images from/to thumbnail
|
||||
// "fade"
|
||||
// "zoom-in-out"
|
||||
//
|
||||
animationEffect: "zoom",
|
||||
|
||||
// Duration in ms for open/close animation
|
||||
animationDuration: 366,
|
||||
|
||||
// Should image change opacity while zooming
|
||||
// If opacity is "auto", then opacity will be changed if image and thumbnail have different aspect ratios
|
||||
zoomOpacity: "auto",
|
||||
|
||||
// Transition effect between slides
|
||||
//
|
||||
// Possible values:
|
||||
// false - disable
|
||||
// "fade'
|
||||
// "slide'
|
||||
// "circular'
|
||||
// "tube'
|
||||
// "zoom-in-out'
|
||||
// "rotate'
|
||||
//
|
||||
transitionEffect: "fade",
|
||||
|
||||
// Duration in ms for transition animation
|
||||
transitionDuration: 366,
|
||||
|
||||
// Custom CSS class for slide element
|
||||
slideClass: "",
|
||||
|
||||
// Custom CSS class for layout
|
||||
baseClass: "",
|
||||
|
||||
// Base template for layout
|
||||
baseTpl: '<div class="fancybox-container" role="dialog" tabindex="-1">' +
|
||||
'<div class="fancybox-bg"></div>' +
|
||||
'<div class="fancybox-inner">' +
|
||||
'<div class="fancybox-infobar"><span data-fancybox-index></span> / <span data-fancybox-count></span></div>' +
|
||||
'<div class="fancybox-toolbar">{{buttons}}</div>' +
|
||||
'<div class="fancybox-navigation">{{arrows}}</div>' +
|
||||
'<div class="fancybox-stage"></div>' +
|
||||
'<div class="fancybox-caption"><div class="fancybox-caption__body"></div></div>' +
|
||||
"</div>" +
|
||||
"</div>",
|
||||
|
||||
// Loading indicator template
|
||||
spinnerTpl: '<div class="fancybox-loading"></div>',
|
||||
|
||||
// Error message template
|
||||
errorTpl: '<div class="fancybox-error"><p>{{ERROR}}</p></div>',
|
||||
|
||||
btnTpl: {
|
||||
download: '<a download data-fancybox-download class="fancybox-button fancybox-button--download" title="{{DOWNLOAD}}" href="javascript:;">' +
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18.62 17.09V19H5.38v-1.91zm-2.97-6.96L17 11.45l-5 4.87-5-4.87 1.36-1.32 2.68 2.64V5h1.92v7.77z"/></svg>' +
|
||||
"</a>",
|
||||
|
||||
zoom: '<button data-fancybox-zoom class="fancybox-button fancybox-button--zoom" title="{{ZOOM}}">' +
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18.7 17.3l-3-3a5.9 5.9 0 0 0-.6-7.6 5.9 5.9 0 0 0-8.4 0 5.9 5.9 0 0 0 0 8.4 5.9 5.9 0 0 0 7.7.7l3 3a1 1 0 0 0 1.3 0c.4-.5.4-1 0-1.5zM8.1 13.8a4 4 0 0 1 0-5.7 4 4 0 0 1 5.7 0 4 4 0 0 1 0 5.7 4 4 0 0 1-5.7 0z"/></svg>' +
|
||||
"</button>",
|
||||
|
||||
close: '<button data-fancybox-close class="fancybox-button fancybox-button--close" title="{{CLOSE}}">' +
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 10.6L6.6 5.2 5.2 6.6l5.4 5.4-5.4 5.4 1.4 1.4 5.4-5.4 5.4 5.4 1.4-1.4-5.4-5.4 5.4-5.4-1.4-1.4-5.4 5.4z"/></svg>' +
|
||||
"</button>",
|
||||
|
||||
// Arrows
|
||||
arrowLeft: '<button data-fancybox-prev class="fancybox-button fancybox-button--arrow_left" title="{{PREV}}">' +
|
||||
'<div><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11.28 15.7l-1.34 1.37L5 12l4.94-5.07 1.34 1.38-2.68 2.72H19v1.94H8.6z"/></svg></div>' +
|
||||
"</button>",
|
||||
|
||||
arrowRight: '<button data-fancybox-next class="fancybox-button fancybox-button--arrow_right" title="{{NEXT}}">' +
|
||||
'<div><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.4 12.97l-2.68 2.72 1.34 1.38L19 12l-4.94-5.07-1.34 1.38 2.68 2.72H5v1.94z"/></svg></div>' +
|
||||
"</button>",
|
||||
|
||||
// This small close button will be appended to your html/inline/ajax content by default,
|
||||
// if "smallBtn" option is not set to false
|
||||
smallBtn: '<button type="button" data-fancybox-close class="fancybox-button fancybox-close-small" title="{{CLOSE}}">' +
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" version="1" viewBox="0 0 24 24"><path d="M13 12l5-5-1-1-5 5-5-5-1 1 5 5-5 5 1 1 5-5 5 5 1-1z"/></svg>' +
|
||||
"</button>"
|
||||
},
|
||||
|
||||
// Container is injected into this element
|
||||
parentEl: "body",
|
||||
|
||||
// Hide browser vertical scrollbars; use at your own risk
|
||||
hideScrollbar: true,
|
||||
|
||||
// Focus handling
|
||||
// ==============
|
||||
|
||||
// Try to focus on the first focusable element after opening
|
||||
autoFocus: true,
|
||||
|
||||
// Put focus back to active element after closing
|
||||
backFocus: true,
|
||||
|
||||
// Do not let user to focus on element outside modal content
|
||||
trapFocus: true,
|
||||
|
||||
// Module specific options
|
||||
// =======================
|
||||
|
||||
fullScreen: {
|
||||
autoStart: false
|
||||
},
|
||||
|
||||
// Set `touch: false` to disable panning/swiping
|
||||
touch: {
|
||||
vertical: true, // Allow to drag content vertically
|
||||
momentum: true // Continue movement after releasing mouse/touch when panning
|
||||
},
|
||||
|
||||
// Hash value when initializing manually,
|
||||
// set `false` to disable hash change
|
||||
hash: null,
|
||||
|
||||
// Customize or add new media types
|
||||
// Example:
|
||||
/*
|
||||
media : {
|
||||
youtube : {
|
||||
params : {
|
||||
autoplay : 0
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
media: {},
|
||||
|
||||
slideShow: {
|
||||
autoStart: false,
|
||||
speed: 3000
|
||||
},
|
||||
|
||||
thumbs: {
|
||||
autoStart: false, // Display thumbnails on opening
|
||||
hideOnClose: true, // Hide thumbnail grid when closing animation starts
|
||||
parentEl: ".fancybox-container", // Container is injected into this element
|
||||
axis: "y" // Vertical (y) or horizontal (x) scrolling
|
||||
},
|
||||
|
||||
// Use mousewheel to navigate gallery
|
||||
// If 'auto' - enabled for images only
|
||||
wheel: "auto",
|
||||
|
||||
// Callbacks
|
||||
//==========
|
||||
|
||||
// See Documentation/API/Events for more information
|
||||
// Example:
|
||||
/*
|
||||
afterShow: function( instance, current ) {
|
||||
console.info( 'Clicked element:' );
|
||||
console.info( current.opts.$orig );
|
||||
}
|
||||
*/
|
||||
|
||||
onInit: $.noop, // When instance has been initialized
|
||||
|
||||
beforeLoad: $.noop, // Before the content of a slide is being loaded
|
||||
afterLoad: $.noop, // When the content of a slide is done loading
|
||||
|
||||
beforeShow: $.noop, // Before open animation starts
|
||||
afterShow: $.noop, // When content is done loading and animating
|
||||
|
||||
beforeClose: $.noop, // Before the instance attempts to close. Return false to cancel the close.
|
||||
afterClose: $.noop, // After instance has been closed
|
||||
|
||||
onActivate: $.noop, // When instance is brought to front
|
||||
onDeactivate: $.noop, // When other instance has been activated
|
||||
|
||||
// Interaction
|
||||
// ===========
|
||||
|
||||
// Use options below to customize taken action when user clicks or double clicks on the fancyBox area,
|
||||
// each option can be string or method that returns value.
|
||||
//
|
||||
// Possible values:
|
||||
// "close" - close instance
|
||||
// "next" - move to next gallery item
|
||||
// "nextOrClose" - move to next gallery item or close if gallery has only one item
|
||||
// "toggleControls" - show/hide controls
|
||||
// "zoom" - zoom image (if loaded)
|
||||
// false - do nothing
|
||||
|
||||
// Clicked on the content
|
||||
clickContent: function (current, event) {
|
||||
return current.type === "image" ? "zoom" : false;
|
||||
},
|
||||
|
||||
// Clicked on the slide
|
||||
clickSlide: "close",
|
||||
|
||||
// Clicked on the background (backdrop) element;
|
||||
// if you have not changed the layout, then most likely you need to use `clickSlide` option
|
||||
clickOutside: "close",
|
||||
|
||||
// Same as previous two, but for double click
|
||||
dblclickContent: false,
|
||||
dblclickSlide: false,
|
||||
dblclickOutside: false,
|
||||
|
||||
// Custom options when mobile device is detected
|
||||
// =============================================
|
||||
|
||||
mobile: {
|
||||
preventCaptionOverlap: false,
|
||||
idleTime: false,
|
||||
clickContent: function (current, event) {
|
||||
return current.type === "image" ? "toggleControls" : false;
|
||||
},
|
||||
clickSlide: function (current, event) {
|
||||
return current.type === "image" ? "toggleControls" : "close";
|
||||
},
|
||||
dblclickContent: function (current, event) {
|
||||
return current.type === "image" ? "zoom" : false;
|
||||
},
|
||||
dblclickSlide: function (current, event) {
|
||||
return current.type === "image" ? "zoom" : false;
|
||||
}
|
||||
},
|
||||
|
||||
// Internationalization
|
||||
// ====================
|
||||
|
||||
lang: "en",
|
||||
i18n: {
|
||||
en: {
|
||||
CLOSE: "Close",
|
||||
NEXT: "Next",
|
||||
PREV: "Previous",
|
||||
ERROR: "The requested content cannot be loaded. <br/> Please try again later.",
|
||||
PLAY_START: "Start slideshow",
|
||||
PLAY_STOP: "Pause slideshow",
|
||||
FULL_SCREEN: "Full screen",
|
||||
THUMBS: "Thumbnails",
|
||||
DOWNLOAD: "Download",
|
||||
SHARE: "Share",
|
||||
ZOOM: "Zoom"
|
||||
},
|
||||
de: {
|
||||
CLOSE: "Schließen",
|
||||
NEXT: "Weiter",
|
||||
PREV: "Zurück",
|
||||
ERROR: "Die angeforderten Daten konnten nicht geladen werden. <br/> Bitte versuchen Sie es später nochmal.",
|
||||
PLAY_START: "Diaschau starten",
|
||||
PLAY_STOP: "Diaschau beenden",
|
||||
FULL_SCREEN: "Vollbild",
|
||||
THUMBS: "Vorschaubilder",
|
||||
DOWNLOAD: "Herunterladen",
|
||||
SHARE: "Teilen",
|
||||
ZOOM: "Vergrößern"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Few useful variables and methods
|
||||
// ================================
|
||||
|
||||
var $W = $(window);
|
||||
var $D = $(document);
|
||||
|
||||
var called = 0;
|
||||
|
||||
// Check if an object is a jQuery object and not a native JavaScript object
|
||||
// ========================================================================
|
||||
var isQuery = function (obj) {
|
||||
return obj && obj.hasOwnProperty && obj instanceof $;
|
||||
};
|
||||
|
||||
// Handle multiple browsers for "requestAnimationFrame" and "cancelAnimationFrame"
|
||||
// ===============================================================================
|
||||
var requestAFrame = (function () {
|
||||
return (
|
||||
window.requestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
window.oRequestAnimationFrame ||
|
||||
// if all else fails, use setTimeout
|
||||
function (callback) {
|
||||
return window.setTimeout(callback, 1000 / 60);
|
||||
}
|
||||
);
|
||||
})();
|
||||
|
||||
var cancelAFrame = (function () {
|
||||
return (
|
||||
window.cancelAnimationFrame ||
|
||||
window.webkitCancelAnimationFrame ||
|
||||
window.mozCancelAnimationFrame ||
|
||||
window.oCancelAnimationFrame ||
|
||||
function (id) {
|
||||
window.clearTimeout(id);
|
||||
}
|
||||
);
|
||||
})();
|
||||
|
||||
// Detect the supported transition-end event property name
|
||||
// =======================================================
|
||||
var transitionEnd = (function () {
|
||||
var el = document.createElement("fakeelement"),
|
||||
t;
|
||||
|
||||
var transitions = {
|
||||
transition: "transitionend",
|
||||
OTransition: "oTransitionEnd",
|
||||
MozTransition: "transitionend",
|
||||
WebkitTransition: "webkitTransitionEnd"
|
||||
};
|
||||
|
||||
for (t in transitions) {
|
||||
if (el.style[t] !== undefined) {
|
||||
return transitions[t];
|
||||
}
|
||||
}
|
||||
|
||||
return "transitionend";
|
||||
})();
|
||||
|
||||
// Force redraw on an element.
|
||||
// This helps in cases where the browser doesn't redraw an updated element properly
|
||||
// ================================================================================
|
||||
var forceRedraw = function ($el) {
|
||||
return $el && $el.length && $el[0].offsetHeight;
|
||||
};
|
||||
|
||||
// Exclude array (`buttons`) options from deep merging
|
||||
// ===================================================
|
||||
var mergeOpts = function (opts1, opts2) {
|
||||
var rez = $.extend(true, {}, opts1, opts2);
|
||||
|
||||
$.each(opts2, function (key, value) {
|
||||
if ($.isArray(value)) {
|
||||
rez[key] = value;
|
||||
}
|
||||
});
|
||||
|
||||
return rez;
|
||||
};
|
||||
|
||||
// How much of an element is visible in viewport
|
||||
// =============================================
|
||||
|
||||
var inViewport = function (elem) {
|
||||
var elemCenter, rez;
|
||||
|
||||
if (!elem || elem.ownerDocument !== document) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$(".fancybox-container").css("pointer-events", "none");
|
||||
|
||||
elemCenter = {
|
||||
x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,
|
||||
y: elem.getBoundingClientRect().top + elem.offsetHeight / 2
|
||||
};
|
||||
|
||||
rez = document.elementFromPoint(elemCenter.x, elemCenter.y) === elem;
|
||||
|
||||
$(".fancybox-container").css("pointer-events", "");
|
||||
|
||||
return rez;
|
||||
};
|
||||
|
||||
// Class definition
|
||||
// ================
|
||||
|
||||
var FancyBox = function (content, opts, index) {
|
||||
var self = this;
|
||||
|
||||
self.opts = mergeOpts({
|
||||
index: index
|
||||
}, $.fancybox.defaults);
|
||||
|
||||
if ($.isPlainObject(opts)) {
|
||||
self.opts = mergeOpts(self.opts, opts);
|
||||
}
|
||||
|
||||
if ($.fancybox.isMobile) {
|
||||
self.opts = mergeOpts(self.opts, self.opts.mobile);
|
||||
}
|
||||
|
||||
self.id = self.opts.id || ++called;
|
||||
|
||||
self.currIndex = parseInt(self.opts.index, 10) || 0;
|
||||
self.prevIndex = null;
|
||||
|
||||
self.prevPos = null;
|
||||
self.currPos = 0;
|
||||
|
||||
self.firstRun = true;
|
||||
|
||||
// All group items
|
||||
self.group = [];
|
||||
|
||||
// Existing slides (for current, next and previous gallery items)
|
||||
self.slides = {};
|
||||
|
||||
// Create group elements
|
||||
self.addContent(content);
|
||||
|
||||
if (!self.group.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.init();
|
||||
};
|
||||
|
||||
$.extend(FancyBox.prototype, {
|
||||
// Create DOM structure
|
||||
// ====================
|
||||
|
||||
init: function () {
|
||||
var self = this,
|
||||
firstItem = self.group[self.currIndex],
|
||||
firstItemOpts = firstItem.opts,
|
||||
$container,
|
||||
buttonStr;
|
||||
|
||||
if (firstItemOpts.closeExisting) {
|
||||
$.fancybox.close(true);
|
||||
}
|
||||
|
||||
// Hide scrollbars
|
||||
// ===============
|
||||
|
||||
$("body").addClass("fancybox-active");
|
||||
|
||||
if (
|
||||
!$.fancybox.getInstance() &&
|
||||
firstItemOpts.hideScrollbar !== false &&
|
||||
!$.fancybox.isMobile &&
|
||||
document.body.scrollHeight > window.innerHeight
|
||||
) {
|
||||
$("head").append(
|
||||
'<style id="fancybox-style-noscroll" type="text/css">.compensate-for-scrollbar{margin-right:' +
|
||||
(window.innerWidth - document.documentElement.clientWidth) +
|
||||
"px;}</style>"
|
||||
);
|
||||
|
||||
$("body").addClass("compensate-for-scrollbar");
|
||||
}
|
||||
|
||||
// Build html markup and set references
|
||||
// ====================================
|
||||
|
||||
// Build html code for buttons and insert into main template
|
||||
buttonStr = "";
|
||||
|
||||
$.each(firstItemOpts.buttons, function (index, value) {
|
||||
buttonStr += firstItemOpts.btnTpl[value] || "";
|
||||
});
|
||||
|
||||
// Create markup from base template, it will be initially hidden to
|
||||
// avoid unnecessary work like painting while initializing is not complete
|
||||
$container = $(
|
||||
self.translate(
|
||||
self,
|
||||
firstItemOpts.baseTpl
|
||||
.replace("{{buttons}}", buttonStr)
|
||||
.replace("{{arrows}}", firstItemOpts.btnTpl.arrowLeft + firstItemOpts.btnTpl.arrowRight)
|
||||
)
|
||||
)
|
||||
.attr("id", "fancybox-container-" + self.id)
|
||||
.addClass(firstItemOpts.baseClass)
|
||||
.data("FancyBox", self)
|
||||
.appendTo(firstItemOpts.parentEl);
|
||||
|
||||
// Create object holding references to jQuery wrapped nodes
|
||||
self.$refs = {
|
||||
container: $container
|
||||
};
|
||||
|
||||
["bg", "inner", "infobar", "toolbar", "stage", "caption", "navigation"].forEach(function (item) {
|
||||
self.$refs[item] = $container.find(".fancybox-" + item);
|
||||
});
|
||||
|
||||
self.trigger("onInit");
|
||||
|
||||
// Enable events, deactive previous instances
|
||||
self.activate();
|
||||
|
||||
// Build slides, load and reveal content
|
||||
self.jumpTo(self.currIndex);
|
||||
},
|
||||
|
||||
// Simple i18n support - replaces object keys found in template
|
||||
// with corresponding values
|
||||
// ============================================================
|
||||
|
||||
translate: function (obj, str) {
|
||||
var arr = obj.opts.i18n[obj.opts.lang] || obj.opts.i18n.en;
|
||||
|
||||
return str.replace(/\{\{(\w+)\}\}/g, function (match, n) {
|
||||
return arr[n] === undefined ? match : arr[n];
|
||||
});
|
||||
},
|
||||
|
||||
// Populate current group with fresh content
|
||||
// Check if each object has valid type and content
|
||||
// ===============================================
|
||||
|
||||
addContent: function (content) {
|
||||
var self = this,
|
||||
items = $.makeArray(content),
|
||||
thumbs;
|
||||
|
||||
$.each(items, function (i, item) {
|
||||
var obj = {},
|
||||
opts = {},
|
||||
$item,
|
||||
type,
|
||||
found,
|
||||
src,
|
||||
srcParts;
|
||||
|
||||
// Step 1 - Make sure we have an object
|
||||
// ====================================
|
||||
|
||||
if ($.isPlainObject(item)) {
|
||||
// We probably have manual usage here, something like
|
||||
// $.fancybox.open( [ { src : "image.jpg", type : "image" } ] )
|
||||
|
||||
obj = item;
|
||||
opts = item.opts || item;
|
||||
} else if ($.type(item) === "object" && $(item).length) {
|
||||
// Here we probably have jQuery collection returned by some selector
|
||||
$item = $(item);
|
||||
|
||||
// Support attributes like `data-options='{"touch" : false}'` and `data-touch='false'`
|
||||
opts = $item.data() || {};
|
||||
opts = $.extend(true, {}, opts, opts.options);
|
||||
|
||||
// Here we store clicked element
|
||||
opts.$orig = $item;
|
||||
|
||||
obj.src = self.opts.src || opts.src || $item.attr("href");
|
||||
|
||||
// Assume that simple syntax is used, for example:
|
||||
// `$.fancybox.open( $("#test"), {} );`
|
||||
if (!obj.type && !obj.src) {
|
||||
obj.type = "inline";
|
||||
obj.src = item;
|
||||
}
|
||||
} else {
|
||||
// Assume we have a simple html code, for example:
|
||||
// $.fancybox.open( '<div><h1>Hi!</h1></div>' );
|
||||
obj = {
|
||||
type: "html",
|
||||
src: item + ""
|
||||
};
|
||||
}
|
||||
|
||||
// Each gallery object has full collection of options
|
||||
obj.opts = $.extend(true, {}, self.opts, opts);
|
||||
|
||||
// Do not merge buttons array
|
||||
if ($.isArray(opts.buttons)) {
|
||||
obj.opts.buttons = opts.buttons;
|
||||
}
|
||||
|
||||
if ($.fancybox.isMobile && obj.opts.mobile) {
|
||||
obj.opts = mergeOpts(obj.opts, obj.opts.mobile);
|
||||
}
|
||||
|
||||
// Step 2 - Make sure we have content type, if not - try to guess
|
||||
// ==============================================================
|
||||
|
||||
type = obj.type || obj.opts.type;
|
||||
src = obj.src || "";
|
||||
|
||||
if (!type && src) {
|
||||
if ((found = src.match(/\.(mp4|mov|ogv|webm)((\?|#).*)?$/i))) {
|
||||
type = "video";
|
||||
|
||||
if (!obj.opts.video.format) {
|
||||
obj.opts.video.format = "video/" + (found[1] === "ogv" ? "ogg" : found[1]);
|
||||
}
|
||||
} else if (src.match(/(^data:image\/[a-z0-9+\/=]*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg|ico)((\?|#).*)?$)/i)) {
|
||||
type = "image";
|
||||
} else if (src.match(/\.(pdf)((\?|#).*)?$/i)) {
|
||||
type = "iframe";
|
||||
obj = $.extend(true, obj, {
|
||||
contentType: "pdf",
|
||||
opts: {
|
||||
iframe: {
|
||||
preload: false
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (src.charAt(0) === "#") {
|
||||
type = "inline";
|
||||
}
|
||||
}
|
||||
|
||||
if (type) {
|
||||
obj.type = type;
|
||||
} else {
|
||||
self.trigger("objectNeedsType", obj);
|
||||
}
|
||||
|
||||
if (!obj.contentType) {
|
||||
obj.contentType = $.inArray(obj.type, ["html", "inline", "ajax"]) > -1 ? "html" : obj.type;
|
||||
}
|
||||
|
||||
// Step 3 - Some adjustments
|
||||
// =========================
|
||||
|
||||
obj.index = self.group.length;
|
||||
|
||||
if (obj.opts.smallBtn == "auto") {
|
||||
obj.opts.smallBtn = $.inArray(obj.type, ["html", "inline", "ajax"]) > -1;
|
||||
}
|
||||
|
||||
if (obj.opts.toolbar === "auto") {
|
||||
obj.opts.toolbar = !obj.opts.smallBtn;
|
||||
}
|
||||
|
||||
// Find thumbnail image, check if exists and if is in the viewport
|
||||
obj.$thumb = obj.opts.$thumb || null;
|
||||
|
||||
if (obj.opts.$trigger && obj.index === self.opts.index) {
|
||||
obj.$thumb = obj.opts.$trigger.find("img:first");
|
||||
|
||||
if (obj.$thumb.length) {
|
||||
obj.opts.$orig = obj.opts.$trigger;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(obj.$thumb && obj.$thumb.length) && obj.opts.$orig) {
|
||||
obj.$thumb = obj.opts.$orig.find("img:first");
|
||||
}
|
||||
|
||||
if (obj.$thumb && !obj.$thumb.length) {
|
||||
obj.$thumb = null;
|
||||
}
|
||||
|
||||
obj.thumb = obj.opts.thumb || (obj.$thumb ? obj.$thumb[0].src : null);
|
||||
|
||||
// "caption" is a "special" option, it can be used to customize caption per gallery item
|
||||
if ($.type(obj.opts.caption) === "function") {
|
||||
obj.opts.caption = obj.opts.caption.apply(item, [self, obj]);
|
||||
}
|
||||
|
||||
if ($.type(self.opts.caption) === "function") {
|
||||
obj.opts.caption = self.opts.caption.apply(item, [self, obj]);
|
||||
}
|
||||
|
||||
// Make sure we have caption as a string or jQuery object
|
||||
if (!(obj.opts.caption instanceof $)) {
|
||||
obj.opts.caption = obj.opts.caption === undefined ? "" : obj.opts.caption + "";
|
||||
}
|
||||
|
||||
// Check if url contains "filter" used to filter the content
|
||||
// Example: "ajax.html #something"
|
||||
if (obj.type === "ajax") {
|
||||
srcParts = src.split(/\s+/, 2);
|
||||
|
||||
if (srcParts.length > 1) {
|
||||
obj.src = srcParts.shift();
|
||||
|
||||
obj.opts.filter = srcParts.shift();
|
||||
}
|
||||
}
|
||||
|
||||
// Hide all buttons and disable interactivity for modal items
|
||||
if (obj.opts.modal) {
|
||||
obj.opts = $.extend(true, obj.opts, {
|
||||
trapFocus: true,
|
||||
// Remove buttons
|
||||
infobar: 0,
|
||||
toolbar: 0,
|
||||
|
||||
smallBtn: 0,
|
||||
|
||||
// Disable keyboard navigation
|
||||
keyboard: 0,
|
||||
|
||||
// Disable some modules
|
||||
slideShow: 0,
|
||||
fullScreen: 0,
|
||||
thumbs: 0,
|
||||
touch: 0,
|
||||
|
||||
// Disable click event handlers
|
||||
clickContent: false,
|
||||
clickSlide: false,
|
||||
clickOutside: false,
|
||||
dblclickContent: false,
|
||||
dblclickSlide: false,
|
||||
dblclickOutside: false
|
||||
});
|
||||
}
|
||||
|
||||
// Step 4 - Add processed object to group
|
||||
// ======================================
|
||||
|
||||
self.group.push(obj);
|
||||
});
|
||||
|
||||
// Update controls if gallery is already opened
|
||||
if (Object.keys(self.slides).length) {
|
||||
self.updateControls();
|
||||
|
||||
// Update thumbnails, if needed
|
||||
thumbs = self.Thumbs;
|
||||
|
||||
if (thumbs && thumbs.isActive) {
|
||||
thumbs.create();
|
||||
|
||||
thumbs.focus();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Attach an event handler functions for:
|
||||
// - navigation buttons
|
||||
// - browser scrolling, resizing;
|
||||
// - focusing
|
||||
// - keyboard
|
||||
// - detecting inactivity
|
||||
// ======================================
|
||||
|
||||
addEvents: function () {
|
||||
var self = this;
|
||||
|
||||
self.removeEvents();
|
||||
|
||||
// Make navigation elements clickable
|
||||
// ==================================
|
||||
|
||||
self.$refs.container
|
||||
.on("click.fb-close", "[data-fancybox-close]", function (e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
self.close(e);
|
||||
})
|
||||
.on("touchstart.fb-prev click.fb-prev", "[data-fancybox-prev]", function (e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
self.previous();
|
||||
})
|
||||
.on("touchstart.fb-next click.fb-next", "[data-fancybox-next]", function (e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
self.next();
|
||||
})
|
||||
.on("click.fb", "[data-fancybox-zoom]", function (e) {
|
||||
// Click handler for zoom button
|
||||
self[self.isScaledDown() ? "scaleToActual" : "scaleToFit"]();
|
||||
});
|
||||
|
||||
// Handle page scrolling and browser resizing
|
||||
// ==========================================
|
||||
|
||||
$W.on("orientationchange.fb resize.fb", function (e) {
|
||||
if (e && e.originalEvent && e.originalEvent.type === "resize") {
|
||||
if (self.requestId) {
|
||||
cancelAFrame(self.requestId);
|
||||
}
|
||||
|
||||
self.requestId = requestAFrame(function () {
|
||||
self.update(e);
|
||||
});
|
||||
} else {
|
||||
if (self.current && self.current.type === "iframe") {
|
||||
self.$refs.stage.hide();
|
||||
}
|
||||
|
||||
setTimeout(
|
||||
function () {
|
||||
self.$refs.stage.show();
|
||||
|
||||
self.update(e);
|
||||
},
|
||||
$.fancybox.isMobile ? 600 : 250
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
$D.on("keydown.fb", function (e) {
|
||||
var instance = $.fancybox ? $.fancybox.getInstance() : null,
|
||||
current = instance.current,
|
||||
keycode = e.keyCode || e.which;
|
||||
|
||||
// Trap keyboard focus inside of the modal
|
||||
// =======================================
|
||||
|
||||
if (keycode == 9) {
|
||||
if (current.opts.trapFocus) {
|
||||
self.focus(e);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable keyboard navigation
|
||||
// ==========================
|
||||
|
||||
if (!current.opts.keyboard || e.ctrlKey || e.altKey || e.shiftKey || $(e.target).is("input,textarea,video,audio,select")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Backspace and Esc keys
|
||||
if (keycode === 8 || keycode === 27) {
|
||||
e.preventDefault();
|
||||
|
||||
self.close(e);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Left arrow and Up arrow
|
||||
if (keycode === 37 || keycode === 38) {
|
||||
e.preventDefault();
|
||||
|
||||
self.previous();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Righ arrow and Down arrow
|
||||
if (keycode === 39 || keycode === 40) {
|
||||
e.preventDefault();
|
||||
|
||||
self.next();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self.trigger("afterKeydown", e, keycode);
|
||||
});
|
||||
|
||||
// Hide controls after some inactivity period
|
||||
if (self.group[self.currIndex].opts.idleTime) {
|
||||
self.idleSecondsCounter = 0;
|
||||
|
||||
$D.on(
|
||||
"mousemove.fb-idle mouseleave.fb-idle mousedown.fb-idle touchstart.fb-idle touchmove.fb-idle scroll.fb-idle keydown.fb-idle",
|
||||
function (e) {
|
||||
self.idleSecondsCounter = 0;
|
||||
|
||||
if (self.isIdle) {
|
||||
self.showControls();
|
||||
}
|
||||
|
||||
self.isIdle = false;
|
||||
}
|
||||
);
|
||||
|
||||
self.idleInterval = window.setInterval(function () {
|
||||
self.idleSecondsCounter++;
|
||||
|
||||
if (self.idleSecondsCounter >= self.group[self.currIndex].opts.idleTime && !self.isDragging) {
|
||||
self.isIdle = true;
|
||||
self.idleSecondsCounter = 0;
|
||||
|
||||
self.hideControls();
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
},
|
||||
|
||||
// Remove events added by the core
|
||||
// ===============================
|
||||
|
||||
removeEvents: function () {
|
||||
var self = this;
|
||||
|
||||
$W.off("orientationchange.fb resize.fb");
|
||||
$D.off("keydown.fb .fb-idle");
|
||||
|
||||
this.$refs.container.off(".fb-close .fb-prev .fb-next");
|
||||
|
||||
if (self.idleInterval) {
|
||||
window.clearInterval(self.idleInterval);
|
||||
|
||||
self.idleInterval = null;
|
||||
}
|
||||
},
|
||||
|
||||
// Change to previous gallery item
|
||||
// ===============================
|
||||
|
||||
previous: function (duration) {
|
||||
return this.jumpTo(this.currPos - 1, duration);
|
||||
},
|
||||
|
||||
// Change to next gallery item
|
||||
// ===========================
|
||||
|
||||
next: function (duration) {
|
||||
return this.jumpTo(this.currPos + 1, duration);
|
||||
},
|
||||
|
||||
// Switch to selected gallery item
|
||||
// ===============================
|
||||
|
||||
jumpTo: function (pos, duration) {
|
||||
var self = this,
|
||||
groupLen = self.group.length,
|
||||
firstRun,
|
||||
isMoved,
|
||||
loop,
|
||||
current,
|
||||
previous,
|
||||
slidePos,
|
||||
stagePos,
|
||||
prop,
|
||||
diff;
|
||||
|
||||
if (self.isDragging || self.isClosing || (self.isAnimating && self.firstRun)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Should loop?
|
||||
pos = parseInt(pos, 10);
|
||||
loop = self.current ? self.current.opts.loop : self.opts.loop;
|
||||
|
||||
if (!loop && (pos < 0 || pos >= groupLen)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if opening for the first time; this helps to speed things up
|
||||
firstRun = self.firstRun = !Object.keys(self.slides).length;
|
||||
|
||||
// Create slides
|
||||
previous = self.current;
|
||||
|
||||
self.prevIndex = self.currIndex;
|
||||
self.prevPos = self.currPos;
|
||||
|
||||
current = self.createSlide(pos);
|
||||
|
||||
if (groupLen > 1) {
|
||||
if (loop || current.index < groupLen - 1) {
|
||||
self.createSlide(pos + 1);
|
||||
}
|
||||
|
||||
if (loop || current.index > 0) {
|
||||
self.createSlide(pos - 1);
|
||||
}
|
||||
}
|
||||
|
||||
self.current = current;
|
||||
self.currIndex = current.index;
|
||||
self.currPos = current.pos;
|
||||
|
||||
self.trigger("beforeShow", firstRun);
|
||||
|
||||
self.updateControls();
|
||||
|
||||
// Validate duration length
|
||||
current.forcedDuration = undefined;
|
||||
|
||||
if ($.isNumeric(duration)) {
|
||||
current.forcedDuration = duration;
|
||||
} else {
|
||||
duration = current.opts[firstRun ? "animationDuration" : "transitionDuration"];
|
||||
}
|
||||
|
||||
duration = parseInt(duration, 10);
|
||||
|
||||
// Check if user has swiped the slides or if still animating
|
||||
isMoved = self.isMoved(current);
|
||||
|
||||
// Make sure current slide is visible
|
||||
current.$slide.addClass("fancybox-slide--current");
|
||||
|
||||
// Fresh start - reveal container, current slide and start loading content
|
||||
if (firstRun) {
|
||||
if (current.opts.animationEffect && duration) {
|
||||
self.$refs.container.css("transition-duration", duration + "ms");
|
||||
}
|
||||
|
||||
self.$refs.container.addClass("fancybox-is-open").trigger("focus");
|
||||
|
||||
// Attempt to load content into slide
|
||||
// This will later call `afterLoad` -> `revealContent`
|
||||
self.loadSlide(current);
|
||||
|
||||
self.preload("image");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Get actual slide/stage positions (before cleaning up)
|
||||
slidePos = $.fancybox.getTranslate(previous.$slide);
|
||||
stagePos = $.fancybox.getTranslate(self.$refs.stage);
|
||||
|
||||
// Clean up all slides
|
||||
$.each(self.slides, function (index, slide) {
|
||||
$.fancybox.stop(slide.$slide, true);
|
||||
});
|
||||
|
||||
if (previous.pos !== current.pos) {
|
||||
previous.isComplete = false;
|
||||
}
|
||||
|
||||
previous.$slide.removeClass("fancybox-slide--complete fancybox-slide--current");
|
||||
|
||||
// If slides are out of place, then animate them to correct position
|
||||
if (isMoved) {
|
||||
// Calculate horizontal swipe distance
|
||||
diff = slidePos.left - (previous.pos * slidePos.width + previous.pos * previous.opts.gutter);
|
||||
|
||||
$.each(self.slides, function (index, slide) {
|
||||
slide.$slide.removeClass("fancybox-animated").removeClass(function (index, className) {
|
||||
return (className.match(/(^|\s)fancybox-fx-\S+/g) || []).join(" ");
|
||||
});
|
||||
|
||||
// Make sure that each slide is in equal distance
|
||||
// This is mostly needed for freshly added slides, because they are not yet positioned
|
||||
var leftPos = slide.pos * slidePos.width + slide.pos * slide.opts.gutter;
|
||||
|
||||
$.fancybox.setTranslate(slide.$slide, {
|
||||
top: 0,
|
||||
left: leftPos - stagePos.left + diff
|
||||
});
|
||||
|
||||
if (slide.pos !== current.pos) {
|
||||
slide.$slide.addClass("fancybox-slide--" + (slide.pos > current.pos ? "next" : "previous"));
|
||||
}
|
||||
|
||||
// Redraw to make sure that transition will start
|
||||
forceRedraw(slide.$slide);
|
||||
|
||||
// Animate the slide
|
||||
$.fancybox.animate(
|
||||
slide.$slide, {
|
||||
top: 0,
|
||||
left: (slide.pos - current.pos) * slidePos.width + (slide.pos - current.pos) * slide.opts.gutter
|
||||
},
|
||||
duration,
|
||||
function () {
|
||||
slide.$slide
|
||||
.css({
|
||||
transform: "",
|
||||
opacity: ""
|
||||
})
|
||||
.removeClass("fancybox-slide--next fancybox-slide--previous");
|
||||
|
||||
if (slide.pos === self.currPos) {
|
||||
self.complete();
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
} else if (duration && current.opts.transitionEffect) {
|
||||
// Set transition effect for previously active slide
|
||||
prop = "fancybox-animated fancybox-fx-" + current.opts.transitionEffect;
|
||||
|
||||
previous.$slide.addClass("fancybox-slide--" + (previous.pos > current.pos ? "next" : "previous"));
|
||||
|
||||
$.fancybox.animate(
|
||||
previous.$slide,
|
||||
prop,
|
||||
duration,
|
||||
function () {
|
||||
previous.$slide.removeClass(prop).removeClass("fancybox-slide--next fancybox-slide--previous");
|
||||
},
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
if (current.isLoaded) {
|
||||
self.revealContent(current);
|
||||
} else {
|
||||
self.loadSlide(current);
|
||||
}
|
||||
|
||||
self.preload("image");
|
||||
},
|
||||
|
||||
// Create new "slide" element
|
||||
// These are gallery items that are actually added to DOM
|
||||
// =======================================================
|
||||
|
||||
createSlide: function (pos) {
|
||||
var self = this,
|
||||
$slide,
|
||||
index;
|
||||
|
||||
index = pos % self.group.length;
|
||||
index = index < 0 ? self.group.length + index : index;
|
||||
|
||||
if (!self.slides[pos] && self.group[index]) {
|
||||
$slide = $('<div class="fancybox-slide"></div>').appendTo(self.$refs.stage);
|
||||
|
||||
self.slides[pos] = $.extend(true, {}, self.group[index], {
|
||||
pos: pos,
|
||||
$slide: $slide,
|
||||
isLoaded: false
|
||||
});
|
||||
|
||||
self.updateSlide(self.slides[pos]);
|
||||
}
|
||||
|
||||
return self.slides[pos];
|
||||
},
|
||||
|
||||
// Scale image to the actual size of the image;
|
||||
// x and y values should be relative to the slide
|
||||
// ==============================================
|
||||
|
||||
scaleToActual: function (x, y, duration) {
|
||||
var self = this,
|
||||
current = self.current,
|
||||
$content = current.$content,
|
||||
canvasWidth = $.fancybox.getTranslate(current.$slide).width,
|
||||
canvasHeight = $.fancybox.getTranslate(current.$slide).height,
|
||||
newImgWidth = current.width,
|
||||
newImgHeight = current.height,
|
||||
imgPos,
|
||||
posX,
|
||||
posY,
|
||||
scaleX,
|
||||
scaleY;
|
||||
|
||||
if (self.isAnimating || self.isMoved() || !$content || !(current.type == "image" && current.isLoaded && !current.hasError)) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.isAnimating = true;
|
||||
|
||||
$.fancybox.stop($content);
|
||||
|
||||
x = x === undefined ? canvasWidth * 0.5 : x;
|
||||
y = y === undefined ? canvasHeight * 0.5 : y;
|
||||
|
||||
imgPos = $.fancybox.getTranslate($content);
|
||||
|
||||
imgPos.top -= $.fancybox.getTranslate(current.$slide).top;
|
||||
imgPos.left -= $.fancybox.getTranslate(current.$slide).left;
|
||||
|
||||
scaleX = newImgWidth / imgPos.width;
|
||||
scaleY = newImgHeight / imgPos.height;
|
||||
|
||||
// Get center position for original image
|
||||
posX = canvasWidth * 0.5 - newImgWidth * 0.5;
|
||||
posY = canvasHeight * 0.5 - newImgHeight * 0.5;
|
||||
|
||||
// Make sure image does not move away from edges
|
||||
if (newImgWidth > canvasWidth) {
|
||||
posX = imgPos.left * scaleX - (x * scaleX - x);
|
||||
|
||||
if (posX > 0) {
|
||||
posX = 0;
|
||||
}
|
||||
|
||||
if (posX < canvasWidth - newImgWidth) {
|
||||
posX = canvasWidth - newImgWidth;
|
||||
}
|
||||
}
|
||||
|
||||
if (newImgHeight > canvasHeight) {
|
||||
posY = imgPos.top * scaleY - (y * scaleY - y);
|
||||
|
||||
if (posY > 0) {
|
||||
posY = 0;
|
||||
}
|
||||
|
||||
if (posY < canvasHeight - newImgHeight) {
|
||||
posY = canvasHeight - newImgHeight;
|
||||
}
|
||||
}
|
||||
|
||||
self.updateCursor(newImgWidth, newImgHeight);
|
||||
|
||||
$.fancybox.animate(
|
||||
$content, {
|
||||
top: posY,
|
||||
left: posX,
|
||||
scaleX: scaleX,
|
||||
scaleY: scaleY
|
||||
},
|
||||
duration || 366,
|
||||
function () {
|
||||
self.isAnimating = false;
|
||||
}
|
||||
);
|
||||
|
||||
// Stop slideshow
|
||||
if (self.SlideShow && self.SlideShow.isActive) {
|
||||
self.SlideShow.stop();
|
||||
}
|
||||
},
|
||||
|
||||
// Scale image to fit inside parent element
|
||||
// ========================================
|
||||
|
||||
scaleToFit: function (duration) {
|
||||
var self = this,
|
||||
current = self.current,
|
||||
$content = current.$content,
|
||||
end;
|
||||
|
||||
if (self.isAnimating || self.isMoved() || !$content || !(current.type == "image" && current.isLoaded && !current.hasError)) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.isAnimating = true;
|
||||
|
||||
$.fancybox.stop($content);
|
||||
|
||||
end = self.getFitPos(current);
|
||||
|
||||
self.updateCursor(end.width, end.height);
|
||||
|
||||
$.fancybox.animate(
|
||||
$content, {
|
||||
top: end.top,
|
||||
left: end.left,
|
||||
scaleX: end.width / $content.width(),
|
||||
scaleY: end.height / $content.height()
|
||||
},
|
||||
duration || 366,
|
||||
function () {
|
||||
self.isAnimating = false;
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
// Calculate image size to fit inside viewport
|
||||
// ===========================================
|
||||
|
||||
getFitPos: function (slide) {
|
||||
var self = this,
|
||||
$content = slide.$content,
|
||||
$slide = slide.$slide,
|
||||
width = slide.width || slide.opts.width,
|
||||
height = slide.height || slide.opts.height,
|
||||
maxWidth,
|
||||
maxHeight,
|
||||
minRatio,
|
||||
aspectRatio,
|
||||
rez = {};
|
||||
|
||||
if (!slide.isLoaded || !$content || !$content.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
maxWidth = $.fancybox.getTranslate(self.$refs.stage).width;
|
||||
maxHeight = $.fancybox.getTranslate(self.$refs.stage).height;
|
||||
|
||||
maxWidth -=
|
||||
parseFloat($slide.css("paddingLeft")) +
|
||||
parseFloat($slide.css("paddingRight")) +
|
||||
parseFloat($content.css("marginLeft")) +
|
||||
parseFloat($content.css("marginRight"));
|
||||
|
||||
maxHeight -=
|
||||
parseFloat($slide.css("paddingTop")) +
|
||||
parseFloat($slide.css("paddingBottom")) +
|
||||
parseFloat($content.css("marginTop")) +
|
||||
parseFloat($content.css("marginBottom"));
|
||||
|
||||
if (!width || !height) {
|
||||
width = maxWidth;
|
||||
height = maxHeight;
|
||||
}
|
||||
|
||||
minRatio = Math.min(1, maxWidth / width, maxHeight / height);
|
||||
|
||||
width = minRatio * width;
|
||||
height = minRatio * height;
|
||||
|
||||
// Adjust width/height to precisely fit into container
|
||||
if (width > maxWidth - 0.5) {
|
||||
width = maxWidth;
|
||||
}
|
||||
|
||||
if (height > maxHeight - 0.5) {
|
||||
height = maxHeight;
|
||||
}
|
||||
|
||||
if (slide.type === "image") {
|
||||
rez.top = Math.floor((maxHeight - height) * 0.5) + parseFloat($slide.css("paddingTop"));
|
||||
rez.left = Math.floor((maxWidth - width) * 0.5) + parseFloat($slide.css("paddingLeft"));
|
||||
} else if (slide.contentType === "video") {
|
||||
// Force aspect ratio for the video
|
||||
// "I say the whole world must learn of our peaceful ways… by force!"
|
||||
aspectRatio = slide.opts.width && slide.opts.height ? width / height : slide.opts.ratio || 16 / 9;
|
||||
|
||||
if (height > width / aspectRatio) {
|
||||
height = width / aspectRatio;
|
||||
} else if (width > height * aspectRatio) {
|
||||
width = height * aspectRatio;
|
||||
}
|
||||
}
|
||||
|
||||
rez.width = width;
|
||||
rez.height = height;
|
||||
|
||||
return rez;
|
||||
},
|
||||
|
||||
// Update content size and position for all slides
|
||||
// ==============================================
|
||||
|
||||
update: function (e) {
|
||||
var self = this;
|
||||
|
||||
$.each(self.slides, function (key, slide) {
|
||||
self.updateSlide(slide, e);
|
||||
});
|
||||
},
|
||||
|
||||
// Update slide content position and size
|
||||
// ======================================
|
||||
|
||||
updateSlide: function (slide, e) {
|
||||
var self = this,
|
||||
$content = slide && slide.$content,
|
||||
width = slide.width || slide.opts.width,
|
||||
height = slide.height || slide.opts.height,
|
||||
$slide = slide.$slide;
|
||||
|
||||
// First, prevent caption overlap, if needed
|
||||
self.adjustCaption(slide);
|
||||
|
||||
// Then resize content to fit inside the slide
|
||||
if ($content && (width || height || slide.contentType === "video") && !slide.hasError) {
|
||||
$.fancybox.stop($content);
|
||||
|
||||
$.fancybox.setTranslate($content, self.getFitPos(slide));
|
||||
|
||||
if (slide.pos === self.currPos) {
|
||||
self.isAnimating = false;
|
||||
|
||||
self.updateCursor();
|
||||
}
|
||||
}
|
||||
|
||||
// Then some adjustments
|
||||
self.adjustLayout(slide);
|
||||
|
||||
if ($slide.length) {
|
||||
$slide.trigger("refresh");
|
||||
|
||||
if (slide.pos === self.currPos) {
|
||||
self.$refs.toolbar
|
||||
.add(self.$refs.navigation.find(".fancybox-button--arrow_right"))
|
||||
.toggleClass("compensate-for-scrollbar", $slide.get(0).scrollHeight > $slide.get(0).clientHeight);
|
||||
}
|
||||
}
|
||||
|
||||
self.trigger("onUpdate", slide, e);
|
||||
},
|
||||
|
||||
// Horizontally center slide
|
||||
// =========================
|
||||
|
||||
centerSlide: function (duration) {
|
||||
var self = this,
|
||||
current = self.current,
|
||||
$slide = current.$slide;
|
||||
|
||||
if (self.isClosing || !current) {
|
||||
return;
|
||||
}
|
||||
|
||||
$slide.siblings().css({
|
||||
transform: "",
|
||||
opacity: ""
|
||||
});
|
||||
|
||||
$slide
|
||||
.parent()
|
||||
.children()
|
||||
.removeClass("fancybox-slide--previous fancybox-slide--next");
|
||||
|
||||
$.fancybox.animate(
|
||||
$slide, {
|
||||
top: 0,
|
||||
left: 0,
|
||||
opacity: 1
|
||||
},
|
||||
duration === undefined ? 0 : duration,
|
||||
function () {
|
||||
// Clean up
|
||||
$slide.css({
|
||||
transform: "",
|
||||
opacity: ""
|
||||
});
|
||||
|
||||
if (!current.isComplete) {
|
||||
self.complete();
|
||||
}
|
||||
},
|
||||
false
|
||||
);
|
||||
},
|
||||
|
||||
// Check if current slide is moved (swiped)
|
||||
// ========================================
|
||||
|
||||
isMoved: function (slide) {
|
||||
var current = slide || this.current,
|
||||
slidePos,
|
||||
stagePos;
|
||||
|
||||
if (!current) {
|
||||
return false;
|
||||
}
|
||||
|
||||
stagePos = $.fancybox.getTranslate(this.$refs.stage);
|
||||
slidePos = $.fancybox.getTranslate(current.$slide);
|
||||
|
||||
return (
|
||||
!current.$slide.hasClass("fancybox-animated") &&
|
||||
(Math.abs(slidePos.top - stagePos.top) > 0.5 || Math.abs(slidePos.left - stagePos.left) > 0.5)
|
||||
);
|
||||
},
|
||||
|
||||
// Update cursor style depending if content can be zoomed
|
||||
// ======================================================
|
||||
|
||||
updateCursor: function (nextWidth, nextHeight) {
|
||||
var self = this,
|
||||
current = self.current,
|
||||
$container = self.$refs.container,
|
||||
canPan,
|
||||
isZoomable;
|
||||
|
||||
if (!current || self.isClosing || !self.Guestures) {
|
||||
return;
|
||||
}
|
||||
|
||||
$container.removeClass("fancybox-is-zoomable fancybox-can-zoomIn fancybox-can-zoomOut fancybox-can-swipe fancybox-can-pan");
|
||||
|
||||
canPan = self.canPan(nextWidth, nextHeight);
|
||||
|
||||
isZoomable = canPan ? true : self.isZoomable();
|
||||
|
||||
$container.toggleClass("fancybox-is-zoomable", isZoomable);
|
||||
|
||||
$("[data-fancybox-zoom]").prop("disabled", !isZoomable);
|
||||
|
||||
if (canPan) {
|
||||
$container.addClass("fancybox-can-pan");
|
||||
} else if (
|
||||
isZoomable &&
|
||||
(current.opts.clickContent === "zoom" || ($.isFunction(current.opts.clickContent) && current.opts.clickContent(current) == "zoom"))
|
||||
) {
|
||||
$container.addClass("fancybox-can-zoomIn");
|
||||
} else if (current.opts.touch && (current.opts.touch.vertical || self.group.length > 1) && current.contentType !== "video") {
|
||||
$container.addClass("fancybox-can-swipe");
|
||||
}
|
||||
},
|
||||
|
||||
// Check if current slide is zoomable
|
||||
// ==================================
|
||||
|
||||
isZoomable: function () {
|
||||
var self = this,
|
||||
current = self.current,
|
||||
fitPos;
|
||||
|
||||
// Assume that slide is zoomable if:
|
||||
// - image is still loading
|
||||
// - actual size of the image is smaller than available area
|
||||
if (current && !self.isClosing && current.type === "image" && !current.hasError) {
|
||||
if (!current.isLoaded) {
|
||||
return true;
|
||||
}
|
||||
|
||||
fitPos = self.getFitPos(current);
|
||||
|
||||
if (fitPos && (current.width > fitPos.width || current.height > fitPos.height)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
// Check if current image dimensions are smaller than actual
|
||||
// =========================================================
|
||||
|
||||
isScaledDown: function (nextWidth, nextHeight) {
|
||||
var self = this,
|
||||
rez = false,
|
||||
current = self.current,
|
||||
$content = current.$content;
|
||||
|
||||
if (nextWidth !== undefined && nextHeight !== undefined) {
|
||||
rez = nextWidth < current.width && nextHeight < current.height;
|
||||
} else if ($content) {
|
||||
rez = $.fancybox.getTranslate($content);
|
||||
rez = rez.width < current.width && rez.height < current.height;
|
||||
}
|
||||
|
||||
return rez;
|
||||
},
|
||||
|
||||
// Check if image dimensions exceed parent element
|
||||
// ===============================================
|
||||
|
||||
canPan: function (nextWidth, nextHeight) {
|
||||
var self = this,
|
||||
current = self.current,
|
||||
pos = null,
|
||||
rez = false;
|
||||
|
||||
if (current.type === "image" && (current.isComplete || (nextWidth && nextHeight)) && !current.hasError) {
|
||||
rez = self.getFitPos(current);
|
||||
|
||||
if (nextWidth !== undefined && nextHeight !== undefined) {
|
||||
pos = {
|
||||
width: nextWidth,
|
||||
height: nextHeight
|
||||
};
|
||||
} else if (current.isComplete) {
|
||||
pos = $.fancybox.getTranslate(current.$content);
|
||||
}
|
||||
|
||||
if (pos && rez) {
|
||||
rez = Math.abs(pos.width - rez.width) > 1.5 || Math.abs(pos.height - rez.height) > 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
return rez;
|
||||
},
|
||||
|
||||
// Load content into the slide
|
||||
// ===========================
|
||||
|
||||
loadSlide: function (slide) {
|
||||
var self = this,
|
||||
type,
|
||||
$slide,
|
||||
ajaxLoad;
|
||||
|
||||
if (slide.isLoading || slide.isLoaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
slide.isLoading = true;
|
||||
|
||||
if (self.trigger("beforeLoad", slide) === false) {
|
||||
slide.isLoading = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
type = slide.type;
|
||||
$slide = slide.$slide;
|
||||
|
||||
$slide
|
||||
.off("refresh")
|
||||
.trigger("onReset")
|
||||
.addClass(slide.opts.slideClass);
|
||||
|
||||
// Create content depending on the type
|
||||
switch (type) {
|
||||
case "image":
|
||||
self.setImage(slide);
|
||||
|
||||
break;
|
||||
|
||||
case "iframe":
|
||||
self.setIframe(slide);
|
||||
|
||||
break;
|
||||
|
||||
case "html":
|
||||
self.setContent(slide, slide.src || slide.content);
|
||||
|
||||
break;
|
||||
|
||||
case "video":
|
||||
self.setContent(
|
||||
slide,
|
||||
slide.opts.video.tpl
|
||||
.replace(/\{\{src\}\}/gi, slide.src)
|
||||
.replace("{{format}}", slide.opts.videoFormat || slide.opts.video.format || "")
|
||||
.replace("{{poster}}", slide.thumb || "")
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case "inline":
|
||||
if ($(slide.src).length) {
|
||||
self.setContent(slide, $(slide.src));
|
||||
} else {
|
||||
self.setError(slide);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "ajax":
|
||||
self.showLoading(slide);
|
||||
|
||||
ajaxLoad = $.ajax(
|
||||
$.extend({}, slide.opts.ajax.settings, {
|
||||
url: slide.src,
|
||||
success: function (data, textStatus) {
|
||||
if (textStatus === "success") {
|
||||
self.setContent(slide, data);
|
||||
}
|
||||
},
|
||||
error: function (jqXHR, textStatus) {
|
||||
if (jqXHR && textStatus !== "abort") {
|
||||
self.setError(slide);
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
$slide.one("onReset", function () {
|
||||
ajaxLoad.abort();
|
||||
});
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
self.setError(slide);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
// Use thumbnail image, if possible
|
||||
// ================================
|
||||
|
||||
setImage: function (slide) {
|
||||
var self = this,
|
||||
ghost;
|
||||
|
||||
// Check if need to show loading icon
|
||||
setTimeout(function () {
|
||||
var $img = slide.$image;
|
||||
|
||||
if (!self.isClosing && slide.isLoading && (!$img || !$img.length || !$img[0].complete) && !slide.hasError) {
|
||||
self.showLoading(slide);
|
||||
}
|
||||
}, 50);
|
||||
|
||||
//Check if image has srcset
|
||||
self.checkSrcset(slide);
|
||||
|
||||
// This will be wrapper containing both ghost and actual image
|
||||
slide.$content = $('<div class="fancybox-content"></div>')
|
||||
.addClass("fancybox-is-hidden")
|
||||
.appendTo(slide.$slide.addClass("fancybox-slide--image"));
|
||||
|
||||
// If we have a thumbnail, we can display it while actual image is loading
|
||||
// Users will not stare at black screen and actual image will appear gradually
|
||||
if (slide.opts.preload !== false && slide.opts.width && slide.opts.height && slide.thumb) {
|
||||
slide.width = slide.opts.width;
|
||||
slide.height = slide.opts.height;
|
||||
|
||||
ghost = document.createElement("img");
|
||||
|
||||
ghost.onerror = function () {
|
||||
$(this).remove();
|
||||
|
||||
slide.$ghost = null;
|
||||
};
|
||||
|
||||
ghost.onload = function () {
|
||||
self.afterLoad(slide);
|
||||
};
|
||||
|
||||
slide.$ghost = $(ghost)
|
||||
.addClass("fancybox-image")
|
||||
.appendTo(slide.$content)
|
||||
.attr("src", slide.thumb);
|
||||
}
|
||||
|
||||
// Start loading actual image
|
||||
self.setBigImage(slide);
|
||||
},
|
||||
|
||||
// Check if image has srcset and get the source
|
||||
// ============================================
|
||||
checkSrcset: function (slide) {
|
||||
var srcset = slide.opts.srcset || slide.opts.image.srcset,
|
||||
found,
|
||||
temp,
|
||||
pxRatio,
|
||||
windowWidth;
|
||||
|
||||
// If we have "srcset", then we need to find first matching "src" value.
|
||||
// This is necessary, because when you set an src attribute, the browser will preload the image
|
||||
// before any javascript or even CSS is applied.
|
||||
if (srcset) {
|
||||
pxRatio = window.devicePixelRatio || 1;
|
||||
windowWidth = window.innerWidth * pxRatio;
|
||||
|
||||
temp = srcset.split(",").map(function (el) {
|
||||
var ret = {};
|
||||
|
||||
el.trim()
|
||||
.split(/\s+/)
|
||||
.forEach(function (el, i) {
|
||||
var value = parseInt(el.substring(0, el.length - 1), 10);
|
||||
|
||||
if (i === 0) {
|
||||
return (ret.url = el);
|
||||
}
|
||||
|
||||
if (value) {
|
||||
ret.value = value;
|
||||
ret.postfix = el[el.length - 1];
|
||||
}
|
||||
});
|
||||
|
||||
return ret;
|
||||
});
|
||||
|
||||
// Sort by value
|
||||
temp.sort(function (a, b) {
|
||||
return a.value - b.value;
|
||||
});
|
||||
|
||||
// Ok, now we have an array of all srcset values
|
||||
for (var j = 0; j < temp.length; j++) {
|
||||
var el = temp[j];
|
||||
|
||||
if ((el.postfix === "w" && el.value >= windowWidth) || (el.postfix === "x" && el.value >= pxRatio)) {
|
||||
found = el;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If not found, take the last one
|
||||
if (!found && temp.length) {
|
||||
found = temp[temp.length - 1];
|
||||
}
|
||||
|
||||
if (found) {
|
||||
slide.src = found.url;
|
||||
|
||||
// If we have default width/height values, we can calculate height for matching source
|
||||
if (slide.width && slide.height && found.postfix == "w") {
|
||||
slide.height = (slide.width / slide.height) * found.value;
|
||||
slide.width = found.value;
|
||||
}
|
||||
|
||||
slide.opts.srcset = srcset;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Create full-size image
|
||||
// ======================
|
||||
|
||||
setBigImage: function (slide) {
|
||||
var self = this,
|
||||
img = document.createElement("img"),
|
||||
$img = $(img);
|
||||
|
||||
slide.$image = $img
|
||||
.one("error", function () {
|
||||
self.setError(slide);
|
||||
})
|
||||
.one("load", function () {
|
||||
var sizes;
|
||||
|
||||
if (!slide.$ghost) {
|
||||
self.resolveImageSlideSize(slide, this.naturalWidth, this.naturalHeight);
|
||||
|
||||
self.afterLoad(slide);
|
||||
}
|
||||
|
||||
if (self.isClosing) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (slide.opts.srcset) {
|
||||
sizes = slide.opts.sizes;
|
||||
|
||||
if (!sizes || sizes === "auto") {
|
||||
sizes =
|
||||
(slide.width / slide.height > 1 && $W.width() / $W.height() > 1 ? "100" : Math.round((slide.width / slide.height) * 100)) +
|
||||
"vw";
|
||||
}
|
||||
|
||||
$img.attr("sizes", sizes).attr("srcset", slide.opts.srcset);
|
||||
}
|
||||
|
||||
// Hide temporary image after some delay
|
||||
if (slide.$ghost) {
|
||||
setTimeout(function () {
|
||||
if (slide.$ghost && !self.isClosing) {
|
||||
slide.$ghost.hide();
|
||||
}
|
||||
}, Math.min(300, Math.max(1000, slide.height / 1600)));
|
||||
}
|
||||
|
||||
self.hideLoading(slide);
|
||||
})
|
||||
.addClass("fancybox-image")
|
||||
.attr("src", slide.src)
|
||||
.appendTo(slide.$content);
|
||||
|
||||
if ((img.complete || img.readyState == "complete") && $img.naturalWidth && $img.naturalHeight) {
|
||||
$img.trigger("load");
|
||||
} else if (img.error) {
|
||||
$img.trigger("error");
|
||||
}
|
||||
},
|
||||
|
||||
// Computes the slide size from image size and maxWidth/maxHeight
|
||||
// ==============================================================
|
||||
|
||||
resolveImageSlideSize: function (slide, imgWidth, imgHeight) {
|
||||
var maxWidth = parseInt(slide.opts.width, 10),
|
||||
maxHeight = parseInt(slide.opts.height, 10);
|
||||
|
||||
// Sets the default values from the image
|
||||
slide.width = imgWidth;
|
||||
slide.height = imgHeight;
|
||||
|
||||
if (maxWidth > 0) {
|
||||
slide.width = maxWidth;
|
||||
slide.height = Math.floor((maxWidth * imgHeight) / imgWidth);
|
||||
}
|
||||
|
||||
if (maxHeight > 0) {
|
||||
slide.width = Math.floor((maxHeight * imgWidth) / imgHeight);
|
||||
slide.height = maxHeight;
|
||||
}
|
||||
},
|
||||
|
||||
// Create iframe wrapper, iframe and bindings
|
||||
// ==========================================
|
||||
|
||||
setIframe: function (slide) {
|
||||
var self = this,
|
||||
opts = slide.opts.iframe,
|
||||
$slide = slide.$slide,
|
||||
$iframe;
|
||||
|
||||
slide.$content = $('<div class="fancybox-content' + (opts.preload ? " fancybox-is-hidden" : "") + '"></div>')
|
||||
.css(opts.css)
|
||||
.appendTo($slide);
|
||||
|
||||
$slide.addClass("fancybox-slide--" + slide.contentType);
|
||||
|
||||
slide.$iframe = $iframe = $(opts.tpl.replace(/\{rnd\}/g, new Date().getTime()))
|
||||
.attr(opts.attr)
|
||||
.appendTo(slide.$content);
|
||||
|
||||
if (opts.preload) {
|
||||
self.showLoading(slide);
|
||||
|
||||
// Unfortunately, it is not always possible to determine if iframe is successfully loaded
|
||||
// (due to browser security policy)
|
||||
|
||||
$iframe.on("load.fb error.fb", function (e) {
|
||||
this.isReady = 1;
|
||||
|
||||
slide.$slide.trigger("refresh");
|
||||
|
||||
self.afterLoad(slide);
|
||||
});
|
||||
|
||||
// Recalculate iframe content size
|
||||
// ===============================
|
||||
|
||||
$slide.on("refresh.fb", function () {
|
||||
var $content = slide.$content,
|
||||
frameWidth = opts.css.width,
|
||||
frameHeight = opts.css.height,
|
||||
$contents,
|
||||
$body;
|
||||
|
||||
if ($iframe[0].isReady !== 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$contents = $iframe.contents();
|
||||
$body = $contents.find("body");
|
||||
} catch (ignore) {}
|
||||
|
||||
// Calculate content dimensions, if it is accessible
|
||||
if ($body && $body.length && $body.children().length) {
|
||||
// Avoid scrolling to top (if multiple instances)
|
||||
$slide.css("overflow", "visible");
|
||||
|
||||
$content.css({
|
||||
width: "100%",
|
||||
"max-width": "100%",
|
||||
height: "9999px"
|
||||
});
|
||||
|
||||
if (frameWidth === undefined) {
|
||||
frameWidth = Math.ceil(Math.max($body[0].clientWidth, $body.outerWidth(true)));
|
||||
}
|
||||
|
||||
$content.css("width", frameWidth ? frameWidth : "").css("max-width", "");
|
||||
|
||||
if (frameHeight === undefined) {
|
||||
frameHeight = Math.ceil(Math.max($body[0].clientHeight, $body.outerHeight(true)));
|
||||
}
|
||||
|
||||
$content.css("height", frameHeight ? frameHeight : "");
|
||||
|
||||
$slide.css("overflow", "auto");
|
||||
}
|
||||
|
||||
$content.removeClass("fancybox-is-hidden");
|
||||
});
|
||||
} else {
|
||||
self.afterLoad(slide);
|
||||
}
|
||||
|
||||
$iframe.attr("src", slide.src);
|
||||
|
||||
// Remove iframe if closing or changing gallery item
|
||||
$slide.one("onReset", function () {
|
||||
// This helps IE not to throw errors when closing
|
||||
try {
|
||||
$(this)
|
||||
.find("iframe")
|
||||
.hide()
|
||||
.unbind()
|
||||
.attr("src", "//about:blank");
|
||||
} catch (ignore) {}
|
||||
|
||||
$(this)
|
||||
.off("refresh.fb")
|
||||
.empty();
|
||||
|
||||
slide.isLoaded = false;
|
||||
slide.isRevealed = false;
|
||||
});
|
||||
},
|
||||
|
||||
// Wrap and append content to the slide
|
||||
// ======================================
|
||||
|
||||
setContent: function (slide, content) {
|
||||
var self = this;
|
||||
|
||||
if (self.isClosing) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.hideLoading(slide);
|
||||
|
||||
if (slide.$content) {
|
||||
$.fancybox.stop(slide.$content);
|
||||
}
|
||||
|
||||
slide.$slide.empty();
|
||||
|
||||
// If content is a jQuery object, then it will be moved to the slide.
|
||||
// The placeholder is created so we will know where to put it back.
|
||||
if (isQuery(content) && content.parent().length) {
|
||||
// Make sure content is not already moved to fancyBox
|
||||
if (content.hasClass("fancybox-content") || content.parent().hasClass("fancybox-content")) {
|
||||
content.parents(".fancybox-slide").trigger("onReset");
|
||||
}
|
||||
|
||||
// Create temporary element marking original place of the content
|
||||
slide.$placeholder = $("<div>")
|
||||
.hide()
|
||||
.insertAfter(content);
|
||||
|
||||
// Make sure content is visible
|
||||
content.css("display", "inline-block");
|
||||
} else if (!slide.hasError) {
|
||||
// If content is just a plain text, try to convert it to html
|
||||
if ($.type(content) === "string") {
|
||||
content = $("<div>")
|
||||
.append($.trim(content))
|
||||
.contents();
|
||||
}
|
||||
|
||||
// If "filter" option is provided, then filter content
|
||||
if (slide.opts.filter) {
|
||||
content = $("<div>")
|
||||
.html(content)
|
||||
.find(slide.opts.filter);
|
||||
}
|
||||
}
|
||||
|
||||
slide.$slide.one("onReset", function () {
|
||||
// Pause all html5 video/audio
|
||||
$(this)
|
||||
.find("video,audio")
|
||||
.trigger("pause");
|
||||
|
||||
// Put content back
|
||||
if (slide.$placeholder) {
|
||||
slide.$placeholder.after(content.removeClass("fancybox-content").hide()).remove();
|
||||
|
||||
slide.$placeholder = null;
|
||||
}
|
||||
|
||||
// Remove custom close button
|
||||
if (slide.$smallBtn) {
|
||||
slide.$smallBtn.remove();
|
||||
|
||||
slide.$smallBtn = null;
|
||||
}
|
||||
|
||||
// Remove content and mark slide as not loaded
|
||||
if (!slide.hasError) {
|
||||
$(this).empty();
|
||||
|
||||
slide.isLoaded = false;
|
||||
slide.isRevealed = false;
|
||||
}
|
||||
});
|
||||
|
||||
$(content).appendTo(slide.$slide);
|
||||
|
||||
if ($(content).is("video,audio")) {
|
||||
$(content).addClass("fancybox-video");
|
||||
|
||||
$(content).wrap("<div></div>");
|
||||
|
||||
slide.contentType = "video";
|
||||
|
||||
slide.opts.width = slide.opts.width || $(content).attr("width");
|
||||
slide.opts.height = slide.opts.height || $(content).attr("height");
|
||||
}
|
||||
|
||||
slide.$content = slide.$slide
|
||||
.children()
|
||||
.filter("div,form,main,video,audio,article,.fancybox-content")
|
||||
.first();
|
||||
|
||||
slide.$content.siblings().hide();
|
||||
|
||||
// Re-check if there is a valid content
|
||||
// (in some cases, ajax response can contain various elements or plain text)
|
||||
if (!slide.$content.length) {
|
||||
slide.$content = slide.$slide
|
||||
.wrapInner("<div></div>")
|
||||
.children()
|
||||
.first();
|
||||
}
|
||||
|
||||
slide.$content.addClass("fancybox-content");
|
||||
|
||||
slide.$slide.addClass("fancybox-slide--" + slide.contentType);
|
||||
|
||||
self.afterLoad(slide);
|
||||
},
|
||||
|
||||
// Display error message
|
||||
// =====================
|
||||
|
||||
setError: function (slide) {
|
||||
slide.hasError = true;
|
||||
|
||||
slide.$slide
|
||||
.trigger("onReset")
|
||||
.removeClass("fancybox-slide--" + slide.contentType)
|
||||
.addClass("fancybox-slide--error");
|
||||
|
||||
slide.contentType = "html";
|
||||
|
||||
this.setContent(slide, this.translate(slide, slide.opts.errorTpl));
|
||||
|
||||
if (slide.pos === this.currPos) {
|
||||
this.isAnimating = false;
|
||||
}
|
||||
},
|
||||
|
||||
// Show loading icon inside the slide
|
||||
// ==================================
|
||||
|
||||
showLoading: function (slide) {
|
||||
var self = this;
|
||||
|
||||
slide = slide || self.current;
|
||||
|
||||
if (slide && !slide.$spinner) {
|
||||
slide.$spinner = $(self.translate(self, self.opts.spinnerTpl))
|
||||
.appendTo(slide.$slide)
|
||||
.hide()
|
||||
.fadeIn("fast");
|
||||
}
|
||||
},
|
||||
|
||||
// Remove loading icon from the slide
|
||||
// ==================================
|
||||
|
||||
hideLoading: function (slide) {
|
||||
var self = this;
|
||||
|
||||
slide = slide || self.current;
|
||||
|
||||
if (slide && slide.$spinner) {
|
||||
slide.$spinner.stop().remove();
|
||||
|
||||
delete slide.$spinner;
|
||||
}
|
||||
},
|
||||
|
||||
// Adjustments after slide content has been loaded
|
||||
// ===============================================
|
||||
|
||||
afterLoad: function (slide) {
|
||||
var self = this;
|
||||
|
||||
if (self.isClosing) {
|
||||
return;
|
||||
}
|
||||
|
||||
slide.isLoading = false;
|
||||
slide.isLoaded = true;
|
||||
|
||||
self.trigger("afterLoad", slide);
|
||||
|
||||
self.hideLoading(slide);
|
||||
|
||||
// Add small close button
|
||||
if (slide.opts.smallBtn && (!slide.$smallBtn || !slide.$smallBtn.length)) {
|
||||
slide.$smallBtn = $(self.translate(slide, slide.opts.btnTpl.smallBtn)).appendTo(slide.$content);
|
||||
}
|
||||
|
||||
// Disable right click
|
||||
if (slide.opts.protect && slide.$content && !slide.hasError) {
|
||||
slide.$content.on("contextmenu.fb", function (e) {
|
||||
if (e.button == 2) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// Add fake element on top of the image
|
||||
// This makes a bit harder for user to select image
|
||||
if (slide.type === "image") {
|
||||
$('<div class="fancybox-spaceball"></div>').appendTo(slide.$content);
|
||||
}
|
||||
}
|
||||
|
||||
self.adjustCaption(slide);
|
||||
|
||||
self.adjustLayout(slide);
|
||||
|
||||
if (slide.pos === self.currPos) {
|
||||
self.updateCursor();
|
||||
}
|
||||
|
||||
self.revealContent(slide);
|
||||
},
|
||||
|
||||
// Prevent caption overlap,
|
||||
// fix css inconsistency across browsers
|
||||
// =====================================
|
||||
|
||||
adjustCaption: function (slide) {
|
||||
var self = this,
|
||||
current = slide || self.current,
|
||||
caption = current.opts.caption,
|
||||
preventOverlap = current.opts.preventCaptionOverlap,
|
||||
$caption = self.$refs.caption,
|
||||
$clone,
|
||||
captionH = false;
|
||||
|
||||
$caption.toggleClass("fancybox-caption--separate", preventOverlap);
|
||||
|
||||
if (preventOverlap && caption && caption.length) {
|
||||
if (current.pos !== self.currPos) {
|
||||
$clone = $caption.clone().appendTo($caption.parent());
|
||||
|
||||
$clone
|
||||
.children()
|
||||
.eq(0)
|
||||
.empty()
|
||||
.html(caption);
|
||||
|
||||
captionH = $clone.outerHeight(true);
|
||||
|
||||
$clone.empty().remove();
|
||||
} else if (self.$caption) {
|
||||
captionH = self.$caption.outerHeight(true);
|
||||
}
|
||||
|
||||
current.$slide.css("padding-bottom", captionH || "");
|
||||
}
|
||||
},
|
||||
|
||||
// Simple hack to fix inconsistency across browsers, described here (affects Edge, too):
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=748518
|
||||
// ====================================================================================
|
||||
|
||||
adjustLayout: function (slide) {
|
||||
var self = this,
|
||||
current = slide || self.current,
|
||||
scrollHeight,
|
||||
marginBottom,
|
||||
inlinePadding,
|
||||
actualPadding;
|
||||
|
||||
if (current.isLoaded && current.opts.disableLayoutFix !== true) {
|
||||
current.$content.css("margin-bottom", "");
|
||||
|
||||
// If we would always set margin-bottom for the content,
|
||||
// then it would potentially break vertical align
|
||||
if (current.$content.outerHeight() > current.$slide.height() + 0.5) {
|
||||
inlinePadding = current.$slide[0].style["padding-bottom"];
|
||||
actualPadding = current.$slide.css("padding-bottom");
|
||||
|
||||
if (parseFloat(actualPadding) > 0) {
|
||||
scrollHeight = current.$slide[0].scrollHeight;
|
||||
|
||||
current.$slide.css("padding-bottom", 0);
|
||||
|
||||
if (Math.abs(scrollHeight - current.$slide[0].scrollHeight) < 1) {
|
||||
marginBottom = actualPadding;
|
||||
}
|
||||
|
||||
current.$slide.css("padding-bottom", inlinePadding);
|
||||
}
|
||||
}
|
||||
|
||||
current.$content.css("margin-bottom", marginBottom);
|
||||
}
|
||||
},
|
||||
|
||||
// Make content visible
|
||||
// This method is called right after content has been loaded or
|
||||
// user navigates gallery and transition should start
|
||||
// ============================================================
|
||||
|
||||
revealContent: function (slide) {
|
||||
var self = this,
|
||||
$slide = slide.$slide,
|
||||
end = false,
|
||||
start = false,
|
||||
isMoved = self.isMoved(slide),
|
||||
isRevealed = slide.isRevealed,
|
||||
effect,
|
||||
effectClassName,
|
||||
duration,
|
||||
opacity;
|
||||
|
||||
slide.isRevealed = true;
|
||||
|
||||
effect = slide.opts[self.firstRun ? "animationEffect" : "transitionEffect"];
|
||||
duration = slide.opts[self.firstRun ? "animationDuration" : "transitionDuration"];
|
||||
|
||||
duration = parseInt(slide.forcedDuration === undefined ? duration : slide.forcedDuration, 10);
|
||||
|
||||
if (isMoved || slide.pos !== self.currPos || !duration) {
|
||||
effect = false;
|
||||
}
|
||||
|
||||
// Check if can zoom
|
||||
if (effect === "zoom") {
|
||||
if (slide.pos === self.currPos && duration && slide.type === "image" && !slide.hasError && (start = self.getThumbPos(slide))) {
|
||||
end = self.getFitPos(slide);
|
||||
} else {
|
||||
effect = "fade";
|
||||
}
|
||||
}
|
||||
|
||||
// Zoom animation
|
||||
// ==============
|
||||
if (effect === "zoom") {
|
||||
self.isAnimating = true;
|
||||
|
||||
end.scaleX = end.width / start.width;
|
||||
end.scaleY = end.height / start.height;
|
||||
|
||||
// Check if we need to animate opacity
|
||||
opacity = slide.opts.zoomOpacity;
|
||||
|
||||
if (opacity == "auto") {
|
||||
opacity = Math.abs(slide.width / slide.height - start.width / start.height) > 0.1;
|
||||
}
|
||||
|
||||
if (opacity) {
|
||||
start.opacity = 0.1;
|
||||
end.opacity = 1;
|
||||
}
|
||||
|
||||
// Draw image at start position
|
||||
$.fancybox.setTranslate(slide.$content.removeClass("fancybox-is-hidden"), start);
|
||||
|
||||
forceRedraw(slide.$content);
|
||||
|
||||
// Start animation
|
||||
$.fancybox.animate(slide.$content, end, duration, function () {
|
||||
self.isAnimating = false;
|
||||
|
||||
self.complete();
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self.updateSlide(slide);
|
||||
|
||||
// Simply show content if no effect
|
||||
// ================================
|
||||
if (!effect) {
|
||||
slide.$content.removeClass("fancybox-is-hidden");
|
||||
|
||||
if (!isRevealed && isMoved && slide.type === "image" && !slide.hasError) {
|
||||
slide.$content.hide().fadeIn("fast");
|
||||
}
|
||||
|
||||
if (slide.pos === self.currPos) {
|
||||
self.complete();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare for CSS transiton
|
||||
// =========================
|
||||
$.fancybox.stop($slide);
|
||||
|
||||
//effectClassName = "fancybox-animated fancybox-slide--" + (slide.pos >= self.prevPos ? "next" : "previous") + " fancybox-fx-" + effect;
|
||||
effectClassName = "fancybox-slide--" + (slide.pos >= self.prevPos ? "next" : "previous") + " fancybox-animated fancybox-fx-" + effect;
|
||||
|
||||
$slide.addClass(effectClassName).removeClass("fancybox-slide--current"); //.addClass(effectClassName);
|
||||
|
||||
slide.$content.removeClass("fancybox-is-hidden");
|
||||
|
||||
// Force reflow
|
||||
forceRedraw($slide);
|
||||
|
||||
if (slide.type !== "image") {
|
||||
slide.$content.hide().show(0);
|
||||
}
|
||||
|
||||
$.fancybox.animate(
|
||||
$slide,
|
||||
"fancybox-slide--current",
|
||||
duration,
|
||||
function () {
|
||||
$slide.removeClass(effectClassName).css({
|
||||
transform: "",
|
||||
opacity: ""
|
||||
});
|
||||
|
||||
if (slide.pos === self.currPos) {
|
||||
self.complete();
|
||||
}
|
||||
},
|
||||
true
|
||||
);
|
||||
},
|
||||
|
||||
// Check if we can and have to zoom from thumbnail
|
||||
//================================================
|
||||
|
||||
getThumbPos: function (slide) {
|
||||
var rez = false,
|
||||
$thumb = slide.$thumb,
|
||||
thumbPos,
|
||||
btw,
|
||||
brw,
|
||||
bbw,
|
||||
blw;
|
||||
|
||||
if (!$thumb || !inViewport($thumb[0])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
thumbPos = $.fancybox.getTranslate($thumb);
|
||||
|
||||
btw = parseFloat($thumb.css("border-top-width") || 0);
|
||||
brw = parseFloat($thumb.css("border-right-width") || 0);
|
||||
bbw = parseFloat($thumb.css("border-bottom-width") || 0);
|
||||
blw = parseFloat($thumb.css("border-left-width") || 0);
|
||||
|
||||
rez = {
|
||||
top: thumbPos.top + btw,
|
||||
left: thumbPos.left + blw,
|
||||
width: thumbPos.width - brw - blw,
|
||||
height: thumbPos.height - btw - bbw,
|
||||
scaleX: 1,
|
||||
scaleY: 1
|
||||
};
|
||||
|
||||
return thumbPos.width > 0 && thumbPos.height > 0 ? rez : false;
|
||||
},
|
||||
|
||||
// Final adjustments after current gallery item is moved to position
|
||||
// and it`s content is loaded
|
||||
// ==================================================================
|
||||
|
||||
complete: function () {
|
||||
var self = this,
|
||||
current = self.current,
|
||||
slides = {},
|
||||
$el;
|
||||
|
||||
if (self.isMoved() || !current.isLoaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!current.isComplete) {
|
||||
current.isComplete = true;
|
||||
|
||||
current.$slide.siblings().trigger("onReset");
|
||||
|
||||
self.preload("inline");
|
||||
|
||||
// Trigger any CSS transiton inside the slide
|
||||
forceRedraw(current.$slide);
|
||||
|
||||
current.$slide.addClass("fancybox-slide--complete");
|
||||
|
||||
// Remove unnecessary slides
|
||||
$.each(self.slides, function (key, slide) {
|
||||
if (slide.pos >= self.currPos - 1 && slide.pos <= self.currPos + 1) {
|
||||
slides[slide.pos] = slide;
|
||||
} else if (slide) {
|
||||
$.fancybox.stop(slide.$slide);
|
||||
|
||||
slide.$slide.off().remove();
|
||||
}
|
||||
});
|
||||
|
||||
self.slides = slides;
|
||||
}
|
||||
|
||||
self.isAnimating = false;
|
||||
|
||||
self.updateCursor();
|
||||
|
||||
self.trigger("afterShow");
|
||||
|
||||
// Autoplay first html5 video/audio
|
||||
if (!!current.opts.video.autoStart) {
|
||||
current.$slide
|
||||
.find("video,audio")
|
||||
.filter(":visible:first")
|
||||
.trigger("play")
|
||||
.one("ended", function () {
|
||||
if (Document.exitFullscreen) {
|
||||
Document.exitFullscreen();
|
||||
} else if (this.webkitExitFullscreen) {
|
||||
this.webkitExitFullscreen();
|
||||
}
|
||||
|
||||
self.next();
|
||||
});
|
||||
}
|
||||
|
||||
// Try to focus on the first focusable element
|
||||
if (current.opts.autoFocus && current.contentType === "html") {
|
||||
// Look for the first input with autofocus attribute
|
||||
$el = current.$content.find("input[autofocus]:enabled:visible:first");
|
||||
|
||||
if ($el.length) {
|
||||
$el.trigger("focus");
|
||||
} else {
|
||||
self.focus(null, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Avoid jumping
|
||||
current.$slide.scrollTop(0).scrollLeft(0);
|
||||
},
|
||||
|
||||
// Preload next and previous slides
|
||||
// ================================
|
||||
|
||||
preload: function (type) {
|
||||
var self = this,
|
||||
prev,
|
||||
next;
|
||||
|
||||
if (self.group.length < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
next = self.slides[self.currPos + 1];
|
||||
prev = self.slides[self.currPos - 1];
|
||||
|
||||
if (prev && prev.type === type) {
|
||||
self.loadSlide(prev);
|
||||
}
|
||||
|
||||
if (next && next.type === type) {
|
||||
self.loadSlide(next);
|
||||
}
|
||||
},
|
||||
|
||||
// Try to find and focus on the first focusable element
|
||||
// ====================================================
|
||||
|
||||
focus: function (e, firstRun) {
|
||||
var self = this,
|
||||
focusableStr = [
|
||||
"a[href]",
|
||||
"area[href]",
|
||||
'input:not([disabled]):not([type="hidden"]):not([aria-hidden])',
|
||||
"select:not([disabled]):not([aria-hidden])",
|
||||
"textarea:not([disabled]):not([aria-hidden])",
|
||||
"button:not([disabled]):not([aria-hidden])",
|
||||
"iframe",
|
||||
"object",
|
||||
"embed",
|
||||
"video",
|
||||
"audio",
|
||||
"[contenteditable]",
|
||||
'[tabindex]:not([tabindex^="-"])'
|
||||
].join(","),
|
||||
focusableItems,
|
||||
focusedItemIndex;
|
||||
|
||||
if (self.isClosing) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (e || !self.current || !self.current.isComplete) {
|
||||
// Focus on any element inside fancybox
|
||||
focusableItems = self.$refs.container.find("*:visible");
|
||||
} else {
|
||||
// Focus inside current slide
|
||||
focusableItems = self.current.$slide.find("*:visible" + (firstRun ? ":not(.fancybox-close-small)" : ""));
|
||||
}
|
||||
|
||||
focusableItems = focusableItems.filter(focusableStr).filter(function () {
|
||||
return $(this).css("visibility") !== "hidden" && !$(this).hasClass("disabled");
|
||||
});
|
||||
|
||||
if (focusableItems.length) {
|
||||
focusedItemIndex = focusableItems.index(document.activeElement);
|
||||
|
||||
if (e && e.shiftKey) {
|
||||
// Back tab
|
||||
if (focusedItemIndex < 0 || focusedItemIndex == 0) {
|
||||
e.preventDefault();
|
||||
|
||||
focusableItems.eq(focusableItems.length - 1).trigger("focus");
|
||||
}
|
||||
} else {
|
||||
// Outside or Forward tab
|
||||
if (focusedItemIndex < 0 || focusedItemIndex == focusableItems.length - 1) {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
focusableItems.eq(0).trigger("focus");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.$refs.container.trigger("focus");
|
||||
}
|
||||
},
|
||||
|
||||
// Activates current instance - brings container to the front and enables keyboard,
|
||||
// notifies other instances about deactivating
|
||||
// =================================================================================
|
||||
|
||||
activate: function () {
|
||||
var self = this;
|
||||
|
||||
// Deactivate all instances
|
||||
$(".fancybox-container").each(function () {
|
||||
var instance = $(this).data("FancyBox");
|
||||
|
||||
// Skip self and closing instances
|
||||
if (instance && instance.id !== self.id && !instance.isClosing) {
|
||||
instance.trigger("onDeactivate");
|
||||
|
||||
instance.removeEvents();
|
||||
|
||||
instance.isVisible = false;
|
||||
}
|
||||
});
|
||||
|
||||
self.isVisible = true;
|
||||
|
||||
if (self.current || self.isIdle) {
|
||||
self.update();
|
||||
|
||||
self.updateControls();
|
||||
}
|
||||
|
||||
self.trigger("onActivate");
|
||||
|
||||
self.addEvents();
|
||||
},
|
||||
|
||||
// Start closing procedure
|
||||
// This will start "zoom-out" animation if needed and clean everything up afterwards
|
||||
// =================================================================================
|
||||
|
||||
close: function (e, d) {
|
||||
var self = this,
|
||||
current = self.current,
|
||||
effect,
|
||||
duration,
|
||||
$content,
|
||||
domRect,
|
||||
opacity,
|
||||
start,
|
||||
end;
|
||||
|
||||
var done = function () {
|
||||
self.cleanUp(e);
|
||||
};
|
||||
|
||||
if (self.isClosing) {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.isClosing = true;
|
||||
|
||||
// If beforeClose callback prevents closing, make sure content is centered
|
||||
if (self.trigger("beforeClose", e) === false) {
|
||||
self.isClosing = false;
|
||||
|
||||
requestAFrame(function () {
|
||||
self.update();
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove all events
|
||||
// If there are multiple instances, they will be set again by "activate" method
|
||||
self.removeEvents();
|
||||
|
||||
$content = current.$content;
|
||||
effect = current.opts.animationEffect;
|
||||
duration = $.isNumeric(d) ? d : effect ? current.opts.animationDuration : 0;
|
||||
|
||||
current.$slide.removeClass("fancybox-slide--complete fancybox-slide--next fancybox-slide--previous fancybox-animated");
|
||||
|
||||
if (e !== true) {
|
||||
$.fancybox.stop(current.$slide);
|
||||
} else {
|
||||
effect = false;
|
||||
}
|
||||
|
||||
// Remove other slides
|
||||
current.$slide
|
||||
.siblings()
|
||||
.trigger("onReset")
|
||||
.remove();
|
||||
|
||||
// Trigger animations
|
||||
if (duration) {
|
||||
self.$refs.container
|
||||
.removeClass("fancybox-is-open")
|
||||
.addClass("fancybox-is-closing")
|
||||
.css("transition-duration", duration + "ms");
|
||||
}
|
||||
|
||||
// Clean up
|
||||
self.hideLoading(current);
|
||||
|
||||
self.hideControls(true);
|
||||
|
||||
self.updateCursor();
|
||||
|
||||
// Check if possible to zoom-out
|
||||
if (
|
||||
effect === "zoom" &&
|
||||
!($content && duration && current.type === "image" && !self.isMoved() && !current.hasError && (end = self.getThumbPos(current)))
|
||||
) {
|
||||
effect = "fade";
|
||||
}
|
||||
|
||||
if (effect === "zoom") {
|
||||
$.fancybox.stop($content);
|
||||
|
||||
domRect = $.fancybox.getTranslate($content);
|
||||
|
||||
start = {
|
||||
top: domRect.top,
|
||||
left: domRect.left,
|
||||
scaleX: domRect.width / end.width,
|
||||
scaleY: domRect.height / end.height,
|
||||
width: end.width,
|
||||
height: end.height
|
||||
};
|
||||
|
||||
// Check if we need to animate opacity
|
||||
opacity = current.opts.zoomOpacity;
|
||||
|
||||
if (opacity == "auto") {
|
||||
opacity = Math.abs(current.width / current.height - end.width / end.height) > 0.1;
|
||||
}
|
||||
|
||||
if (opacity) {
|
||||
end.opacity = 0;
|
||||
}
|
||||
|
||||
$.fancybox.setTranslate($content, start);
|
||||
|
||||
forceRedraw($content);
|
||||
|
||||
$.fancybox.animate($content, end, duration, done);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (effect && duration) {
|
||||
$.fancybox.animate(
|
||||
current.$slide.addClass("fancybox-slide--previous").removeClass("fancybox-slide--current"),
|
||||
"fancybox-animated fancybox-fx-" + effect,
|
||||
duration,
|
||||
done
|
||||
);
|
||||
} else {
|
||||
// If skip animation
|
||||
if (e === true) {
|
||||
setTimeout(done, duration);
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
// Final adjustments after removing the instance
|
||||
// =============================================
|
||||
|
||||
cleanUp: function (e) {
|
||||
var self = this,
|
||||
instance,
|
||||
$focus = self.current.opts.$orig,
|
||||
x,
|
||||
y;
|
||||
|
||||
self.current.$slide.trigger("onReset");
|
||||
|
||||
self.$refs.container.empty().remove();
|
||||
|
||||
self.trigger("afterClose", e);
|
||||
|
||||
// Place back focus
|
||||
if (!!self.current.opts.backFocus) {
|
||||
if (!$focus || !$focus.length || !$focus.is(":visible")) {
|
||||
$focus = self.$trigger;
|
||||
}
|
||||
|
||||
if ($focus && $focus.length) {
|
||||
x = window.scrollX;
|
||||
y = window.scrollY;
|
||||
|
||||
$focus.trigger("focus");
|
||||
|
||||
$("html, body")
|
||||
.scrollTop(y)
|
||||
.scrollLeft(x);
|
||||
}
|
||||
}
|
||||
|
||||
self.current = null;
|
||||
|
||||
// Check if there are other instances
|
||||
instance = $.fancybox.getInstance();
|
||||
|
||||
if (instance) {
|
||||
instance.activate();
|
||||
} else {
|
||||
$("body").removeClass("fancybox-active compensate-for-scrollbar");
|
||||
|
||||
$("#fancybox-style-noscroll").remove();
|
||||
}
|
||||
},
|
||||
|
||||
// Call callback and trigger an event
|
||||
// ==================================
|
||||
|
||||
trigger: function (name, slide) {
|
||||
var args = Array.prototype.slice.call(arguments, 1),
|
||||
self = this,
|
||||
obj = slide && slide.opts ? slide : self.current,
|
||||
rez;
|
||||
|
||||
if (obj) {
|
||||
args.unshift(obj);
|
||||
} else {
|
||||
obj = self;
|
||||
}
|
||||
|
||||
args.unshift(self);
|
||||
|
||||
if ($.isFunction(obj.opts[name])) {
|
||||
rez = obj.opts[name].apply(obj, args);
|
||||
}
|
||||
|
||||
if (rez === false) {
|
||||
return rez;
|
||||
}
|
||||
|
||||
if (name === "afterClose" || !self.$refs) {
|
||||
$D.trigger(name + ".fb", args);
|
||||
} else {
|
||||
self.$refs.container.trigger(name + ".fb", args);
|
||||
}
|
||||
},
|
||||
|
||||
// Update infobar values, navigation button states and reveal caption
|
||||
// ==================================================================
|
||||
|
||||
updateControls: function () {
|
||||
var self = this,
|
||||
current = self.current,
|
||||
index = current.index,
|
||||
$container = self.$refs.container,
|
||||
$caption = self.$refs.caption,
|
||||
caption = current.opts.caption;
|
||||
|
||||
// Recalculate content dimensions
|
||||
current.$slide.trigger("refresh");
|
||||
|
||||
// Set caption
|
||||
if (caption && caption.length) {
|
||||
self.$caption = $caption;
|
||||
|
||||
$caption
|
||||
.children()
|
||||
.eq(0)
|
||||
.html(caption);
|
||||
} else {
|
||||
self.$caption = null;
|
||||
}
|
||||
|
||||
if (!self.hasHiddenControls && !self.isIdle) {
|
||||
self.showControls();
|
||||
}
|
||||
|
||||
// Update info and navigation elements
|
||||
$container.find("[data-fancybox-count]").html(self.group.length);
|
||||
$container.find("[data-fancybox-index]").html(index + 1);
|
||||
|
||||
$container.find("[data-fancybox-prev]").prop("disabled", !current.opts.loop && index <= 0);
|
||||
$container.find("[data-fancybox-next]").prop("disabled", !current.opts.loop && index >= self.group.length - 1);
|
||||
|
||||
if (current.type === "image") {
|
||||
// Re-enable buttons; update download button source
|
||||
$container
|
||||
.find("[data-fancybox-zoom]")
|
||||
.show()
|
||||
.end()
|
||||
.find("[data-fancybox-download]")
|
||||
.attr("href", current.opts.image.src || current.src)
|
||||
.show();
|
||||
} else if (current.opts.toolbar) {
|
||||
$container.find("[data-fancybox-download],[data-fancybox-zoom]").hide();
|
||||
}
|
||||
|
||||
// Make sure focus is not on disabled button/element
|
||||
if ($(document.activeElement).is(":hidden,[disabled]")) {
|
||||
self.$refs.container.trigger("focus");
|
||||
}
|
||||
},
|
||||
|
||||
// Hide toolbar and caption
|
||||
// ========================
|
||||
|
||||
hideControls: function (andCaption) {
|
||||
var self = this,
|
||||
arr = ["infobar", "toolbar", "nav"];
|
||||
|
||||
if (andCaption || !self.current.opts.preventCaptionOverlap) {
|
||||
arr.push("caption");
|
||||
}
|
||||
|
||||
this.$refs.container.removeClass(
|
||||
arr
|
||||
.map(function (i) {
|
||||
return "fancybox-show-" + i;
|
||||
})
|
||||
.join(" ")
|
||||
);
|
||||
|
||||
this.hasHiddenControls = true;
|
||||
},
|
||||
|
||||
showControls: function () {
|
||||
var self = this,
|
||||
opts = self.current ? self.current.opts : self.opts,
|
||||
$container = self.$refs.container;
|
||||
|
||||
self.hasHiddenControls = false;
|
||||
self.idleSecondsCounter = 0;
|
||||
|
||||
$container
|
||||
.toggleClass("fancybox-show-toolbar", !!(opts.toolbar && opts.buttons))
|
||||
.toggleClass("fancybox-show-infobar", !!(opts.infobar && self.group.length > 1))
|
||||
.toggleClass("fancybox-show-caption", !!self.$caption)
|
||||
.toggleClass("fancybox-show-nav", !!(opts.arrows && self.group.length > 1))
|
||||
.toggleClass("fancybox-is-modal", !!opts.modal);
|
||||
},
|
||||
|
||||
// Toggle toolbar and caption
|
||||
// ==========================
|
||||
|
||||
toggleControls: function () {
|
||||
if (this.hasHiddenControls) {
|
||||
this.showControls();
|
||||
} else {
|
||||
this.hideControls();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fancybox = {
|
||||
version: "3.5.7",
|
||||
defaults: defaults,
|
||||
|
||||
// Get current instance and execute a command.
|
||||
//
|
||||
// Examples of usage:
|
||||
//
|
||||
// $instance = $.fancybox.getInstance();
|
||||
// $.fancybox.getInstance().jumpTo( 1 );
|
||||
// $.fancybox.getInstance( 'jumpTo', 1 );
|
||||
// $.fancybox.getInstance( function() {
|
||||
// console.info( this.currIndex );
|
||||
// });
|
||||
// ======================================================
|
||||
|
||||
getInstance: function (command) {
|
||||
var instance = $('.fancybox-container:not(".fancybox-is-closing"):last').data("FancyBox"),
|
||||
args = Array.prototype.slice.call(arguments, 1);
|
||||
|
||||
if (instance instanceof FancyBox) {
|
||||
if ($.type(command) === "string") {
|
||||
instance[command].apply(instance, args);
|
||||
} else if ($.type(command) === "function") {
|
||||
command.apply(instance, args);
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
// Create new instance
|
||||
// ===================
|
||||
|
||||
open: function (items, opts, index) {
|
||||
return new FancyBox(items, opts, index);
|
||||
},
|
||||
|
||||
// Close current or all instances
|
||||
// ==============================
|
||||
|
||||
close: function (all) {
|
||||
var instance = this.getInstance();
|
||||
|
||||
if (instance) {
|
||||
instance.close();
|
||||
|
||||
// Try to find and close next instance
|
||||
if (all === true) {
|
||||
this.close(all);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Close all instances and unbind all events
|
||||
// =========================================
|
||||
|
||||
destroy: function () {
|
||||
this.close(true);
|
||||
|
||||
$D.add("body").off("click.fb-start", "**");
|
||||
},
|
||||
|
||||
// Try to detect mobile devices
|
||||
// ============================
|
||||
|
||||
isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),
|
||||
|
||||
// Detect if 'translate3d' support is available
|
||||
// ============================================
|
||||
|
||||
use3d: (function () {
|
||||
var div = document.createElement("div");
|
||||
|
||||
return (
|
||||
window.getComputedStyle &&
|
||||
window.getComputedStyle(div) &&
|
||||
window.getComputedStyle(div).getPropertyValue("transform") &&
|
||||
!(document.documentMode && document.documentMode < 11)
|
||||
);
|
||||
})(),
|
||||
|
||||
// Helper function to get current visual state of an element
|
||||
// returns array[ top, left, horizontal-scale, vertical-scale, opacity ]
|
||||
// =====================================================================
|
||||
|
||||
getTranslate: function ($el) {
|
||||
var domRect;
|
||||
|
||||
if (!$el || !$el.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
domRect = $el[0].getBoundingClientRect();
|
||||
|
||||
return {
|
||||
top: domRect.top || 0,
|
||||
left: domRect.left || 0,
|
||||
width: domRect.width,
|
||||
height: domRect.height,
|
||||
opacity: parseFloat($el.css("opacity"))
|
||||
};
|
||||
},
|
||||
|
||||
// Shortcut for setting "translate3d" properties for element
|
||||
// Can set be used to set opacity, too
|
||||
// ========================================================
|
||||
|
||||
setTranslate: function ($el, props) {
|
||||
var str = "",
|
||||
css = {};
|
||||
|
||||
if (!$el || !props) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (props.left !== undefined || props.top !== undefined) {
|
||||
str =
|
||||
(props.left === undefined ? $el.position().left : props.left) +
|
||||
"px, " +
|
||||
(props.top === undefined ? $el.position().top : props.top) +
|
||||
"px";
|
||||
|
||||
if (this.use3d) {
|
||||
str = "translate3d(" + str + ", 0px)";
|
||||
} else {
|
||||
str = "translate(" + str + ")";
|
||||
}
|
||||
}
|
||||
|
||||
if (props.scaleX !== undefined && props.scaleY !== undefined) {
|
||||
str += " scale(" + props.scaleX + ", " + props.scaleY + ")";
|
||||
} else if (props.scaleX !== undefined) {
|
||||
str += " scaleX(" + props.scaleX + ")";
|
||||
}
|
||||
|
||||
if (str.length) {
|
||||
css.transform = str;
|
||||
}
|
||||
|
||||
if (props.opacity !== undefined) {
|
||||
css.opacity = props.opacity;
|
||||
}
|
||||
|
||||
if (props.width !== undefined) {
|
||||
css.width = props.width;
|
||||
}
|
||||
|
||||
if (props.height !== undefined) {
|
||||
css.height = props.height;
|
||||
}
|
||||
|
||||
return $el.css(css);
|
||||
},
|
||||
|
||||
// Simple CSS transition handler
|
||||
// =============================
|
||||
|
||||
animate: function ($el, to, duration, callback, leaveAnimationName) {
|
||||
var self = this,
|
||||
from;
|
||||
|
||||
if ($.isFunction(duration)) {
|
||||
callback = duration;
|
||||
duration = null;
|
||||
}
|
||||
|
||||
self.stop($el);
|
||||
|
||||
from = self.getTranslate($el);
|
||||
|
||||
$el.on(transitionEnd, function (e) {
|
||||
// Skip events from child elements and z-index change
|
||||
if (e && e.originalEvent && (!$el.is(e.originalEvent.target) || e.originalEvent.propertyName == "z-index")) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.stop($el);
|
||||
|
||||
if ($.isNumeric(duration)) {
|
||||
$el.css("transition-duration", "");
|
||||
}
|
||||
|
||||
if ($.isPlainObject(to)) {
|
||||
if (to.scaleX !== undefined && to.scaleY !== undefined) {
|
||||
self.setTranslate($el, {
|
||||
top: to.top,
|
||||
left: to.left,
|
||||
width: from.width * to.scaleX,
|
||||
height: from.height * to.scaleY,
|
||||
scaleX: 1,
|
||||
scaleY: 1
|
||||
});
|
||||
}
|
||||
} else if (leaveAnimationName !== true) {
|
||||
$el.removeClass(to);
|
||||
}
|
||||
|
||||
if ($.isFunction(callback)) {
|
||||
callback(e);
|
||||
}
|
||||
});
|
||||
|
||||
if ($.isNumeric(duration)) {
|
||||
$el.css("transition-duration", duration + "ms");
|
||||
}
|
||||
|
||||
// Start animation by changing CSS properties or class name
|
||||
if ($.isPlainObject(to)) {
|
||||
if (to.scaleX !== undefined && to.scaleY !== undefined) {
|
||||
delete to.width;
|
||||
delete to.height;
|
||||
|
||||
if ($el.parent().hasClass("fancybox-slide--image")) {
|
||||
$el.parent().addClass("fancybox-is-scaling");
|
||||
}
|
||||
}
|
||||
|
||||
$.fancybox.setTranslate($el, to);
|
||||
} else {
|
||||
$el.addClass(to);
|
||||
}
|
||||
|
||||
// Make sure that `transitionend` callback gets fired
|
||||
$el.data(
|
||||
"timer",
|
||||
setTimeout(function () {
|
||||
$el.trigger(transitionEnd);
|
||||
}, duration + 33)
|
||||
);
|
||||
},
|
||||
|
||||
stop: function ($el, callCallback) {
|
||||
if ($el && $el.length) {
|
||||
clearTimeout($el.data("timer"));
|
||||
|
||||
if (callCallback) {
|
||||
$el.trigger(transitionEnd);
|
||||
}
|
||||
|
||||
$el.off(transitionEnd).css("transition-duration", "");
|
||||
|
||||
$el.parent().removeClass("fancybox-is-scaling");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Default click handler for "fancyboxed" links
|
||||
// ============================================
|
||||
|
||||
function _run(e, opts) {
|
||||
var items = [],
|
||||
index = 0,
|
||||
$target,
|
||||
value,
|
||||
instance;
|
||||
|
||||
// Avoid opening multiple times
|
||||
if (e && e.isDefaultPrevented()) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
opts = opts || {};
|
||||
|
||||
if (e && e.data) {
|
||||
opts = mergeOpts(e.data.options, opts);
|
||||
}
|
||||
|
||||
$target = opts.$target || $(e.currentTarget).trigger("blur");
|
||||
instance = $.fancybox.getInstance();
|
||||
|
||||
if (instance && instance.$trigger && instance.$trigger.is($target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (opts.selector) {
|
||||
items = $(opts.selector);
|
||||
} else {
|
||||
// Get all related items and find index for clicked one
|
||||
value = $target.attr("data-fancybox") || "";
|
||||
|
||||
if (value) {
|
||||
items = e.data ? e.data.items : [];
|
||||
items = items.length ? items.filter('[data-fancybox="' + value + '"]') : $('[data-fancybox="' + value + '"]');
|
||||
} else {
|
||||
items = [$target];
|
||||
}
|
||||
}
|
||||
|
||||
index = $(items).index($target);
|
||||
|
||||
// Sometimes current item can not be found
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
}
|
||||
|
||||
instance = $.fancybox.open(items, opts, index);
|
||||
|
||||
// Save last active element
|
||||
instance.$trigger = $target;
|
||||
}
|
||||
|
||||
// Create a jQuery plugin
|
||||
// ======================
|
||||
|
||||
$.fn.fancybox = function (options) {
|
||||
var selector;
|
||||
|
||||
options = options || {};
|
||||
selector = options.selector || false;
|
||||
|
||||
if (selector) {
|
||||
// Use body element instead of document so it executes first
|
||||
$("body")
|
||||
.off("click.fb-start", selector)
|
||||
.on("click.fb-start", selector, {
|
||||
options: options
|
||||
}, _run);
|
||||
} else {
|
||||
this.off("click.fb-start").on(
|
||||
"click.fb-start", {
|
||||
items: this,
|
||||
options: options
|
||||
},
|
||||
_run
|
||||
);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// Self initializing plugin for all elements having `data-fancybox` attribute
|
||||
// ==========================================================================
|
||||
|
||||
$D.on("click.fb-start", "[data-fancybox]", _run);
|
||||
|
||||
// Enable "trigger elements"
|
||||
// =========================
|
||||
|
||||
$D.on("click.fb-start", "[data-fancybox-trigger]", function (e) {
|
||||
$('[data-fancybox="' + $(this).attr("data-fancybox-trigger") + '"]')
|
||||
.eq($(this).attr("data-fancybox-index") || 0)
|
||||
.trigger("click.fb-start", {
|
||||
$trigger: $(this)
|
||||
});
|
||||
});
|
||||
|
||||
// Track focus event for better accessibility styling
|
||||
// ==================================================
|
||||
(function () {
|
||||
var buttonStr = ".fancybox-button",
|
||||
focusStr = "fancybox-focus",
|
||||
$pressed = null;
|
||||
|
||||
$D.on("mousedown mouseup focus blur", buttonStr, function (e) {
|
||||
switch (e.type) {
|
||||
case "mousedown":
|
||||
$pressed = $(this);
|
||||
break;
|
||||
case "mouseup":
|
||||
$pressed = null;
|
||||
break;
|
||||
case "focusin":
|
||||
$(buttonStr).removeClass(focusStr);
|
||||
|
||||
if (!$(this).is($pressed) && !$(this).is("[disabled]")) {
|
||||
$(this).addClass(focusStr);
|
||||
}
|
||||
break;
|
||||
case "focusout":
|
||||
$(buttonStr).removeClass(focusStr);
|
||||
break;
|
||||
}
|
||||
});
|
||||
})();
|
||||
})(window, document, jQuery);
|
||||
// ==========================================================================
|
||||
//
|
||||
// Media
|
||||
// Adds additional media type support
|
||||
//
|
||||
// ==========================================================================
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
// Object containing properties for each media type
|
||||
var defaults = {
|
||||
youtube: {
|
||||
matcher: /(youtube\.com|youtu\.be|youtube\-nocookie\.com)\/(watch\?(.*&)?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*))(.*)/i,
|
||||
params: {
|
||||
autoplay: 1,
|
||||
autohide: 1,
|
||||
fs: 1,
|
||||
rel: 0,
|
||||
hd: 1,
|
||||
wmode: "transparent",
|
||||
enablejsapi: 1,
|
||||
html5: 1
|
||||
},
|
||||
paramPlace: 8,
|
||||
type: "iframe",
|
||||
url: "https://www.youtube-nocookie.com/embed/$4",
|
||||
thumb: "https://img.youtube.com/vi/$4/hqdefault.jpg"
|
||||
},
|
||||
|
||||
vimeo: {
|
||||
matcher: /^.+vimeo.com\/(.*\/)?([\d]+)(.*)?/,
|
||||
params: {
|
||||
autoplay: 1,
|
||||
hd: 1,
|
||||
show_title: 1,
|
||||
show_byline: 1,
|
||||
show_portrait: 0,
|
||||
fullscreen: 1
|
||||
},
|
||||
paramPlace: 3,
|
||||
type: "iframe",
|
||||
url: "//player.vimeo.com/video/$2"
|
||||
},
|
||||
|
||||
instagram: {
|
||||
matcher: /(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i,
|
||||
type: "image",
|
||||
url: "//$1/p/$2/media/?size=l"
|
||||
},
|
||||
|
||||
// Examples:
|
||||
// http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16
|
||||
// https://www.google.com/maps/@37.7852006,-122.4146355,14.65z
|
||||
// https://www.google.com/maps/@52.2111123,2.9237542,6.61z?hl=en
|
||||
// https://www.google.com/maps/place/Googleplex/@37.4220041,-122.0833494,17z/data=!4m5!3m4!1s0x0:0x6c296c66619367e0!8m2!3d37.4219998!4d-122.0840572
|
||||
gmap_place: {
|
||||
matcher: /(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(((maps\/(place\/(.*)\/)?\@(.*),(\d+.?\d+?)z))|(\?ll=))(.*)?/i,
|
||||
type: "iframe",
|
||||
url: function (rez) {
|
||||
return (
|
||||
"//maps.google." +
|
||||
rez[2] +
|
||||
"/?ll=" +
|
||||
(rez[9] ? rez[9] + "&z=" + Math.floor(rez[10]) + (rez[12] ? rez[12].replace(/^\//, "&") : "") : rez[12] + "").replace(/\?/, "&") +
|
||||
"&output=" +
|
||||
(rez[12] && rez[12].indexOf("layer=c") > 0 ? "svembed" : "embed")
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
// Examples:
|
||||
// https://www.google.com/maps/search/Empire+State+Building/
|
||||
// https://www.google.com/maps/search/?api=1&query=centurylink+field
|
||||
// https://www.google.com/maps/search/?api=1&query=47.5951518,-122.3316393
|
||||
gmap_search: {
|
||||
matcher: /(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(maps\/search\/)(.*)/i,
|
||||
type: "iframe",
|
||||
url: function (rez) {
|
||||
return "//maps.google." + rez[2] + "/maps?q=" + rez[5].replace("query=", "q=").replace("api=1", "") + "&output=embed";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Formats matching url to final form
|
||||
var format = function (url, rez, params) {
|
||||
if (!url) {
|
||||
return;
|
||||
}
|
||||
|
||||
params = params || "";
|
||||
|
||||
if ($.type(params) === "object") {
|
||||
params = $.param(params, true);
|
||||
}
|
||||
|
||||
$.each(rez, function (key, value) {
|
||||
url = url.replace("$" + key, value || "");
|
||||
});
|
||||
|
||||
if (params.length) {
|
||||
url += (url.indexOf("?") > 0 ? "&" : "?") + params;
|
||||
}
|
||||
|
||||
return url;
|
||||
};
|
||||
|
||||
$(document).on("objectNeedsType.fb", function (e, instance, item) {
|
||||
var url = item.src || "",
|
||||
type = false,
|
||||
media,
|
||||
thumb,
|
||||
rez,
|
||||
params,
|
||||
urlParams,
|
||||
paramObj,
|
||||
provider;
|
||||
|
||||
media = $.extend(true, {}, defaults, item.opts.media);
|
||||
|
||||
// Look for any matching media type
|
||||
$.each(media, function (providerName, providerOpts) {
|
||||
rez = url.match(providerOpts.matcher);
|
||||
|
||||
if (!rez) {
|
||||
return;
|
||||
}
|
||||
|
||||
type = providerOpts.type;
|
||||
provider = providerName;
|
||||
paramObj = {};
|
||||
|
||||
if (providerOpts.paramPlace && rez[providerOpts.paramPlace]) {
|
||||
urlParams = rez[providerOpts.paramPlace];
|
||||
|
||||
if (urlParams[0] == "?") {
|
||||
urlParams = urlParams.substring(1);
|
||||
}
|
||||
|
||||
urlParams = urlParams.split("&");
|
||||
|
||||
for (var m = 0; m < urlParams.length; ++m) {
|
||||
var p = urlParams[m].split("=", 2);
|
||||
|
||||
if (p.length == 2) {
|
||||
paramObj[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
params = $.extend(true, {}, providerOpts.params, item.opts[providerName], paramObj);
|
||||
|
||||
url =
|
||||
$.type(providerOpts.url) === "function" ? providerOpts.url.call(this, rez, params, item) : format(providerOpts.url, rez, params);
|
||||
|
||||
thumb =
|
||||
$.type(providerOpts.thumb) === "function" ? providerOpts.thumb.call(this, rez, params, item) : format(providerOpts.thumb, rez);
|
||||
|
||||
if (providerName === "youtube") {
|
||||
url = url.replace(/&t=((\d+)m)?(\d+)s/, function (match, p1, m, s) {
|
||||
return "&start=" + ((m ? parseInt(m, 10) * 60 : 0) + parseInt(s, 10));
|
||||
});
|
||||
} else if (providerName === "vimeo") {
|
||||
url = url.replace("&%23", "#");
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
// If it is found, then change content type and update the url
|
||||
|
||||
if (type) {
|
||||
if (!item.opts.thumb && !(item.opts.$thumb && item.opts.$thumb.length)) {
|
||||
item.opts.thumb = thumb;
|
||||
}
|
||||
|
||||
if (type === "iframe") {
|
||||
item.opts = $.extend(true, item.opts, {
|
||||
iframe: {
|
||||
preload: false,
|
||||
attr: {
|
||||
scrolling: "no"
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$.extend(item, {
|
||||
type: type,
|
||||
src: url,
|
||||
origSrc: item.src,
|
||||
contentSource: provider,
|
||||
contentType: type === "image" ? "image" : provider == "gmap_place" || provider == "gmap_search" ? "map" : "video"
|
||||
});
|
||||
} else if (url) {
|
||||
item.type = item.opts.defaultType;
|
||||
}
|
||||
});
|
||||
|
||||
// Load YouTube/Video API on request to detect when video finished playing
|
||||
var VideoAPILoader = {
|
||||
youtube: {
|
||||
src: "https://www.youtube.com/iframe_api",
|
||||
class: "YT",
|
||||
loading: false,
|
||||
loaded: false
|
||||
},
|
||||
|
||||
vimeo: {
|
||||
src: "https://player.vimeo.com/api/player.js",
|
||||
class: "Vimeo",
|
||||
loading: false,
|
||||
loaded: false
|
||||
},
|
||||
|
||||
load: function (vendor) {
|
||||
var _this = this,
|
||||
script;
|
||||
|
||||
if (this[vendor].loaded) {
|
||||
setTimeout(function () {
|
||||
_this.done(vendor);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (this[vendor].loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
this[vendor].loading = true;
|
||||
|
||||
script = document.createElement("script");
|
||||
script.type = "text/javascript";
|
||||
script.src = this[vendor].src;
|
||||
|
||||
if (vendor === "youtube") {
|
||||
window.onYouTubeIframeAPIReady = function () {
|
||||
_this[vendor].loaded = true;
|
||||
_this.done(vendor);
|
||||
};
|
||||
} else {
|
||||
script.onload = function () {
|
||||
_this[vendor].loaded = true;
|
||||
_this.done(vendor);
|
||||
};
|
||||
}
|
||||
|
||||
document.body.appendChild(script);
|
||||
},
|
||||
done: function (vendor) {
|
||||
var instance, $el, player;
|
||||
|
||||
if (vendor === "youtube") {
|
||||
delete window.onYouTubeIframeAPIReady;
|
||||
}
|
||||
|
||||
instance = $.fancybox.getInstance();
|
||||
|
||||
if (instance) {
|
||||
$el = instance.current.$content.find("iframe");
|
||||
|
||||
if (vendor === "youtube" && YT !== undefined && YT) {
|
||||
player = new YT.Player($el.attr("id"), {
|
||||
events: {
|
||||
onStateChange: function (e) {
|
||||
if (e.data == 0) {
|
||||
instance.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (vendor === "vimeo" && Vimeo !== undefined && Vimeo) {
|
||||
player = new Vimeo.Player($el);
|
||||
|
||||
player.on("ended", function () {
|
||||
instance.next();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on({
|
||||
"afterShow.fb": function (e, instance, current) {
|
||||
if (instance.group.length > 1 && (current.contentSource === "youtube" || current.contentSource === "vimeo")) {
|
||||
VideoAPILoader.load(current.contentSource);
|
||||
}
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
||||
// ==========================================================================
|
||||
//
|
||||
// Guestures
|
||||
// Adds touch guestures, handles click and tap events
|
||||
//
|
||||
// ==========================================================================
|
||||
(function (window, document, $) {
|
||||
"use strict";
|
||||
|
||||
var requestAFrame = (function () {
|
||||
return (
|
||||
window.requestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
window.oRequestAnimationFrame ||
|
||||
// if all else fails, use setTimeout
|
||||
function (callback) {
|
||||
return window.setTimeout(callback, 1000 / 60);
|
||||
}
|
||||
);
|
||||
})();
|
||||
|
||||
var cancelAFrame = (function () {
|
||||
return (
|
||||
window.cancelAnimationFrame ||
|
||||
window.webkitCancelAnimationFrame ||
|
||||
window.mozCancelAnimationFrame ||
|
||||
window.oCancelAnimationFrame ||
|
||||
function (id) {
|
||||
window.clearTimeout(id);
|
||||
}
|
||||
);
|
||||
})();
|
||||
|
||||
var getPointerXY = function (e) {
|
||||
var result = [];
|
||||
|
||||
e = e.originalEvent || e || window.e;
|
||||
e = e.touches && e.touches.length ? e.touches : e.changedTouches && e.changedTouches.length ? e.changedTouches : [e];
|
||||
|
||||
for (var key in e) {
|
||||
if (e[key].pageX) {
|
||||
result.push({
|
||||
x: e[key].pageX,
|
||||
y: e[key].pageY
|
||||
});
|
||||
} else if (e[key].clientX) {
|
||||
result.push({
|
||||
x: e[key].clientX,
|
||||
y: e[key].clientY
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
var distance = function (point2, point1, what) {
|
||||
if (!point1 || !point2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (what === "x") {
|
||||
return point2.x - point1.x;
|
||||
} else if (what === "y") {
|
||||
return point2.y - point1.y;
|
||||
}
|
||||
|
||||
return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2));
|
||||
};
|
||||
|
||||
var isClickable = function ($el) {
|
||||
if (
|
||||
$el.is('a,area,button,[role="button"],input,label,select,summary,textarea,video,audio,iframe') ||
|
||||
$.isFunction($el.get(0).onclick) ||
|
||||
$el.data("selectable")
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for attributes like data-fancybox-next or data-fancybox-close
|
||||
for (var i = 0, atts = $el[0].attributes, n = atts.length; i < n; i++) {
|
||||
if (atts[i].nodeName.substr(0, 14) === "data-fancybox-") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
var hasScrollbars = function (el) {
|
||||
var overflowY = window.getComputedStyle(el)["overflow-y"],
|
||||
overflowX = window.getComputedStyle(el)["overflow-x"],
|
||||
vertical = (overflowY === "scroll" || overflowY === "auto") && el.scrollHeight > el.clientHeight,
|
||||
horizontal = (overflowX === "scroll" || overflowX === "auto") && el.scrollWidth > el.clientWidth;
|
||||
|
||||
return vertical || horizontal;
|
||||
};
|
||||
|
||||
var isScrollable = function ($el) {
|
||||
var rez = false;
|
||||
|
||||
while (true) {
|
||||
rez = hasScrollbars($el.get(0));
|
||||
|
||||
if (rez) {
|
||||
break;
|
||||
}
|
||||
|
||||
$el = $el.parent();
|
||||
|
||||
if (!$el.length || $el.hasClass("fancybox-stage") || $el.is("body")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return rez;
|
||||
};
|
||||
|
||||
var Guestures = function (instance) {
|
||||
var self = this;
|
||||
|
||||
self.instance = instance;
|
||||
|
||||
self.$bg = instance.$refs.bg;
|
||||
self.$stage = instance.$refs.stage;
|
||||
self.$container = instance.$refs.container;
|
||||
|
||||
self.destroy();
|
||||
|
||||
self.$container.on("touchstart.fb.touch mousedown.fb.touch", $.proxy(self, "ontouchstart"));
|
||||
};
|
||||
|
||||
Guestures.prototype.destroy = function () {
|
||||
var self = this;
|
||||
|
||||
self.$container.off(".fb.touch");
|
||||
|
||||
$(document).off(".fb.touch");
|
||||
|
||||
if (self.requestId) {
|
||||
cancelAFrame(self.requestId);
|
||||
self.requestId = null;
|
||||
}
|
||||
|
||||
if (self.tapped) {
|
||||
clearTimeout(self.tapped);
|
||||
self.tapped = null;
|
||||
}
|
||||
};
|
||||
|
||||
Guestures.prototype.ontouchstart = function (e) {
|
||||
var self = this,
|
||||
$target = $(e.target),
|
||||
instance = self.instance,
|
||||
current = instance.current,
|
||||
$slide = current.$slide,
|
||||
$content = current.$content,
|
||||
isTouchDevice = e.type == "touchstart";
|
||||
|
||||
// Do not respond to both (touch and mouse) events
|
||||
if (isTouchDevice) {
|
||||
self.$container.off("mousedown.fb.touch");
|
||||
}
|
||||
|
||||
// Ignore right click
|
||||
if (e.originalEvent && e.originalEvent.button == 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore taping on links, buttons, input elements
|
||||
if (!$slide.length || !$target.length || isClickable($target) || isClickable($target.parent())) {
|
||||
return;
|
||||
}
|
||||
// Ignore clicks on the scrollbar
|
||||
if (!$target.is("img") && e.originalEvent.clientX > $target[0].clientWidth + $target.offset().left) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore clicks while zooming or closing
|
||||
if (!current || instance.isAnimating || current.$slide.hasClass("fancybox-animated")) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self.realPoints = self.startPoints = getPointerXY(e);
|
||||
|
||||
if (!self.startPoints.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Allow other scripts to catch touch event if "touch" is set to false
|
||||
if (current.touch) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
self.startEvent = e;
|
||||
|
||||
self.canTap = true;
|
||||
self.$target = $target;
|
||||
self.$content = $content;
|
||||
self.opts = current.opts.touch;
|
||||
|
||||
self.isPanning = false;
|
||||
self.isSwiping = false;
|
||||
self.isZooming = false;
|
||||
self.isScrolling = false;
|
||||
self.canPan = instance.canPan();
|
||||
|
||||
self.startTime = new Date().getTime();
|
||||
self.distanceX = self.distanceY = self.distance = 0;
|
||||
|
||||
self.canvasWidth = Math.round($slide[0].clientWidth);
|
||||
self.canvasHeight = Math.round($slide[0].clientHeight);
|
||||
|
||||
self.contentLastPos = null;
|
||||
self.contentStartPos = $.fancybox.getTranslate(self.$content) || {
|
||||
top: 0,
|
||||
left: 0
|
||||
};
|
||||
self.sliderStartPos = $.fancybox.getTranslate($slide);
|
||||
|
||||
// Since position will be absolute, but we need to make it relative to the stage
|
||||
self.stagePos = $.fancybox.getTranslate(instance.$refs.stage);
|
||||
|
||||
self.sliderStartPos.top -= self.stagePos.top;
|
||||
self.sliderStartPos.left -= self.stagePos.left;
|
||||
|
||||
self.contentStartPos.top -= self.stagePos.top;
|
||||
self.contentStartPos.left -= self.stagePos.left;
|
||||
|
||||
$(document)
|
||||
.off(".fb.touch")
|
||||
.on(isTouchDevice ? "touchend.fb.touch touchcancel.fb.touch" : "mouseup.fb.touch mouseleave.fb.touch", $.proxy(self, "ontouchend"))
|
||||
.on(isTouchDevice ? "touchmove.fb.touch" : "mousemove.fb.touch", $.proxy(self, "ontouchmove"));
|
||||
|
||||
if ($.fancybox.isMobile) {
|
||||
document.addEventListener("scroll", self.onscroll, true);
|
||||
}
|
||||
|
||||
// Skip if clicked outside the sliding area
|
||||
if (!(self.opts || self.canPan) || !($target.is(self.$stage) || self.$stage.find($target).length)) {
|
||||
if ($target.is(".fancybox-image")) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
if (!($.fancybox.isMobile && $target.parents(".fancybox-caption").length)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
self.isScrollable = isScrollable($target) || isScrollable($target.parent());
|
||||
|
||||
// Check if element is scrollable and try to prevent default behavior (scrolling)
|
||||
if (!($.fancybox.isMobile && self.isScrollable)) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
// One finger or mouse click - swipe or pan an image
|
||||
if (self.startPoints.length === 1 || current.hasError) {
|
||||
if (self.canPan) {
|
||||
$.fancybox.stop(self.$content);
|
||||
|
||||
self.isPanning = true;
|
||||
} else {
|
||||
self.isSwiping = true;
|
||||
}
|
||||
|
||||
self.$container.addClass("fancybox-is-grabbing");
|
||||
}
|
||||
|
||||
// Two fingers - zoom image
|
||||
if (self.startPoints.length === 2 && current.type === "image" && (current.isLoaded || current.$ghost)) {
|
||||
self.canTap = false;
|
||||
self.isSwiping = false;
|
||||
self.isPanning = false;
|
||||
|
||||
self.isZooming = true;
|
||||
|
||||
$.fancybox.stop(self.$content);
|
||||
|
||||
self.centerPointStartX = (self.startPoints[0].x + self.startPoints[1].x) * 0.5 - $(window).scrollLeft();
|
||||
self.centerPointStartY = (self.startPoints[0].y + self.startPoints[1].y) * 0.5 - $(window).scrollTop();
|
||||
|
||||
self.percentageOfImageAtPinchPointX = (self.centerPointStartX - self.contentStartPos.left) / self.contentStartPos.width;
|
||||
self.percentageOfImageAtPinchPointY = (self.centerPointStartY - self.contentStartPos.top) / self.contentStartPos.height;
|
||||
|
||||
self.startDistanceBetweenFingers = distance(self.startPoints[0], self.startPoints[1]);
|
||||
}
|
||||
};
|
||||
|
||||
Guestures.prototype.onscroll = function (e) {
|
||||
var self = this;
|
||||
|
||||
self.isScrolling = true;
|
||||
|
||||
document.removeEventListener("scroll", self.onscroll, true);
|
||||
};
|
||||
|
||||
Guestures.prototype.ontouchmove = function (e) {
|
||||
var self = this;
|
||||
|
||||
// Make sure user has not released over iframe or disabled element
|
||||
if (e.originalEvent.buttons !== undefined && e.originalEvent.buttons === 0) {
|
||||
self.ontouchend(e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.isScrolling) {
|
||||
self.canTap = false;
|
||||
return;
|
||||
}
|
||||
|
||||
self.newPoints = getPointerXY(e);
|
||||
|
||||
if (!(self.opts || self.canPan) || !self.newPoints.length || !self.newPoints.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(self.isSwiping && self.isSwiping === true)) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
self.distanceX = distance(self.newPoints[0], self.startPoints[0], "x");
|
||||
self.distanceY = distance(self.newPoints[0], self.startPoints[0], "y");
|
||||
|
||||
self.distance = distance(self.newPoints[0], self.startPoints[0]);
|
||||
|
||||
// Skip false ontouchmove events (Chrome)
|
||||
if (self.distance > 0) {
|
||||
if (self.isSwiping) {
|
||||
self.onSwipe(e);
|
||||
} else if (self.isPanning) {
|
||||
self.onPan();
|
||||
} else if (self.isZooming) {
|
||||
self.onZoom();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Guestures.prototype.onSwipe = function (e) {
|
||||
var self = this,
|
||||
instance = self.instance,
|
||||
swiping = self.isSwiping,
|
||||
left = self.sliderStartPos.left || 0,
|
||||
angle;
|
||||
|
||||
// If direction is not yet determined
|
||||
if (swiping === true) {
|
||||
// We need at least 10px distance to correctly calculate an angle
|
||||
if (Math.abs(self.distance) > 10) {
|
||||
self.canTap = false;
|
||||
|
||||
if (instance.group.length < 2 && self.opts.vertical) {
|
||||
self.isSwiping = "y";
|
||||
} else if (instance.isDragging || self.opts.vertical === false || (self.opts.vertical === "auto" && $(window).width() > 800)) {
|
||||
self.isSwiping = "x";
|
||||
} else {
|
||||
angle = Math.abs((Math.atan2(self.distanceY, self.distanceX) * 180) / Math.PI);
|
||||
|
||||
self.isSwiping = angle > 45 && angle < 135 ? "y" : "x";
|
||||
}
|
||||
|
||||
if (self.isSwiping === "y" && $.fancybox.isMobile && self.isScrollable) {
|
||||
self.isScrolling = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
instance.isDragging = self.isSwiping;
|
||||
|
||||
// Reset points to avoid jumping, because we dropped first swipes to calculate the angle
|
||||
self.startPoints = self.newPoints;
|
||||
|
||||
$.each(instance.slides, function (index, slide) {
|
||||
var slidePos, stagePos;
|
||||
|
||||
$.fancybox.stop(slide.$slide);
|
||||
|
||||
slidePos = $.fancybox.getTranslate(slide.$slide);
|
||||
stagePos = $.fancybox.getTranslate(instance.$refs.stage);
|
||||
|
||||
slide.$slide
|
||||
.css({
|
||||
transform: "",
|
||||
opacity: "",
|
||||
"transition-duration": ""
|
||||
})
|
||||
.removeClass("fancybox-animated")
|
||||
.removeClass(function (index, className) {
|
||||
return (className.match(/(^|\s)fancybox-fx-\S+/g) || []).join(" ");
|
||||
});
|
||||
|
||||
if (slide.pos === instance.current.pos) {
|
||||
self.sliderStartPos.top = slidePos.top - stagePos.top;
|
||||
self.sliderStartPos.left = slidePos.left - stagePos.left;
|
||||
}
|
||||
|
||||
$.fancybox.setTranslate(slide.$slide, {
|
||||
top: slidePos.top - stagePos.top,
|
||||
left: slidePos.left - stagePos.left
|
||||
});
|
||||
});
|
||||
|
||||
// Stop slideshow
|
||||
if (instance.SlideShow && instance.SlideShow.isActive) {
|
||||
instance.SlideShow.stop();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Sticky edges
|
||||
if (swiping == "x") {
|
||||
if (
|
||||
self.distanceX > 0 &&
|
||||
(self.instance.group.length < 2 || (self.instance.current.index === 0 && !self.instance.current.opts.loop))
|
||||
) {
|
||||
left = left + Math.pow(self.distanceX, 0.8);
|
||||
} else if (
|
||||
self.distanceX < 0 &&
|
||||
(self.instance.group.length < 2 ||
|
||||
(self.instance.current.index === self.instance.group.length - 1 && !self.instance.current.opts.loop))
|
||||
) {
|
||||
left = left - Math.pow(-self.distanceX, 0.8);
|
||||
} else {
|
||||
left = left + self.distanceX;
|
||||
}
|
||||
}
|
||||
|
||||
self.sliderLastPos = {
|
||||
top: swiping == "x" ? 0 : self.sliderStartPos.top + self.distanceY,
|
||||
left: left
|
||||
};
|
||||
|
||||
if (self.requestId) {
|
||||
cancelAFrame(self.requestId);
|
||||
|
||||
self.requestId = null;
|
||||
}
|
||||
|
||||
self.requestId = requestAFrame(function () {
|
||||
if (self.sliderLastPos) {
|
||||
$.each(self.instance.slides, function (index, slide) {
|
||||
var pos = slide.pos - self.instance.currPos;
|
||||
|
||||
$.fancybox.setTranslate(slide.$slide, {
|
||||
top: self.sliderLastPos.top,
|
||||
left: self.sliderLastPos.left + pos * self.canvasWidth + pos * slide.opts.gutter
|
||||
});
|
||||
});
|
||||
|
||||
self.$container.addClass("fancybox-is-sliding");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Guestures.prototype.onPan = function () {
|
||||
var self = this;
|
||||
|
||||
// Prevent accidental movement (sometimes, when tapping casually, finger can move a bit)
|
||||
if (distance(self.newPoints[0], self.realPoints[0]) < ($.fancybox.isMobile ? 10 : 5)) {
|
||||
self.startPoints = self.newPoints;
|
||||
return;
|
||||
}
|
||||
|
||||
self.canTap = false;
|
||||
|
||||
self.contentLastPos = self.limitMovement();
|
||||
|
||||
if (self.requestId) {
|
||||
cancelAFrame(self.requestId);
|
||||
}
|
||||
|
||||
self.requestId = requestAFrame(function () {
|
||||
$.fancybox.setTranslate(self.$content, self.contentLastPos);
|
||||
});
|
||||
};
|
||||
|
||||
// Make panning sticky to the edges
|
||||
Guestures.prototype.limitMovement = function () {
|
||||
var self = this;
|
||||
|
||||
var canvasWidth = self.canvasWidth;
|
||||
var canvasHeight = self.canvasHeight;
|
||||
|
||||
var distanceX = self.distanceX;
|
||||
var distanceY = self.distanceY;
|
||||
|
||||
var contentStartPos = self.contentStartPos;
|
||||
|
||||
var currentOffsetX = contentStartPos.left;
|
||||
var currentOffsetY = contentStartPos.top;
|
||||
|
||||
var currentWidth = contentStartPos.width;
|
||||
var currentHeight = contentStartPos.height;
|
||||
|
||||
var minTranslateX, minTranslateY, maxTranslateX, maxTranslateY, newOffsetX, newOffsetY;
|
||||
|
||||
if (currentWidth > canvasWidth) {
|
||||
newOffsetX = currentOffsetX + distanceX;
|
||||
} else {
|
||||
newOffsetX = currentOffsetX;
|
||||
}
|
||||
|
||||
newOffsetY = currentOffsetY + distanceY;
|
||||
|
||||
// Slow down proportionally to traveled distance
|
||||
minTranslateX = Math.max(0, canvasWidth * 0.5 - currentWidth * 0.5);
|
||||
minTranslateY = Math.max(0, canvasHeight * 0.5 - currentHeight * 0.5);
|
||||
|
||||
maxTranslateX = Math.min(canvasWidth - currentWidth, canvasWidth * 0.5 - currentWidth * 0.5);
|
||||
maxTranslateY = Math.min(canvasHeight - currentHeight, canvasHeight * 0.5 - currentHeight * 0.5);
|
||||
|
||||
// ->
|
||||
if (distanceX > 0 && newOffsetX > minTranslateX) {
|
||||
newOffsetX = minTranslateX - 1 + Math.pow(-minTranslateX + currentOffsetX + distanceX, 0.8) || 0;
|
||||
}
|
||||
|
||||
// <-
|
||||
if (distanceX < 0 && newOffsetX < maxTranslateX) {
|
||||
newOffsetX = maxTranslateX + 1 - Math.pow(maxTranslateX - currentOffsetX - distanceX, 0.8) || 0;
|
||||
}
|
||||
|
||||
// \/
|
||||
if (distanceY > 0 && newOffsetY > minTranslateY) {
|
||||
newOffsetY = minTranslateY - 1 + Math.pow(-minTranslateY + currentOffsetY + distanceY, 0.8) || 0;
|
||||
}
|
||||
|
||||
// /\
|
||||
if (distanceY < 0 && newOffsetY < maxTranslateY) {
|
||||
newOffsetY = maxTranslateY + 1 - Math.pow(maxTranslateY - currentOffsetY - distanceY, 0.8) || 0;
|
||||
}
|
||||
|
||||
return {
|
||||
top: newOffsetY,
|
||||
left: newOffsetX
|
||||
};
|
||||
};
|
||||
|
||||
Guestures.prototype.limitPosition = function (newOffsetX, newOffsetY, newWidth, newHeight) {
|
||||
var self = this;
|
||||
|
||||
var canvasWidth = self.canvasWidth;
|
||||
var canvasHeight = self.canvasHeight;
|
||||
|
||||
if (newWidth > canvasWidth) {
|
||||
newOffsetX = newOffsetX > 0 ? 0 : newOffsetX;
|
||||
newOffsetX = newOffsetX < canvasWidth - newWidth ? canvasWidth - newWidth : newOffsetX;
|
||||
} else {
|
||||
// Center horizontally
|
||||
newOffsetX = Math.max(0, canvasWidth / 2 - newWidth / 2);
|
||||
}
|
||||
|
||||
if (newHeight > canvasHeight) {
|
||||
newOffsetY = newOffsetY > 0 ? 0 : newOffsetY;
|
||||
newOffsetY = newOffsetY < canvasHeight - newHeight ? canvasHeight - newHeight : newOffsetY;
|
||||
} else {
|
||||
// Center vertically
|
||||
newOffsetY = Math.max(0, canvasHeight / 2 - newHeight / 2);
|
||||
}
|
||||
|
||||
return {
|
||||
top: newOffsetY,
|
||||
left: newOffsetX
|
||||
};
|
||||
};
|
||||
|
||||
Guestures.prototype.onZoom = function () {
|
||||
var self = this;
|
||||
|
||||
// Calculate current distance between points to get pinch ratio and new width and height
|
||||
var contentStartPos = self.contentStartPos;
|
||||
|
||||
var currentWidth = contentStartPos.width;
|
||||
var currentHeight = contentStartPos.height;
|
||||
|
||||
var currentOffsetX = contentStartPos.left;
|
||||
var currentOffsetY = contentStartPos.top;
|
||||
|
||||
var endDistanceBetweenFingers = distance(self.newPoints[0], self.newPoints[1]);
|
||||
|
||||
var pinchRatio = endDistanceBetweenFingers / self.startDistanceBetweenFingers;
|
||||
|
||||
var newWidth = Math.floor(currentWidth * pinchRatio);
|
||||
var newHeight = Math.floor(currentHeight * pinchRatio);
|
||||
|
||||
// This is the translation due to pinch-zooming
|
||||
var translateFromZoomingX = (currentWidth - newWidth) * self.percentageOfImageAtPinchPointX;
|
||||
var translateFromZoomingY = (currentHeight - newHeight) * self.percentageOfImageAtPinchPointY;
|
||||
|
||||
// Point between the two touches
|
||||
var centerPointEndX = (self.newPoints[0].x + self.newPoints[1].x) / 2 - $(window).scrollLeft();
|
||||
var centerPointEndY = (self.newPoints[0].y + self.newPoints[1].y) / 2 - $(window).scrollTop();
|
||||
|
||||
// And this is the translation due to translation of the centerpoint
|
||||
// between the two fingers
|
||||
var translateFromTranslatingX = centerPointEndX - self.centerPointStartX;
|
||||
var translateFromTranslatingY = centerPointEndY - self.centerPointStartY;
|
||||
|
||||
// The new offset is the old/current one plus the total translation
|
||||
var newOffsetX = currentOffsetX + (translateFromZoomingX + translateFromTranslatingX);
|
||||
var newOffsetY = currentOffsetY + (translateFromZoomingY + translateFromTranslatingY);
|
||||
|
||||
var newPos = {
|
||||
top: newOffsetY,
|
||||
left: newOffsetX,
|
||||
scaleX: pinchRatio,
|
||||
scaleY: pinchRatio
|
||||
};
|
||||
|
||||
self.canTap = false;
|
||||
|
||||
self.newWidth = newWidth;
|
||||
self.newHeight = newHeight;
|
||||
|
||||
self.contentLastPos = newPos;
|
||||
|
||||
if (self.requestId) {
|
||||
cancelAFrame(self.requestId);
|
||||
}
|
||||
|
||||
self.requestId = requestAFrame(function () {
|
||||
$.fancybox.setTranslate(self.$content, self.contentLastPos);
|
||||
});
|
||||
};
|
||||
|
||||
Guestures.prototype.ontouchend = function (e) {
|
||||
var self = this;
|
||||
|
||||
var swiping = self.isSwiping;
|
||||
var panning = self.isPanning;
|
||||
var zooming = self.isZooming;
|
||||
var scrolling = self.isScrolling;
|
||||
|
||||
self.endPoints = getPointerXY(e);
|
||||
self.dMs = Math.max(new Date().getTime() - self.startTime, 1);
|
||||
|
||||
self.$container.removeClass("fancybox-is-grabbing");
|
||||
|
||||
$(document).off(".fb.touch");
|
||||
|
||||
document.removeEventListener("scroll", self.onscroll, true);
|
||||
|
||||
if (self.requestId) {
|
||||
cancelAFrame(self.requestId);
|
||||
|
||||
self.requestId = null;
|
||||
}
|
||||
|
||||
self.isSwiping = false;
|
||||
self.isPanning = false;
|
||||
self.isZooming = false;
|
||||
self.isScrolling = false;
|
||||
|
||||
self.instance.isDragging = false;
|
||||
|
||||
if (self.canTap) {
|
||||
return self.onTap(e);
|
||||
}
|
||||
|
||||
self.speed = 100;
|
||||
|
||||
// Speed in px/ms
|
||||
self.velocityX = (self.distanceX / self.dMs) * 0.5;
|
||||
self.velocityY = (self.distanceY / self.dMs) * 0.5;
|
||||
|
||||
if (panning) {
|
||||
self.endPanning();
|
||||
} else if (zooming) {
|
||||
self.endZooming();
|
||||
} else {
|
||||
self.endSwiping(swiping, scrolling);
|
||||
}
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
Guestures.prototype.endSwiping = function (swiping, scrolling) {
|
||||
var self = this,
|
||||
ret = false,
|
||||
len = self.instance.group.length,
|
||||
distanceX = Math.abs(self.distanceX),
|
||||
canAdvance = swiping == "x" && len > 1 && ((self.dMs > 130 && distanceX > 10) || distanceX > 50),
|
||||
speedX = 300;
|
||||
|
||||
self.sliderLastPos = null;
|
||||
|
||||
// Close if swiped vertically / navigate if horizontally
|
||||
if (swiping == "y" && !scrolling && Math.abs(self.distanceY) > 50) {
|
||||
// Continue vertical movement
|
||||
$.fancybox.animate(
|
||||
self.instance.current.$slide, {
|
||||
top: self.sliderStartPos.top + self.distanceY + self.velocityY * 150,
|
||||
opacity: 0
|
||||
},
|
||||
200
|
||||
);
|
||||
ret = self.instance.close(true, 250);
|
||||
} else if (canAdvance && self.distanceX > 0) {
|
||||
ret = self.instance.previous(speedX);
|
||||
} else if (canAdvance && self.distanceX < 0) {
|
||||
ret = self.instance.next(speedX);
|
||||
}
|
||||
|
||||
if (ret === false && (swiping == "x" || swiping == "y")) {
|
||||
self.instance.centerSlide(200);
|
||||
}
|
||||
|
||||
self.$container.removeClass("fancybox-is-sliding");
|
||||
};
|
||||
|
||||
// Limit panning from edges
|
||||
// ========================
|
||||
Guestures.prototype.endPanning = function () {
|
||||
var self = this,
|
||||
newOffsetX,
|
||||
newOffsetY,
|
||||
newPos;
|
||||
|
||||
if (!self.contentLastPos) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.opts.momentum === false || self.dMs > 350) {
|
||||
newOffsetX = self.contentLastPos.left;
|
||||
newOffsetY = self.contentLastPos.top;
|
||||
} else {
|
||||
// Continue movement
|
||||
newOffsetX = self.contentLastPos.left + self.velocityX * 500;
|
||||
newOffsetY = self.contentLastPos.top + self.velocityY * 500;
|
||||
}
|
||||
|
||||
newPos = self.limitPosition(newOffsetX, newOffsetY, self.contentStartPos.width, self.contentStartPos.height);
|
||||
|
||||
newPos.width = self.contentStartPos.width;
|
||||
newPos.height = self.contentStartPos.height;
|
||||
|
||||
$.fancybox.animate(self.$content, newPos, 366);
|
||||
};
|
||||
|
||||
Guestures.prototype.endZooming = function () {
|
||||
var self = this;
|
||||
|
||||
var current = self.instance.current;
|
||||
|
||||
var newOffsetX, newOffsetY, newPos, reset;
|
||||
|
||||
var newWidth = self.newWidth;
|
||||
var newHeight = self.newHeight;
|
||||
|
||||
if (!self.contentLastPos) {
|
||||
return;
|
||||
}
|
||||
|
||||
newOffsetX = self.contentLastPos.left;
|
||||
newOffsetY = self.contentLastPos.top;
|
||||
|
||||
reset = {
|
||||
top: newOffsetY,
|
||||
left: newOffsetX,
|
||||
width: newWidth,
|
||||
height: newHeight,
|
||||
scaleX: 1,
|
||||
scaleY: 1
|
||||
};
|
||||
|
||||
// Reset scalex/scaleY values; this helps for perfomance and does not break animation
|
||||
$.fancybox.setTranslate(self.$content, reset);
|
||||
|
||||
if (newWidth < self.canvasWidth && newHeight < self.canvasHeight) {
|
||||
self.instance.scaleToFit(150);
|
||||
} else if (newWidth > current.width || newHeight > current.height) {
|
||||
self.instance.scaleToActual(self.centerPointStartX, self.centerPointStartY, 150);
|
||||
} else {
|
||||
newPos = self.limitPosition(newOffsetX, newOffsetY, newWidth, newHeight);
|
||||
|
||||
$.fancybox.animate(self.$content, newPos, 150);
|
||||
}
|
||||
};
|
||||
|
||||
Guestures.prototype.onTap = function (e) {
|
||||
var self = this;
|
||||
var $target = $(e.target);
|
||||
|
||||
var instance = self.instance;
|
||||
var current = instance.current;
|
||||
|
||||
var endPoints = (e && getPointerXY(e)) || self.startPoints;
|
||||
|
||||
var tapX = endPoints[0] ? endPoints[0].x - $(window).scrollLeft() - self.stagePos.left : 0;
|
||||
var tapY = endPoints[0] ? endPoints[0].y - $(window).scrollTop() - self.stagePos.top : 0;
|
||||
|
||||
var where;
|
||||
|
||||
var process = function (prefix) {
|
||||
var action = current.opts[prefix];
|
||||
|
||||
if ($.isFunction(action)) {
|
||||
action = action.apply(instance, [current, e]);
|
||||
}
|
||||
|
||||
if (!action) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case "close":
|
||||
instance.close(self.startEvent);
|
||||
|
||||
break;
|
||||
|
||||
case "toggleControls":
|
||||
instance.toggleControls();
|
||||
|
||||
break;
|
||||
|
||||
case "next":
|
||||
instance.next();
|
||||
|
||||
break;
|
||||
|
||||
case "nextOrClose":
|
||||
if (instance.group.length > 1) {
|
||||
instance.next();
|
||||
} else {
|
||||
instance.close(self.startEvent);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "zoom":
|
||||
if (current.type == "image" && (current.isLoaded || current.$ghost)) {
|
||||
if (instance.canPan()) {
|
||||
instance.scaleToFit();
|
||||
} else if (instance.isScaledDown()) {
|
||||
instance.scaleToActual(tapX, tapY);
|
||||
} else if (instance.group.length < 2) {
|
||||
instance.close(self.startEvent);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
// Ignore right click
|
||||
if (e.originalEvent && e.originalEvent.button == 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip if clicked on the scrollbar
|
||||
if (!$target.is("img") && tapX > $target[0].clientWidth + $target.offset().left) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check where is clicked
|
||||
if ($target.is(".fancybox-bg,.fancybox-inner,.fancybox-outer,.fancybox-container")) {
|
||||
where = "Outside";
|
||||
} else if ($target.is(".fancybox-slide")) {
|
||||
where = "Slide";
|
||||
} else if (
|
||||
instance.current.$content &&
|
||||
instance.current.$content
|
||||
.find($target)
|
||||
.addBack()
|
||||
.filter($target).length
|
||||
) {
|
||||
where = "Content";
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if this is a double tap
|
||||
if (self.tapped) {
|
||||
// Stop previously created single tap
|
||||
clearTimeout(self.tapped);
|
||||
self.tapped = null;
|
||||
|
||||
// Skip if distance between taps is too big
|
||||
if (Math.abs(tapX - self.tapX) > 50 || Math.abs(tapY - self.tapY) > 50) {
|
||||
return this;
|
||||
}
|
||||
|
||||
// OK, now we assume that this is a double-tap
|
||||
process("dblclick" + where);
|
||||
} else {
|
||||
// Single tap will be processed if user has not clicked second time within 300ms
|
||||
// or there is no need to wait for double-tap
|
||||
self.tapX = tapX;
|
||||
self.tapY = tapY;
|
||||
|
||||
if (current.opts["dblclick" + where] && current.opts["dblclick" + where] !== current.opts["click" + where]) {
|
||||
self.tapped = setTimeout(function () {
|
||||
self.tapped = null;
|
||||
|
||||
if (!instance.isAnimating) {
|
||||
process("click" + where);
|
||||
}
|
||||
}, 500);
|
||||
} else {
|
||||
process("click" + where);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
$(document)
|
||||
.on("onActivate.fb", function (e, instance) {
|
||||
if (instance && !instance.Guestures) {
|
||||
instance.Guestures = new Guestures(instance);
|
||||
}
|
||||
})
|
||||
.on("beforeClose.fb", function (e, instance) {
|
||||
if (instance && instance.Guestures) {
|
||||
instance.Guestures.destroy();
|
||||
}
|
||||
});
|
||||
})(window, document, jQuery);
|
||||
// ==========================================================================
|
||||
//
|
||||
// SlideShow
|
||||
// Enables slideshow functionality
|
||||
//
|
||||
// Example of usage:
|
||||
// $.fancybox.getInstance().SlideShow.start()
|
||||
//
|
||||
// ==========================================================================
|
||||
(function (document, $) {
|
||||
"use strict";
|
||||
|
||||
$.extend(true, $.fancybox.defaults, {
|
||||
btnTpl: {
|
||||
slideShow: '<button data-fancybox-play class="fancybox-button fancybox-button--play" title="{{PLAY_START}}">' +
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6.5 5.4v13.2l11-6.6z"/></svg>' +
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.33 5.75h2.2v12.5h-2.2V5.75zm5.15 0h2.2v12.5h-2.2V5.75z"/></svg>' +
|
||||
"</button>"
|
||||
},
|
||||
slideShow: {
|
||||
autoStart: false,
|
||||
speed: 3000,
|
||||
progress: true
|
||||
}
|
||||
});
|
||||
|
||||
var SlideShow = function (instance) {
|
||||
this.instance = instance;
|
||||
this.init();
|
||||
};
|
||||
|
||||
$.extend(SlideShow.prototype, {
|
||||
timer: null,
|
||||
isActive: false,
|
||||
$button: null,
|
||||
|
||||
init: function () {
|
||||
var self = this,
|
||||
instance = self.instance,
|
||||
opts = instance.group[instance.currIndex].opts.slideShow;
|
||||
|
||||
self.$button = instance.$refs.toolbar.find("[data-fancybox-play]").on("click", function () {
|
||||
self.toggle();
|
||||
});
|
||||
|
||||
if (instance.group.length < 2 || !opts) {
|
||||
self.$button.hide();
|
||||
} else if (opts.progress) {
|
||||
self.$progress = $('<div class="fancybox-progress"></div>').appendTo(instance.$refs.inner);
|
||||
}
|
||||
},
|
||||
|
||||
set: function (force) {
|
||||
var self = this,
|
||||
instance = self.instance,
|
||||
current = instance.current;
|
||||
|
||||
// Check if reached last element
|
||||
if (current && (force === true || current.opts.loop || instance.currIndex < instance.group.length - 1)) {
|
||||
if (self.isActive && current.contentType !== "video") {
|
||||
if (self.$progress) {
|
||||
$.fancybox.animate(self.$progress.show(), {
|
||||
scaleX: 1
|
||||
}, current.opts.slideShow.speed);
|
||||
}
|
||||
|
||||
self.timer = setTimeout(function () {
|
||||
if (!instance.current.opts.loop && instance.current.index == instance.group.length - 1) {
|
||||
instance.jumpTo(0);
|
||||
} else {
|
||||
instance.next();
|
||||
}
|
||||
}, current.opts.slideShow.speed);
|
||||
}
|
||||
} else {
|
||||
self.stop();
|
||||
instance.idleSecondsCounter = 0;
|
||||
instance.showControls();
|
||||
}
|
||||
},
|
||||
|
||||
clear: function () {
|
||||
var self = this;
|
||||
|
||||
clearTimeout(self.timer);
|
||||
|
||||
self.timer = null;
|
||||
|
||||
if (self.$progress) {
|
||||
self.$progress.removeAttr("style").hide();
|
||||
}
|
||||
},
|
||||
|
||||
start: function () {
|
||||
var self = this,
|
||||
current = self.instance.current;
|
||||
|
||||
if (current) {
|
||||
self.$button
|
||||
.attr("title", (current.opts.i18n[current.opts.lang] || current.opts.i18n.en).PLAY_STOP)
|
||||
.removeClass("fancybox-button--play")
|
||||
.addClass("fancybox-button--pause");
|
||||
|
||||
self.isActive = true;
|
||||
|
||||
if (current.isComplete) {
|
||||
self.set(true);
|
||||
}
|
||||
|
||||
self.instance.trigger("onSlideShowChange", true);
|
||||
}
|
||||
},
|
||||
|
||||
stop: function () {
|
||||
var self = this,
|
||||
current = self.instance.current;
|
||||
|
||||
self.clear();
|
||||
|
||||
self.$button
|
||||
.attr("title", (current.opts.i18n[current.opts.lang] || current.opts.i18n.en).PLAY_START)
|
||||
.removeClass("fancybox-button--pause")
|
||||
.addClass("fancybox-button--play");
|
||||
|
||||
self.isActive = false;
|
||||
|
||||
self.instance.trigger("onSlideShowChange", false);
|
||||
|
||||
if (self.$progress) {
|
||||
self.$progress.removeAttr("style").hide();
|
||||
}
|
||||
},
|
||||
|
||||
toggle: function () {
|
||||
var self = this;
|
||||
|
||||
if (self.isActive) {
|
||||
self.stop();
|
||||
} else {
|
||||
self.start();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on({
|
||||
"onInit.fb": function (e, instance) {
|
||||
if (instance && !instance.SlideShow) {
|
||||
instance.SlideShow = new SlideShow(instance);
|
||||
}
|
||||
},
|
||||
|
||||
"beforeShow.fb": function (e, instance, current, firstRun) {
|
||||
var SlideShow = instance && instance.SlideShow;
|
||||
|
||||
if (firstRun) {
|
||||
if (SlideShow && current.opts.slideShow.autoStart) {
|
||||
SlideShow.start();
|
||||
}
|
||||
} else if (SlideShow && SlideShow.isActive) {
|
||||
SlideShow.clear();
|
||||
}
|
||||
},
|
||||
|
||||
"afterShow.fb": function (e, instance, current) {
|
||||
var SlideShow = instance && instance.SlideShow;
|
||||
|
||||
if (SlideShow && SlideShow.isActive) {
|
||||
SlideShow.set();
|
||||
}
|
||||
},
|
||||
|
||||
"afterKeydown.fb": function (e, instance, current, keypress, keycode) {
|
||||
var SlideShow = instance && instance.SlideShow;
|
||||
|
||||
// "P" or Spacebar
|
||||
if (SlideShow && current.opts.slideShow && (keycode === 80 || keycode === 32) && !$(document.activeElement).is("button,a,input")) {
|
||||
keypress.preventDefault();
|
||||
|
||||
SlideShow.toggle();
|
||||
}
|
||||
},
|
||||
|
||||
"beforeClose.fb onDeactivate.fb": function (e, instance) {
|
||||
var SlideShow = instance && instance.SlideShow;
|
||||
|
||||
if (SlideShow) {
|
||||
SlideShow.stop();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Page Visibility API to pause slideshow when window is not active
|
||||
$(document).on("visibilitychange", function () {
|
||||
var instance = $.fancybox.getInstance(),
|
||||
SlideShow = instance && instance.SlideShow;
|
||||
|
||||
if (SlideShow && SlideShow.isActive) {
|
||||
if (document.hidden) {
|
||||
SlideShow.clear();
|
||||
} else {
|
||||
SlideShow.set();
|
||||
}
|
||||
}
|
||||
});
|
||||
})(document, jQuery);
|
||||
// ==========================================================================
|
||||
//
|
||||
// FullScreen
|
||||
// Adds fullscreen functionality
|
||||
//
|
||||
// ==========================================================================
|
||||
(function (document, $) {
|
||||
"use strict";
|
||||
|
||||
// Collection of methods supported by user browser
|
||||
var fn = (function () {
|
||||
var fnMap = [
|
||||
["requestFullscreen", "exitFullscreen", "fullscreenElement", "fullscreenEnabled", "fullscreenchange", "fullscreenerror"],
|
||||
// new WebKit
|
||||
[
|
||||
"webkitRequestFullscreen",
|
||||
"webkitExitFullscreen",
|
||||
"webkitFullscreenElement",
|
||||
"webkitFullscreenEnabled",
|
||||
"webkitfullscreenchange",
|
||||
"webkitfullscreenerror"
|
||||
],
|
||||
// old WebKit (Safari 5.1)
|
||||
[
|
||||
"webkitRequestFullScreen",
|
||||
"webkitCancelFullScreen",
|
||||
"webkitCurrentFullScreenElement",
|
||||
"webkitCancelFullScreen",
|
||||
"webkitfullscreenchange",
|
||||
"webkitfullscreenerror"
|
||||
],
|
||||
[
|
||||
"mozRequestFullScreen",
|
||||
"mozCancelFullScreen",
|
||||
"mozFullScreenElement",
|
||||
"mozFullScreenEnabled",
|
||||
"mozfullscreenchange",
|
||||
"mozfullscreenerror"
|
||||
],
|
||||
["msRequestFullscreen", "msExitFullscreen", "msFullscreenElement", "msFullscreenEnabled", "MSFullscreenChange", "MSFullscreenError"]
|
||||
];
|
||||
|
||||
var ret = {};
|
||||
|
||||
for (var i = 0; i < fnMap.length; i++) {
|
||||
var val = fnMap[i];
|
||||
|
||||
if (val && val[1] in document) {
|
||||
for (var j = 0; j < val.length; j++) {
|
||||
ret[fnMap[0][j]] = val[j];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
})();
|
||||
|
||||
if (fn) {
|
||||
var FullScreen = {
|
||||
request: function (elem) {
|
||||
elem = elem || document.documentElement;
|
||||
|
||||
elem[fn.requestFullscreen](elem.ALLOW_KEYBOARD_INPUT);
|
||||
},
|
||||
exit: function () {
|
||||
document[fn.exitFullscreen]();
|
||||
},
|
||||
toggle: function (elem) {
|
||||
elem = elem || document.documentElement;
|
||||
|
||||
if (this.isFullscreen()) {
|
||||
this.exit();
|
||||
} else {
|
||||
this.request(elem);
|
||||
}
|
||||
},
|
||||
isFullscreen: function () {
|
||||
return Boolean(document[fn.fullscreenElement]);
|
||||
},
|
||||
enabled: function () {
|
||||
return Boolean(document[fn.fullscreenEnabled]);
|
||||
}
|
||||
};
|
||||
|
||||
$.extend(true, $.fancybox.defaults, {
|
||||
btnTpl: {
|
||||
fullScreen: '<button data-fancybox-fullscreen class="fancybox-button fancybox-button--fsenter" title="{{FULL_SCREEN}}">' +
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/></svg>' +
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5 16h3v3h2v-5H5zm3-8H5v2h5V5H8zm6 11h2v-3h3v-2h-5zm2-11V5h-2v5h5V8z"/></svg>' +
|
||||
"</button>"
|
||||
},
|
||||
fullScreen: {
|
||||
autoStart: false
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on(fn.fullscreenchange, function () {
|
||||
var isFullscreen = FullScreen.isFullscreen(),
|
||||
instance = $.fancybox.getInstance();
|
||||
|
||||
if (instance) {
|
||||
// If image is zooming, then force to stop and reposition properly
|
||||
if (instance.current && instance.current.type === "image" && instance.isAnimating) {
|
||||
instance.isAnimating = false;
|
||||
|
||||
instance.update(true, true, 0);
|
||||
|
||||
if (!instance.isComplete) {
|
||||
instance.complete();
|
||||
}
|
||||
}
|
||||
|
||||
instance.trigger("onFullscreenChange", isFullscreen);
|
||||
|
||||
instance.$refs.container.toggleClass("fancybox-is-fullscreen", isFullscreen);
|
||||
|
||||
instance.$refs.toolbar
|
||||
.find("[data-fancybox-fullscreen]")
|
||||
.toggleClass("fancybox-button--fsenter", !isFullscreen)
|
||||
.toggleClass("fancybox-button--fsexit", isFullscreen);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).on({
|
||||
"onInit.fb": function (e, instance) {
|
||||
var $container;
|
||||
|
||||
if (!fn) {
|
||||
instance.$refs.toolbar.find("[data-fancybox-fullscreen]").remove();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (instance && instance.group[instance.currIndex].opts.fullScreen) {
|
||||
$container = instance.$refs.container;
|
||||
|
||||
$container.on("click.fb-fullscreen", "[data-fancybox-fullscreen]", function (e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
FullScreen.toggle();
|
||||
});
|
||||
|
||||
if (instance.opts.fullScreen && instance.opts.fullScreen.autoStart === true) {
|
||||
FullScreen.request();
|
||||
}
|
||||
|
||||
// Expose API
|
||||
instance.FullScreen = FullScreen;
|
||||
} else if (instance) {
|
||||
instance.$refs.toolbar.find("[data-fancybox-fullscreen]").hide();
|
||||
}
|
||||
},
|
||||
|
||||
"afterKeydown.fb": function (e, instance, current, keypress, keycode) {
|
||||
// "F"
|
||||
if (instance && instance.FullScreen && keycode === 70) {
|
||||
keypress.preventDefault();
|
||||
|
||||
instance.FullScreen.toggle();
|
||||
}
|
||||
},
|
||||
|
||||
"beforeClose.fb": function (e, instance) {
|
||||
if (instance && instance.FullScreen && instance.$refs.container.hasClass("fancybox-is-fullscreen")) {
|
||||
FullScreen.exit();
|
||||
}
|
||||
}
|
||||
});
|
||||
})(document, jQuery);
|
||||
// ==========================================================================
|
||||
//
|
||||
// Thumbs
|
||||
// Displays thumbnails in a grid
|
||||
//
|
||||
// ==========================================================================
|
||||
(function (document, $) {
|
||||
"use strict";
|
||||
|
||||
var CLASS = "fancybox-thumbs",
|
||||
CLASS_ACTIVE = CLASS + "-active";
|
||||
|
||||
// Make sure there are default values
|
||||
$.fancybox.defaults = $.extend(
|
||||
true, {
|
||||
btnTpl: {
|
||||
thumbs: '<button data-fancybox-thumbs class="fancybox-button fancybox-button--thumbs" title="{{THUMBS}}">' +
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14.59 14.59h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76H5.65v-3.76zm8.94-4.47h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76H5.65v-3.76zm8.94-4.47h3.76v3.76h-3.76V5.65zm-4.47 0h3.76v3.76h-3.76V5.65zm-4.47 0h3.76v3.76H5.65V5.65z"/></svg>' +
|
||||
"</button>"
|
||||
},
|
||||
thumbs: {
|
||||
autoStart: false, // Display thumbnails on opening
|
||||
hideOnClose: true, // Hide thumbnail grid when closing animation starts
|
||||
parentEl: ".fancybox-container", // Container is injected into this element
|
||||
axis: "y" // Vertical (y) or horizontal (x) scrolling
|
||||
}
|
||||
},
|
||||
$.fancybox.defaults
|
||||
);
|
||||
|
||||
var FancyThumbs = function (instance) {
|
||||
this.init(instance);
|
||||
};
|
||||
|
||||
$.extend(FancyThumbs.prototype, {
|
||||
$button: null,
|
||||
$grid: null,
|
||||
$list: null,
|
||||
isVisible: false,
|
||||
isActive: false,
|
||||
|
||||
init: function (instance) {
|
||||
var self = this,
|
||||
group = instance.group,
|
||||
enabled = 0;
|
||||
|
||||
self.instance = instance;
|
||||
self.opts = group[instance.currIndex].opts.thumbs;
|
||||
|
||||
instance.Thumbs = self;
|
||||
|
||||
self.$button = instance.$refs.toolbar.find("[data-fancybox-thumbs]");
|
||||
|
||||
// Enable thumbs if at least two group items have thumbnails
|
||||
for (var i = 0, len = group.length; i < len; i++) {
|
||||
if (group[i].thumb) {
|
||||
enabled++;
|
||||
}
|
||||
|
||||
if (enabled > 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (enabled > 1 && !!self.opts) {
|
||||
self.$button.removeAttr("style").on("click", function () {
|
||||
self.toggle();
|
||||
});
|
||||
|
||||
self.isActive = true;
|
||||
} else {
|
||||
self.$button.hide();
|
||||
}
|
||||
},
|
||||
|
||||
create: function () {
|
||||
var self = this,
|
||||
instance = self.instance,
|
||||
parentEl = self.opts.parentEl,
|
||||
list = [],
|
||||
src;
|
||||
|
||||
if (!self.$grid) {
|
||||
// Create main element
|
||||
self.$grid = $('<div class="' + CLASS + " " + CLASS + "-" + self.opts.axis + '"></div>').appendTo(
|
||||
instance.$refs.container
|
||||
.find(parentEl)
|
||||
.addBack()
|
||||
.filter(parentEl)
|
||||
);
|
||||
|
||||
// Add "click" event that performs gallery navigation
|
||||
self.$grid.on("click", "a", function () {
|
||||
instance.jumpTo($(this).attr("data-index"));
|
||||
});
|
||||
}
|
||||
|
||||
// Build the list
|
||||
if (!self.$list) {
|
||||
self.$list = $('<div class="' + CLASS + '__list">').appendTo(self.$grid);
|
||||
}
|
||||
|
||||
$.each(instance.group, function (i, item) {
|
||||
src = item.thumb;
|
||||
|
||||
if (!src && item.type === "image") {
|
||||
src = item.src;
|
||||
}
|
||||
|
||||
list.push(
|
||||
'<a href="javascript:;" tabindex="0" data-index="' +
|
||||
i +
|
||||
'"' +
|
||||
(src && src.length ? ' style="background-image:url(' + src + ')"' : 'class="fancybox-thumbs-missing"') +
|
||||
"></a>"
|
||||
);
|
||||
});
|
||||
|
||||
self.$list[0].innerHTML = list.join("");
|
||||
|
||||
if (self.opts.axis === "x") {
|
||||
// Set fixed width for list element to enable horizontal scrolling
|
||||
self.$list.width(
|
||||
parseInt(self.$grid.css("padding-right"), 10) +
|
||||
instance.group.length *
|
||||
self.$list
|
||||
.children()
|
||||
.eq(0)
|
||||
.outerWidth(true)
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
focus: function (duration) {
|
||||
var self = this,
|
||||
$list = self.$list,
|
||||
$grid = self.$grid,
|
||||
thumb,
|
||||
thumbPos;
|
||||
|
||||
if (!self.instance.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
thumb = $list
|
||||
.children()
|
||||
.removeClass(CLASS_ACTIVE)
|
||||
.filter('[data-index="' + self.instance.current.index + '"]')
|
||||
.addClass(CLASS_ACTIVE);
|
||||
|
||||
thumbPos = thumb.position();
|
||||
|
||||
// Check if need to scroll to make current thumb visible
|
||||
if (self.opts.axis === "y" && (thumbPos.top < 0 || thumbPos.top > $list.height() - thumb.outerHeight())) {
|
||||
$list.stop().animate({
|
||||
scrollTop: $list.scrollTop() + thumbPos.top
|
||||
},
|
||||
duration
|
||||
);
|
||||
} else if (
|
||||
self.opts.axis === "x" &&
|
||||
(thumbPos.left < $grid.scrollLeft() || thumbPos.left > $grid.scrollLeft() + ($grid.width() - thumb.outerWidth()))
|
||||
) {
|
||||
$list
|
||||
.parent()
|
||||
.stop()
|
||||
.animate({
|
||||
scrollLeft: thumbPos.left
|
||||
},
|
||||
duration
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
update: function () {
|
||||
var that = this;
|
||||
that.instance.$refs.container.toggleClass("fancybox-show-thumbs", this.isVisible);
|
||||
|
||||
if (that.isVisible) {
|
||||
if (!that.$grid) {
|
||||
that.create();
|
||||
}
|
||||
|
||||
that.instance.trigger("onThumbsShow");
|
||||
|
||||
that.focus(0);
|
||||
} else if (that.$grid) {
|
||||
that.instance.trigger("onThumbsHide");
|
||||
}
|
||||
|
||||
// Update content position
|
||||
that.instance.update();
|
||||
},
|
||||
|
||||
hide: function () {
|
||||
this.isVisible = false;
|
||||
this.update();
|
||||
},
|
||||
|
||||
show: function () {
|
||||
this.isVisible = true;
|
||||
this.update();
|
||||
},
|
||||
|
||||
toggle: function () {
|
||||
this.isVisible = !this.isVisible;
|
||||
this.update();
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on({
|
||||
"onInit.fb": function (e, instance) {
|
||||
var Thumbs;
|
||||
|
||||
if (instance && !instance.Thumbs) {
|
||||
Thumbs = new FancyThumbs(instance);
|
||||
|
||||
if (Thumbs.isActive && Thumbs.opts.autoStart === true) {
|
||||
Thumbs.show();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"beforeShow.fb": function (e, instance, item, firstRun) {
|
||||
var Thumbs = instance && instance.Thumbs;
|
||||
|
||||
if (Thumbs && Thumbs.isVisible) {
|
||||
Thumbs.focus(firstRun ? 0 : 250);
|
||||
}
|
||||
},
|
||||
|
||||
"afterKeydown.fb": function (e, instance, current, keypress, keycode) {
|
||||
var Thumbs = instance && instance.Thumbs;
|
||||
|
||||
// "G"
|
||||
if (Thumbs && Thumbs.isActive && keycode === 71) {
|
||||
keypress.preventDefault();
|
||||
|
||||
Thumbs.toggle();
|
||||
}
|
||||
},
|
||||
|
||||
"beforeClose.fb": function (e, instance) {
|
||||
var Thumbs = instance && instance.Thumbs;
|
||||
|
||||
if (Thumbs && Thumbs.isVisible && Thumbs.opts.hideOnClose !== false) {
|
||||
Thumbs.$grid.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
})(document, jQuery);
|
||||
//// ==========================================================================
|
||||
//
|
||||
// Share
|
||||
// Displays simple form for sharing current url
|
||||
//
|
||||
// ==========================================================================
|
||||
(function (document, $) {
|
||||
"use strict";
|
||||
|
||||
$.extend(true, $.fancybox.defaults, {
|
||||
btnTpl: {
|
||||
share: '<button data-fancybox-share class="fancybox-button fancybox-button--share" title="{{SHARE}}">' +
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M2.55 19c1.4-8.4 9.1-9.8 11.9-9.8V5l7 7-7 6.3v-3.5c-2.8 0-10.5 2.1-11.9 4.2z"/></svg>' +
|
||||
"</button>"
|
||||
},
|
||||
share: {
|
||||
url: function (instance, item) {
|
||||
return (
|
||||
(!instance.currentHash && !(item.type === "inline" || item.type === "html") ? item.origSrc || item.src : false) || window.location
|
||||
);
|
||||
},
|
||||
tpl: '<div class="fancybox-share">' +
|
||||
"<h1>{{SHARE}}</h1>" +
|
||||
"<p>" +
|
||||
'<a class="fancybox-share__button fancybox-share__button--fb" href="https://www.facebook.com/sharer/sharer.php?u={{url}}">' +
|
||||
'<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m287 456v-299c0-21 6-35 35-35h38v-63c-7-1-29-3-55-3-54 0-91 33-91 94v306m143-254h-205v72h196" /></svg>' +
|
||||
"<span>Facebook</span>" +
|
||||
"</a>" +
|
||||
'<a class="fancybox-share__button fancybox-share__button--tw" href="https://twitter.com/intent/tweet?url={{url}}&text={{descr}}">' +
|
||||
'<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m456 133c-14 7-31 11-47 13 17-10 30-27 37-46-15 10-34 16-52 20-61-62-157-7-141 75-68-3-129-35-169-85-22 37-11 86 26 109-13 0-26-4-37-9 0 39 28 72 65 80-12 3-25 4-37 2 10 33 41 57 77 57-42 30-77 38-122 34 170 111 378-32 359-208 16-11 30-25 41-42z" /></svg>' +
|
||||
"<span>Twitter</span>" +
|
||||
"</a>" +
|
||||
'<a class="fancybox-share__button fancybox-share__button--pt" href="https://www.pinterest.com/pin/create/button/?url={{url}}&description={{descr}}&media={{media}}">' +
|
||||
'<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m265 56c-109 0-164 78-164 144 0 39 15 74 47 87 5 2 10 0 12-5l4-19c2-6 1-8-3-13-9-11-15-25-15-45 0-58 43-110 113-110 62 0 96 38 96 88 0 67-30 122-73 122-24 0-42-19-36-44 6-29 20-60 20-81 0-19-10-35-31-35-25 0-44 26-44 60 0 21 7 36 7 36l-30 125c-8 37-1 83 0 87 0 3 4 4 5 2 2-3 32-39 42-75l16-64c8 16 31 29 56 29 74 0 124-67 124-157 0-69-58-132-146-132z" fill="#fff"/></svg>' +
|
||||
"<span>Pinterest</span>" +
|
||||
"</a>" +
|
||||
"</p>" +
|
||||
'<p><input class="fancybox-share__input" type="text" value="{{url_raw}}" onclick="select()" /></p>' +
|
||||
"</div>"
|
||||
}
|
||||
});
|
||||
|
||||
function escapeHtml(string) {
|
||||
var entityMap = {
|
||||
"&": "&",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
'"': """,
|
||||
"'": "'",
|
||||
"/": "/",
|
||||
"`": "`",
|
||||
"=": "="
|
||||
};
|
||||
|
||||
return String(string).replace(/[&<>"'`=\/]/g, function (s) {
|
||||
return entityMap[s];
|
||||
});
|
||||
}
|
||||
|
||||
$(document).on("click", "[data-fancybox-share]", function () {
|
||||
var instance = $.fancybox.getInstance(),
|
||||
current = instance.current || null,
|
||||
url,
|
||||
tpl;
|
||||
|
||||
if (!current) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($.type(current.opts.share.url) === "function") {
|
||||
url = current.opts.share.url.apply(current, [instance, current]);
|
||||
}
|
||||
|
||||
tpl = current.opts.share.tpl
|
||||
.replace(/\{\{media\}\}/g, current.type === "image" ? encodeURIComponent(current.src) : "")
|
||||
.replace(/\{\{url\}\}/g, encodeURIComponent(url))
|
||||
.replace(/\{\{url_raw\}\}/g, escapeHtml(url))
|
||||
.replace(/\{\{descr\}\}/g, instance.$caption ? encodeURIComponent(instance.$caption.text()) : "");
|
||||
|
||||
$.fancybox.open({
|
||||
src: instance.translate(instance, tpl),
|
||||
type: "html",
|
||||
opts: {
|
||||
touch: false,
|
||||
animationEffect: false,
|
||||
afterLoad: function (shareInstance, shareCurrent) {
|
||||
// Close self if parent instance is closing
|
||||
instance.$refs.container.one("beforeClose.fb", function () {
|
||||
shareInstance.close(null, 0);
|
||||
});
|
||||
|
||||
// Opening links in a popup window
|
||||
shareCurrent.$content.find(".fancybox-share__button").click(function () {
|
||||
window.open(this.href, "Share", "width=550, height=450");
|
||||
return false;
|
||||
});
|
||||
},
|
||||
mobile: {
|
||||
autoFocus: false
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
})(document, jQuery);
|
||||
// ==========================================================================
|
||||
//
|
||||
// Hash
|
||||
// Enables linking to each modal
|
||||
//
|
||||
// ==========================================================================
|
||||
(function (window, document, $) {
|
||||
"use strict";
|
||||
|
||||
// Simple $.escapeSelector polyfill (for jQuery prior v3)
|
||||
if (!$.escapeSelector) {
|
||||
$.escapeSelector = function (sel) {
|
||||
var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
|
||||
var fcssescape = function (ch, asCodePoint) {
|
||||
if (asCodePoint) {
|
||||
// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
|
||||
if (ch === "\0") {
|
||||
return "\uFFFD";
|
||||
}
|
||||
|
||||
// Control characters and (dependent upon position) numbers get escaped as code points
|
||||
return ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " ";
|
||||
}
|
||||
|
||||
// Other potentially-special ASCII characters get backslash-escaped
|
||||
return "\\" + ch;
|
||||
};
|
||||
|
||||
return (sel + "").replace(rcssescape, fcssescape);
|
||||
};
|
||||
}
|
||||
|
||||
// Get info about gallery name and current index from url
|
||||
function parseUrl() {
|
||||
var hash = window.location.hash.substr(1),
|
||||
rez = hash.split("-"),
|
||||
index = rez.length > 1 && /^\+?\d+$/.test(rez[rez.length - 1]) ? parseInt(rez.pop(-1), 10) || 1 : 1,
|
||||
gallery = rez.join("-");
|
||||
|
||||
return {
|
||||
hash: hash,
|
||||
/* Index is starting from 1 */
|
||||
index: index < 1 ? 1 : index,
|
||||
gallery: gallery
|
||||
};
|
||||
}
|
||||
|
||||
// Trigger click evnt on links to open new fancyBox instance
|
||||
function triggerFromUrl(url) {
|
||||
if (url.gallery !== "") {
|
||||
// If we can find element matching 'data-fancybox' atribute,
|
||||
// then triggering click event should start fancyBox
|
||||
$("[data-fancybox='" + $.escapeSelector(url.gallery) + "']")
|
||||
.eq(url.index - 1)
|
||||
.focus()
|
||||
.trigger("click.fb-start");
|
||||
}
|
||||
}
|
||||
|
||||
// Get gallery name from current instance
|
||||
function getGalleryID(instance) {
|
||||
var opts, ret;
|
||||
|
||||
if (!instance) {
|
||||
return false;
|
||||
}
|
||||
|
||||
opts = instance.current ? instance.current.opts : instance.opts;
|
||||
ret = opts.hash || (opts.$orig ? opts.$orig.data("fancybox") || opts.$orig.data("fancybox-trigger") : "");
|
||||
|
||||
return ret === "" ? false : ret;
|
||||
}
|
||||
|
||||
// Start when DOM becomes ready
|
||||
$(function () {
|
||||
// Check if user has disabled this module
|
||||
if ($.fancybox.defaults.hash === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update hash when opening/closing fancyBox
|
||||
$(document).on({
|
||||
"onInit.fb": function (e, instance) {
|
||||
var url, gallery;
|
||||
|
||||
if (instance.group[instance.currIndex].opts.hash === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
url = parseUrl();
|
||||
gallery = getGalleryID(instance);
|
||||
|
||||
// Make sure gallery start index matches index from hash
|
||||
if (gallery && url.gallery && gallery == url.gallery) {
|
||||
instance.currIndex = url.index - 1;
|
||||
}
|
||||
},
|
||||
|
||||
"beforeShow.fb": function (e, instance, current, firstRun) {
|
||||
var gallery;
|
||||
|
||||
if (!current || current.opts.hash === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if need to update window hash
|
||||
gallery = getGalleryID(instance);
|
||||
|
||||
if (!gallery) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Variable containing last hash value set by fancyBox
|
||||
// It will be used to determine if fancyBox needs to close after hash change is detected
|
||||
instance.currentHash = gallery + (instance.group.length > 1 ? "-" + (current.index + 1) : "");
|
||||
|
||||
// If current hash is the same (this instance most likely is opened by hashchange), then do nothing
|
||||
if (window.location.hash === "#" + instance.currentHash) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (firstRun && !instance.origHash) {
|
||||
instance.origHash = window.location.hash;
|
||||
}
|
||||
|
||||
if (instance.hashTimer) {
|
||||
clearTimeout(instance.hashTimer);
|
||||
}
|
||||
|
||||
// Update hash
|
||||
instance.hashTimer = setTimeout(function () {
|
||||
if ("replaceState" in window.history) {
|
||||
window.history[firstRun ? "pushState" : "replaceState"]({},
|
||||
document.title,
|
||||
window.location.pathname + window.location.search + "#" + instance.currentHash
|
||||
);
|
||||
|
||||
if (firstRun) {
|
||||
instance.hasCreatedHistory = true;
|
||||
}
|
||||
} else {
|
||||
window.location.hash = instance.currentHash;
|
||||
}
|
||||
|
||||
instance.hashTimer = null;
|
||||
}, 300);
|
||||
},
|
||||
|
||||
"beforeClose.fb": function (e, instance, current) {
|
||||
if (!current || current.opts.hash === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearTimeout(instance.hashTimer);
|
||||
|
||||
// Goto previous history entry
|
||||
if (instance.currentHash && instance.hasCreatedHistory) {
|
||||
window.history.back();
|
||||
} else if (instance.currentHash) {
|
||||
if ("replaceState" in window.history) {
|
||||
window.history.replaceState({}, document.title, window.location.pathname + window.location.search + (instance.origHash || ""));
|
||||
} else {
|
||||
window.location.hash = instance.origHash;
|
||||
}
|
||||
}
|
||||
|
||||
instance.currentHash = null;
|
||||
}
|
||||
});
|
||||
|
||||
// Check if need to start/close after url has changed
|
||||
$(window).on("hashchange.fb", function () {
|
||||
var url = parseUrl(),
|
||||
fb = null;
|
||||
|
||||
// Find last fancyBox instance that has "hash"
|
||||
$.each(
|
||||
$(".fancybox-container")
|
||||
.get()
|
||||
.reverse(),
|
||||
function (index, value) {
|
||||
var tmp = $(value).data("FancyBox");
|
||||
|
||||
if (tmp && tmp.currentHash) {
|
||||
fb = tmp;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (fb) {
|
||||
// Now, compare hash values
|
||||
if (fb.currentHash !== url.gallery + "-" + url.index && !(url.index === 1 && fb.currentHash == url.gallery)) {
|
||||
fb.currentHash = null;
|
||||
|
||||
fb.close();
|
||||
}
|
||||
} else if (url.gallery !== "") {
|
||||
triggerFromUrl(url);
|
||||
}
|
||||
});
|
||||
|
||||
// Check current hash and trigger click event on matching element to start fancyBox, if needed
|
||||
setTimeout(function () {
|
||||
if (!$.fancybox.getInstance()) {
|
||||
triggerFromUrl(parseUrl());
|
||||
}
|
||||
}, 50);
|
||||
});
|
||||
})(window, document, jQuery);
|
||||
// ==========================================================================
|
||||
//
|
||||
// Wheel
|
||||
// Basic mouse weheel support for gallery navigation
|
||||
//
|
||||
// ==========================================================================
|
||||
(function (document, $) {
|
||||
"use strict";
|
||||
|
||||
var prevTime = new Date().getTime();
|
||||
|
||||
$(document).on({
|
||||
"onInit.fb": function (e, instance, current) {
|
||||
instance.$refs.stage.on("mousewheel DOMMouseScroll wheel MozMousePixelScroll", function (e) {
|
||||
var current = instance.current,
|
||||
currTime = new Date().getTime();
|
||||
|
||||
if (instance.group.length < 2 || current.opts.wheel === false || (current.opts.wheel === "auto" && current.type !== "image")) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
if (current.$slide.hasClass("fancybox-animated")) {
|
||||
return;
|
||||
}
|
||||
|
||||
e = e.originalEvent || e;
|
||||
|
||||
if (currTime - prevTime < 250) {
|
||||
return;
|
||||
}
|
||||
|
||||
prevTime = currTime;
|
||||
|
||||
instance[(-e.deltaY || -e.deltaX || e.wheelDelta || -e.detail) < 0 ? "next" : "previous"]();
|
||||
});
|
||||
}
|
||||
});
|
||||
})(document, jQuery);
|
||||
1
view/js/fancybox/jquery.fancybox.min.css
vendored
Normal file
1
view/js/fancybox/jquery.fancybox.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
13
view/js/fancybox/jquery.fancybox.min.js
vendored
Normal file
13
view/js/fancybox/jquery.fancybox.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
21
view/js/vanillaEmojiPicker/LICENSE
Normal file
21
view/js/vanillaEmojiPicker/LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2022 woody180
|
||||
|
||||
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.
|
||||
39
view/js/vanillaEmojiPicker/README.md
Normal file
39
view/js/vanillaEmojiPicker/README.md
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# FG Emoji Picker - Emoji picker created with vanilla javascript
|
||||
This is the simplest to use emoji picker built with vanilla javascript.
|
||||
|
||||

|
||||
|
||||
## Benefits:
|
||||
|
||||
- It is only one .js file without css or other files
|
||||
- There is no jQuery or other libraries
|
||||
- Simplicity of usage
|
||||
- Multiple textareas and triggers
|
||||
- Draggable emoji picker container
|
||||
|
||||
## Initialize
|
||||
|
||||
Initialze plugin with ```new EmojiPicker({});```
|
||||
|
||||
## Options
|
||||
|
||||
- Trigger - must be an array of objects. Inside object there are two properties. First is selector, and second - **insertInto** method to define where emoji going to be inserted. If there are multiple 'textarea's - you can provide array of selectors as well. Watch example below.
|
||||
- Close button - **closeButton** method can be true of false depending on whether you want close button on emoji picker or not.
|
||||
- specialButtons - takes color code to change special (move and close) button colors.
|
||||
|
||||
```
|
||||
new EmojiPicker({
|
||||
trigger: [
|
||||
{
|
||||
selector: '.first-btn',
|
||||
insertInto: ['.one', '.two'] // If there is only one '.selector', than it can be used without array
|
||||
},
|
||||
{
|
||||
selector: '.second-btn',
|
||||
insertInto: '.two'
|
||||
}
|
||||
],
|
||||
closeButton: true,
|
||||
specialButtons: 'green' // #008000, rgba(0, 128, 0);
|
||||
});
|
||||
```
|
||||
59
view/js/vanillaEmojiPicker/index.html
Normal file
59
view/js/vanillaEmojiPicker/index.html
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<!-- UIkit CSS -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.9.4/dist/css/uikit.min.css" />
|
||||
<!-- UIkit JS -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/uikit@3.9.4/dist/js/uikit.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/uikit@3.9.4/dist/js/uikit-icons.min.js"></script>
|
||||
<style>
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
<div class="uk-container uk-container-small uk-section">
|
||||
<div class="uk-margin-large">
|
||||
<textarea name="" class="one uk-textarea uk-margin uk-height-medium">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</textarea>
|
||||
<button class="first-btn uk-button uk-button-primary">Start picker</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<textarea name="" class="two uk-textarea uk-margin"></textarea>
|
||||
<button class="second-btn uk-button uk-button-primary">Start picker</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script src="vanillaEmojiPicker.js"></script>
|
||||
<script>
|
||||
|
||||
new EmojiPicker({
|
||||
trigger: [
|
||||
{
|
||||
selector: '.first-btn',
|
||||
insertInto: ['.one', '.two'] // '.selector' can be used without array
|
||||
},
|
||||
{
|
||||
selector: '.second-btn',
|
||||
insertInto: '.two'
|
||||
}
|
||||
],
|
||||
closeButton: true,
|
||||
//specialButtons: green
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
47
view/js/vanillaEmojiPicker/indextest.html
Normal file
47
view/js/vanillaEmojiPicker/indextest.html
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
<div>
|
||||
<textarea name="" class="two uk-textarea uk-margin"></textarea>
|
||||
</div>
|
||||
<div class="uk-container uk-container-small uk-section">
|
||||
<div>
|
||||
<button class="second-btn uk-button uk-button-primary">Start picker</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script src="vanillaEmojiPicker.js"></script>
|
||||
<script>
|
||||
|
||||
new EmojiPicker({
|
||||
trigger: [
|
||||
{
|
||||
selector: '.second-btn',
|
||||
insertInto: '.two'
|
||||
}
|
||||
],
|
||||
closeButton: true,
|
||||
//specialButtons: green
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
BIN
view/js/vanillaEmojiPicker/screenshot.png
Normal file
BIN
view/js/vanillaEmojiPicker/screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 68 KiB |
7948
view/js/vanillaEmojiPicker/vanillaEmojiPicker.js
Normal file
7948
view/js/vanillaEmojiPicker/vanillaEmojiPicker.js
Normal file
|
|
@ -0,0 +1,7948 @@
|
|||
const EmojiPicker = function(options) {
|
||||
|
||||
this.options = options;
|
||||
this.trigger = this.options.trigger.map(item => item.selector);
|
||||
this.insertInto = undefined;
|
||||
let emojiesHTML = '';
|
||||
let categoriesHTML = '';
|
||||
let emojiList = undefined;
|
||||
let moseMove = false;
|
||||
const pickerWidth = this.options.closeButton ? 370 : 350;
|
||||
const pickerHeight = 400;
|
||||
|
||||
this.lib = function(el = undefined) {
|
||||
|
||||
const isNodeList = (nodes) => {
|
||||
var stringRepr = Object.prototype.toString.call(nodes);
|
||||
|
||||
return typeof nodes === 'object' &&
|
||||
/^\[object (HTMLCollection|NodeList|Object)\]$/.test(stringRepr) &&
|
||||
(typeof nodes.length === 'number') &&
|
||||
(nodes.length === 0 || (typeof nodes[0] === "object" && nodes[0].nodeType > 0));
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
el: () => {
|
||||
// Check if is node
|
||||
if (!el) {
|
||||
return undefined;
|
||||
} else if (el.nodeName) {
|
||||
return [el];
|
||||
} else if (isNodeList(el)) {
|
||||
return Array.from(el)
|
||||
} else if (typeof(el) === 'string' || typeof(el) === 'STRING') {
|
||||
return Array.from(document.querySelectorAll(el));
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
|
||||
on(event, callback, classList = undefined) {
|
||||
if (!classList) {
|
||||
this.el().forEach(item => {
|
||||
item.addEventListener(event, callback.bind(item))
|
||||
})
|
||||
} else {
|
||||
this.el().forEach(item => {
|
||||
item.addEventListener(event, (e) => {
|
||||
if (e.target.closest(classList)) {
|
||||
|
||||
let attr = undefined;
|
||||
|
||||
if (Array.isArray(classList)) {
|
||||
const stringifiedElem = e.target.outerHTML;
|
||||
|
||||
const index = classList.findIndex(attr => stringifiedElem.includes(attr.slice(1)));
|
||||
|
||||
attr = classList[index];
|
||||
}
|
||||
|
||||
callback(e, attr)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
css(params) {
|
||||
for (const key in params) {
|
||||
if (Object.hasOwnProperty.call(params, key)) {
|
||||
const cssVal = params[key];
|
||||
this.el().forEach(el => el.style[key] = cssVal)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
attr(param1, param2 = undefined) {
|
||||
|
||||
if (!param2) {
|
||||
return this.el()[0].getAttribute(param1)
|
||||
}
|
||||
this.el().forEach(el => el.setAttribute(param1, param2))
|
||||
},
|
||||
|
||||
removeAttr(param) {
|
||||
this.el().forEach(el => el.removeAttribute(param))
|
||||
},
|
||||
|
||||
addClass(param) {
|
||||
this.el().forEach(el => el.classList.add(param))
|
||||
},
|
||||
|
||||
removeClass(param) {
|
||||
this.el().forEach(el => el.classList.remove(param))
|
||||
},
|
||||
|
||||
slug(str) {
|
||||
return str
|
||||
.toLowerCase()
|
||||
.replace(/[^\u00BF-\u1FFF\u2C00-\uD7FF\w]+|[\_]+/ig, '-')
|
||||
.replace(/ +/g,'-')
|
||||
;
|
||||
},
|
||||
|
||||
remove(param) {
|
||||
this.el().forEach(el => el.remove())
|
||||
},
|
||||
|
||||
val(param = undefined) {
|
||||
let val;
|
||||
|
||||
if (param === undefined) {
|
||||
this.el().forEach(el => {
|
||||
val = el.value;
|
||||
})
|
||||
} else {
|
||||
this.el().forEach(el => {
|
||||
el.value = param;
|
||||
})
|
||||
}
|
||||
|
||||
return val;
|
||||
},
|
||||
|
||||
text(msg = undefined) {
|
||||
if (msg === undefined) {
|
||||
return el.innerText;
|
||||
} else {
|
||||
this.el().forEach(el => {
|
||||
el.innerText = msg;
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
html(data = undefined) {
|
||||
if (data === undefined) {
|
||||
return el.innerHTML;
|
||||
} else {
|
||||
this.el().forEach(el => {
|
||||
el.innerHTML = data;
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const emojiObj = {
|
||||
'People': [
|
||||
{
|
||||
"emoji": "😀",
|
||||
"title": "Grinning Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😃",
|
||||
"title": "Grinning Face with Big Eyes"
|
||||
},
|
||||
{
|
||||
"emoji": "😄",
|
||||
"title": "Grinning Face with Smiling Eyes"
|
||||
},
|
||||
{
|
||||
"emoji": "😁",
|
||||
"title": "Beaming Face with Smiling Eyes"
|
||||
},
|
||||
{
|
||||
"emoji": "😆",
|
||||
"title": "Grinning Squinting Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😅",
|
||||
"title": "Grinning Face with Sweat"
|
||||
},
|
||||
{
|
||||
"emoji": "🤣",
|
||||
"title": "Rolling on the Floor Laughing"
|
||||
},
|
||||
{
|
||||
"emoji": "😂",
|
||||
"title": "Face with Tears of Joy"
|
||||
},
|
||||
{
|
||||
"emoji": "🙂",
|
||||
"title": "Slightly Smiling Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🙃",
|
||||
"title": "Upside-Down Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😉",
|
||||
"title": "Winking Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😊",
|
||||
"title": "Smiling Face with Smiling Eyes"
|
||||
},
|
||||
{
|
||||
"emoji": "😇",
|
||||
"title": "Smiling Face with Halo"
|
||||
},
|
||||
{
|
||||
"emoji": "🥰",
|
||||
"title": "Smiling Face with Hearts"
|
||||
},
|
||||
{
|
||||
"emoji": "😍",
|
||||
"title": "Smiling Face with Heart-Eyes"
|
||||
},
|
||||
{
|
||||
"emoji": "🤩",
|
||||
"title": "Star-Struck"
|
||||
},
|
||||
{
|
||||
"emoji": "😘",
|
||||
"title": "Face Blowing a Kiss"
|
||||
},
|
||||
{
|
||||
"emoji": "😗",
|
||||
"title": "Kissing Face"
|
||||
},
|
||||
{
|
||||
"emoji": "☺️",
|
||||
"title": "Smiling Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😚",
|
||||
"title": "Kissing Face with Closed Eyes"
|
||||
},
|
||||
{
|
||||
"emoji": "😙",
|
||||
"title": "Kissing Face with Smiling Eyes"
|
||||
},
|
||||
{
|
||||
"emoji": "🥲",
|
||||
"title": "Smiling Face with Tear"
|
||||
},
|
||||
{
|
||||
"emoji": "😋",
|
||||
"title": "Face Savoring Food"
|
||||
},
|
||||
{
|
||||
"emoji": "😛",
|
||||
"title": "Face with Tongue"
|
||||
},
|
||||
{
|
||||
"emoji": "😜",
|
||||
"title": "Winking Face with Tongue"
|
||||
},
|
||||
{
|
||||
"emoji": "🤪",
|
||||
"title": "Zany Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😝",
|
||||
"title": "Squinting Face with Tongue"
|
||||
},
|
||||
{
|
||||
"emoji": "🤑",
|
||||
"title": "Money-Mouth Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🤗",
|
||||
"title": "Smiling Face with Open Hands"
|
||||
},
|
||||
{
|
||||
"emoji": "🤭",
|
||||
"title": "Face with Hand Over Mouth"
|
||||
},
|
||||
{
|
||||
"emoji": "🤫",
|
||||
"title": "Shushing Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🤔",
|
||||
"title": "Thinking Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🤐",
|
||||
"title": "Zipper-Mouth Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🤨",
|
||||
"title": "Face with Raised Eyebrow"
|
||||
},
|
||||
{
|
||||
"emoji": "😐",
|
||||
"title": "Neutral Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😑",
|
||||
"title": "Expressionless Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😶",
|
||||
"title": "Face Without Mouth"
|
||||
},
|
||||
{
|
||||
"emoji": "😶🌫️",
|
||||
"title": "Face in Clouds"
|
||||
},
|
||||
{
|
||||
"emoji": "😏",
|
||||
"title": "Smirking Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😒",
|
||||
"title": "Unamused Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🙄",
|
||||
"title": "Face with Rolling Eyes"
|
||||
},
|
||||
{
|
||||
"emoji": "😬",
|
||||
"title": "Grimacing Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😮💨",
|
||||
"title": "Face Exhaling"
|
||||
},
|
||||
{
|
||||
"emoji": "🤥",
|
||||
"title": "Lying Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😌",
|
||||
"title": "Relieved Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😔",
|
||||
"title": "Pensive Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😪",
|
||||
"title": "Sleepy Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🤤",
|
||||
"title": "Drooling Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😴",
|
||||
"title": "Sleeping Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😷",
|
||||
"title": "Face with Medical Mask"
|
||||
},
|
||||
{
|
||||
"emoji": "🤒",
|
||||
"title": "Face with Thermometer"
|
||||
},
|
||||
{
|
||||
"emoji": "🤕",
|
||||
"title": "Face with Head-Bandage"
|
||||
},
|
||||
{
|
||||
"emoji": "🤢",
|
||||
"title": "Nauseated Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🤮",
|
||||
"title": "Face Vomiting"
|
||||
},
|
||||
{
|
||||
"emoji": "🤧",
|
||||
"title": "Sneezing Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🥵",
|
||||
"title": "Hot Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🥶",
|
||||
"title": "Cold Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🥴",
|
||||
"title": "Woozy Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😵",
|
||||
"title": "Face with Crossed-Out Eyes"
|
||||
},
|
||||
{
|
||||
"emoji": "😵💫",
|
||||
"title": "Face with Spiral Eyes"
|
||||
},
|
||||
{
|
||||
"emoji": "🤯",
|
||||
"title": "Exploding Head"
|
||||
},
|
||||
{
|
||||
"emoji": "🤠",
|
||||
"title": "Cowboy Hat Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🥳",
|
||||
"title": "Partying Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🥸",
|
||||
"title": "Disguised Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😎",
|
||||
"title": "Smiling Face with Sunglasses"
|
||||
},
|
||||
{
|
||||
"emoji": "🤓",
|
||||
"title": "Nerd Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🧐",
|
||||
"title": "Face with Monocle"
|
||||
},
|
||||
{
|
||||
"emoji": "😕",
|
||||
"title": "Confused Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😟",
|
||||
"title": "Worried Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🙁",
|
||||
"title": "Slightly Frowning Face"
|
||||
},
|
||||
{
|
||||
"emoji": "☹️",
|
||||
"title": "Frowning Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😮",
|
||||
"title": "Face with Open Mouth"
|
||||
},
|
||||
{
|
||||
"emoji": "😯",
|
||||
"title": "Hushed Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😲",
|
||||
"title": "Astonished Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😳",
|
||||
"title": "Flushed Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🥺",
|
||||
"title": "Pleading Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😦",
|
||||
"title": "Frowning Face with Open Mouth"
|
||||
},
|
||||
{
|
||||
"emoji": "😧",
|
||||
"title": "Anguished Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😨",
|
||||
"title": "Fearful Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😰",
|
||||
"title": "Anxious Face with Sweat"
|
||||
},
|
||||
{
|
||||
"emoji": "😥",
|
||||
"title": "Sad but Relieved Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😢",
|
||||
"title": "Crying Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😭",
|
||||
"title": "Loudly Crying Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😱",
|
||||
"title": "Face Screaming in Fear"
|
||||
},
|
||||
{
|
||||
"emoji": "😖",
|
||||
"title": "Confounded Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😣",
|
||||
"title": "Persevering Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😞",
|
||||
"title": "Disappointed Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😓",
|
||||
"title": "Downcast Face with Sweat"
|
||||
},
|
||||
{
|
||||
"emoji": "😩",
|
||||
"title": "Weary Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😫",
|
||||
"title": "Tired Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🥱",
|
||||
"title": "Yawning Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😤",
|
||||
"title": "Face with Steam From Nose"
|
||||
},
|
||||
{
|
||||
"emoji": "😡",
|
||||
"title": "Enraged Face"
|
||||
},
|
||||
{
|
||||
"emoji": "😠",
|
||||
"title": "Angry Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🤬",
|
||||
"title": "Face with Symbols on Mouth"
|
||||
},
|
||||
{
|
||||
"emoji": "😈",
|
||||
"title": "Smiling Face with Horns"
|
||||
},
|
||||
{
|
||||
"emoji": "👿",
|
||||
"title": "Angry Face with Horns"
|
||||
},
|
||||
{
|
||||
"emoji": "💀",
|
||||
"title": "Skull"
|
||||
},
|
||||
{
|
||||
"emoji": "☠️",
|
||||
"title": "Skull and Crossbones"
|
||||
},
|
||||
{
|
||||
"emoji": "💩",
|
||||
"title": "Pile of Poo"
|
||||
},
|
||||
{
|
||||
"emoji": "🤡",
|
||||
"title": "Clown Face"
|
||||
},
|
||||
{
|
||||
"emoji": "👹",
|
||||
"title": "Ogre"
|
||||
},
|
||||
{
|
||||
"emoji": "👺",
|
||||
"title": "Goblin"
|
||||
},
|
||||
{
|
||||
"emoji": "👻",
|
||||
"title": "Ghost"
|
||||
},
|
||||
{
|
||||
"emoji": "👽",
|
||||
"title": "Alien"
|
||||
},
|
||||
{
|
||||
"emoji": "👾",
|
||||
"title": "Alien Monster"
|
||||
},
|
||||
{
|
||||
"emoji": "🤖",
|
||||
"title": "Robot"
|
||||
},
|
||||
{
|
||||
"emoji": "😺",
|
||||
"title": "Grinning Cat"
|
||||
},
|
||||
{
|
||||
"emoji": "😸",
|
||||
"title": "Grinning Cat with Smiling Eyes"
|
||||
},
|
||||
{
|
||||
"emoji": "😹",
|
||||
"title": "Cat with Tears of Joy"
|
||||
},
|
||||
{
|
||||
"emoji": "😻",
|
||||
"title": "Smiling Cat with Heart-Eyes"
|
||||
},
|
||||
{
|
||||
"emoji": "😼",
|
||||
"title": "Cat with Wry Smile"
|
||||
},
|
||||
{
|
||||
"emoji": "😽",
|
||||
"title": "Kissing Cat"
|
||||
},
|
||||
{
|
||||
"emoji": "🙀",
|
||||
"title": "Weary Cat"
|
||||
},
|
||||
{
|
||||
"emoji": "😿",
|
||||
"title": "Crying Cat"
|
||||
},
|
||||
{
|
||||
"emoji": "😾",
|
||||
"title": "Pouting Cat"
|
||||
},
|
||||
{
|
||||
"emoji": "💋",
|
||||
"title": "Kiss Mark"
|
||||
},
|
||||
{
|
||||
"emoji": "👋",
|
||||
"title": "Waving Hand"
|
||||
},
|
||||
{
|
||||
"emoji": "🤚",
|
||||
"title": "Raised Back of Hand"
|
||||
},
|
||||
{
|
||||
"emoji": "🖐️",
|
||||
"title": "Hand with Fingers Splayed"
|
||||
},
|
||||
{
|
||||
"emoji": "✋",
|
||||
"title": "Raised Hand"
|
||||
},
|
||||
{
|
||||
"emoji": "🖖",
|
||||
"title": "Vulcan Salute"
|
||||
},
|
||||
{
|
||||
"emoji": "👌",
|
||||
"title": "OK Hand"
|
||||
},
|
||||
{
|
||||
"emoji": "🤌",
|
||||
"title": "Pinched Fingers"
|
||||
},
|
||||
{
|
||||
"emoji": "🤏",
|
||||
"title": "Pinching Hand"
|
||||
},
|
||||
{
|
||||
"emoji": "✌️",
|
||||
"title": "Victory Hand"
|
||||
},
|
||||
{
|
||||
"emoji": "🤞",
|
||||
"title": "Crossed Fingers"
|
||||
},
|
||||
{
|
||||
"emoji": "🤟",
|
||||
"title": "Love-You Gesture"
|
||||
},
|
||||
{
|
||||
"emoji": "🤘",
|
||||
"title": "Sign of the Horns"
|
||||
},
|
||||
{
|
||||
"emoji": "🤙",
|
||||
"title": "Call Me Hand"
|
||||
},
|
||||
{
|
||||
"emoji": "👈",
|
||||
"title": "Backhand Index Pointing Left"
|
||||
},
|
||||
{
|
||||
"emoji": "👉",
|
||||
"title": "Backhand Index Pointing Right"
|
||||
},
|
||||
{
|
||||
"emoji": "👆",
|
||||
"title": "Backhand Index Pointing Up"
|
||||
},
|
||||
{
|
||||
"emoji": "🖕",
|
||||
"title": "Middle Finger"
|
||||
},
|
||||
{
|
||||
"emoji": "👇",
|
||||
"title": "Backhand Index Pointing Down"
|
||||
},
|
||||
{
|
||||
"emoji": "☝️",
|
||||
"title": "Index Pointing Up"
|
||||
},
|
||||
{
|
||||
"emoji": "👍",
|
||||
"title": "Thumbs Up"
|
||||
},
|
||||
{
|
||||
"emoji": "👎",
|
||||
"title": "Thumbs Down"
|
||||
},
|
||||
{
|
||||
"emoji": "✊",
|
||||
"title": "Raised Fist"
|
||||
},
|
||||
{
|
||||
"emoji": "👊",
|
||||
"title": "Oncoming Fist"
|
||||
},
|
||||
{
|
||||
"emoji": "🤛",
|
||||
"title": "Left-Facing Fist"
|
||||
},
|
||||
{
|
||||
"emoji": "🤜",
|
||||
"title": "Right-Facing Fist"
|
||||
},
|
||||
{
|
||||
"emoji": "👏",
|
||||
"title": "Clapping Hands"
|
||||
},
|
||||
{
|
||||
"emoji": "🙌",
|
||||
"title": "Raising Hands"
|
||||
},
|
||||
{
|
||||
"emoji": "👐",
|
||||
"title": "Open Hands"
|
||||
},
|
||||
{
|
||||
"emoji": "🤲",
|
||||
"title": "Palms Up Together"
|
||||
},
|
||||
{
|
||||
"emoji": "🤝",
|
||||
"title": "Handshake"
|
||||
},
|
||||
{
|
||||
"emoji": "🙏",
|
||||
"title": "Folded Hands"
|
||||
},
|
||||
{
|
||||
"emoji": "✍️",
|
||||
"title": "Writing Hand"
|
||||
},
|
||||
{
|
||||
"emoji": "💅",
|
||||
"title": "Nail Polish"
|
||||
},
|
||||
{
|
||||
"emoji": "🤳",
|
||||
"title": "Selfie"
|
||||
},
|
||||
{
|
||||
"emoji": "💪",
|
||||
"title": "Flexed Biceps"
|
||||
},
|
||||
{
|
||||
"emoji": "🦾",
|
||||
"title": "Mechanical Arm"
|
||||
},
|
||||
{
|
||||
"emoji": "🦿",
|
||||
"title": "Mechanical Leg"
|
||||
},
|
||||
{
|
||||
"emoji": "🦵",
|
||||
"title": "Leg"
|
||||
},
|
||||
{
|
||||
"emoji": "🦶",
|
||||
"title": "Foot"
|
||||
},
|
||||
{
|
||||
"emoji": "👂",
|
||||
"title": "Ear"
|
||||
},
|
||||
{
|
||||
"emoji": "🦻",
|
||||
"title": "Ear with Hearing Aid"
|
||||
},
|
||||
{
|
||||
"emoji": "👃",
|
||||
"title": "Nose"
|
||||
},
|
||||
{
|
||||
"emoji": "🧠",
|
||||
"title": "Brain"
|
||||
},
|
||||
{
|
||||
"emoji": "🫀",
|
||||
"title": "Anatomical Heart"
|
||||
},
|
||||
{
|
||||
"emoji": "🫁",
|
||||
"title": "Lungs"
|
||||
},
|
||||
{
|
||||
"emoji": "🦷",
|
||||
"title": "Tooth"
|
||||
},
|
||||
{
|
||||
"emoji": "🦴",
|
||||
"title": "Bone"
|
||||
},
|
||||
{
|
||||
"emoji": "👀",
|
||||
"title": "Eyes"
|
||||
},
|
||||
{
|
||||
"emoji": "👁️",
|
||||
"title": "Eye"
|
||||
},
|
||||
{
|
||||
"emoji": "👅",
|
||||
"title": "Tongue"
|
||||
},
|
||||
{
|
||||
"emoji": "👄",
|
||||
"title": "Mouth"
|
||||
},
|
||||
{
|
||||
"emoji": "👶",
|
||||
"title": "Baby"
|
||||
},
|
||||
{
|
||||
"emoji": "🧒",
|
||||
"title": "Child"
|
||||
},
|
||||
{
|
||||
"emoji": "👦",
|
||||
"title": "Boy"
|
||||
},
|
||||
{
|
||||
"emoji": "👧",
|
||||
"title": "Girl"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑",
|
||||
"title": "Person"
|
||||
},
|
||||
{
|
||||
"emoji": "👱",
|
||||
"title": "Person: Blond Hair"
|
||||
},
|
||||
{
|
||||
"emoji": "👨",
|
||||
"title": "Man"
|
||||
},
|
||||
{
|
||||
"emoji": "🧔",
|
||||
"title": "Person: Beard"
|
||||
},
|
||||
{
|
||||
"emoji": "👨🦰",
|
||||
"title": "Man: Red Hair"
|
||||
},
|
||||
{
|
||||
"emoji": "👨🦱",
|
||||
"title": "Man: Curly Hair"
|
||||
},
|
||||
{
|
||||
"emoji": "👨🦳",
|
||||
"title": "Man: White Hair"
|
||||
},
|
||||
{
|
||||
"emoji": "👨🦲",
|
||||
"title": "Man: Bald"
|
||||
},
|
||||
{
|
||||
"emoji": "👩",
|
||||
"title": "Woman"
|
||||
},
|
||||
{
|
||||
"emoji": "👩🦰",
|
||||
"title": "Woman: Red Hair"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🦰",
|
||||
"title": "Person: Red Hair"
|
||||
},
|
||||
{
|
||||
"emoji": "👩🦱",
|
||||
"title": "Woman: Curly Hair"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🦱",
|
||||
"title": "Person: Curly Hair"
|
||||
},
|
||||
{
|
||||
"emoji": "👩🦳",
|
||||
"title": "Woman: White Hair"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🦳",
|
||||
"title": "Person: White Hair"
|
||||
},
|
||||
{
|
||||
"emoji": "👩🦲",
|
||||
"title": "Woman: Bald"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🦲",
|
||||
"title": "Person: Bald"
|
||||
},
|
||||
{
|
||||
"emoji": "👱♀️",
|
||||
"title": "Woman: Blond Hair"
|
||||
},
|
||||
{
|
||||
"emoji": "👱♂️",
|
||||
"title": "Man: Blond Hair"
|
||||
},
|
||||
{
|
||||
"emoji": "🧓",
|
||||
"title": "Older Person"
|
||||
},
|
||||
{
|
||||
"emoji": "👴",
|
||||
"title": "Old Man"
|
||||
},
|
||||
{
|
||||
"emoji": "👵",
|
||||
"title": "Old Woman"
|
||||
},
|
||||
{
|
||||
"emoji": "🙍",
|
||||
"title": "Person Frowning"
|
||||
},
|
||||
{
|
||||
"emoji": "🙍♂️",
|
||||
"title": "Man Frowning"
|
||||
},
|
||||
{
|
||||
"emoji": "🙍♀️",
|
||||
"title": "Woman Frowning"
|
||||
},
|
||||
{
|
||||
"emoji": "🙎",
|
||||
"title": "Person Pouting"
|
||||
},
|
||||
{
|
||||
"emoji": "🙎♂️",
|
||||
"title": "Man Pouting"
|
||||
},
|
||||
{
|
||||
"emoji": "🙎♀️",
|
||||
"title": "Woman Pouting"
|
||||
},
|
||||
{
|
||||
"emoji": "🙅",
|
||||
"title": "Person Gesturing No"
|
||||
},
|
||||
{
|
||||
"emoji": "🙅♂️",
|
||||
"title": "Man Gesturing No"
|
||||
},
|
||||
{
|
||||
"emoji": "🙅♀️",
|
||||
"title": "Woman Gesturing No"
|
||||
},
|
||||
{
|
||||
"emoji": "🙆",
|
||||
"title": "Person Gesturing OK"
|
||||
},
|
||||
{
|
||||
"emoji": "🙆♂️",
|
||||
"title": "Man Gesturing OK"
|
||||
},
|
||||
{
|
||||
"emoji": "🙆♀️",
|
||||
"title": "Woman Gesturing OK"
|
||||
},
|
||||
{
|
||||
"emoji": "💁",
|
||||
"title": "Person Tipping Hand"
|
||||
},
|
||||
{
|
||||
"emoji": "💁♂️",
|
||||
"title": "Man Tipping Hand"
|
||||
},
|
||||
{
|
||||
"emoji": "💁♀️",
|
||||
"title": "Woman Tipping Hand"
|
||||
},
|
||||
{
|
||||
"emoji": "🙋",
|
||||
"title": "Person Raising Hand"
|
||||
},
|
||||
{
|
||||
"emoji": "🙋♂️",
|
||||
"title": "Man Raising Hand"
|
||||
},
|
||||
{
|
||||
"emoji": "🙋♀️",
|
||||
"title": "Woman Raising Hand"
|
||||
},
|
||||
{
|
||||
"emoji": "🧏",
|
||||
"title": "Deaf Person"
|
||||
},
|
||||
{
|
||||
"emoji": "🧏♂️",
|
||||
"title": "Deaf Man"
|
||||
},
|
||||
{
|
||||
"emoji": "🧏♀️",
|
||||
"title": "Deaf Woman"
|
||||
},
|
||||
{
|
||||
"emoji": "🙇",
|
||||
"title": "Person Bowing"
|
||||
},
|
||||
{
|
||||
"emoji": "🙇♂️",
|
||||
"title": "Man Bowing"
|
||||
},
|
||||
{
|
||||
"emoji": "🙇♀️",
|
||||
"title": "Woman Bowing"
|
||||
},
|
||||
{
|
||||
"emoji": "🤦",
|
||||
"title": "Person Facepalming"
|
||||
},
|
||||
{
|
||||
"emoji": "🤦♂️",
|
||||
"title": "Man Facepalming"
|
||||
},
|
||||
{
|
||||
"emoji": "🤦♀️",
|
||||
"title": "Woman Facepalming"
|
||||
},
|
||||
{
|
||||
"emoji": "🤷",
|
||||
"title": "Person Shrugging"
|
||||
},
|
||||
{
|
||||
"emoji": "🤷♂️",
|
||||
"title": "Man Shrugging"
|
||||
},
|
||||
{
|
||||
"emoji": "🤷♀️",
|
||||
"title": "Woman Shrugging"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑⚕️",
|
||||
"title": "Health Worker"
|
||||
},
|
||||
{
|
||||
"emoji": "👨⚕️",
|
||||
"title": "Man Health Worker"
|
||||
},
|
||||
{
|
||||
"emoji": "👩⚕️",
|
||||
"title": "Woman Health Worker"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🎓",
|
||||
"title": "Student"
|
||||
},
|
||||
{
|
||||
"emoji": "👨🎓",
|
||||
"title": "Man Student"
|
||||
},
|
||||
{
|
||||
"emoji": "👩🎓",
|
||||
"title": "Woman Student"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🏫",
|
||||
"title": "Teacher"
|
||||
},
|
||||
{
|
||||
"emoji": "👨🏫",
|
||||
"title": "Man Teacher"
|
||||
},
|
||||
{
|
||||
"emoji": "👩🏫",
|
||||
"title": "Woman Teacher"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑⚖️",
|
||||
"title": "Judge"
|
||||
},
|
||||
{
|
||||
"emoji": "👨⚖️",
|
||||
"title": "Man Judge"
|
||||
},
|
||||
{
|
||||
"emoji": "👩⚖️",
|
||||
"title": "Woman Judge"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🌾",
|
||||
"title": "Farmer"
|
||||
},
|
||||
{
|
||||
"emoji": "👨🌾",
|
||||
"title": "Man Farmer"
|
||||
},
|
||||
{
|
||||
"emoji": "👩🌾",
|
||||
"title": "Woman Farmer"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🍳",
|
||||
"title": "Cook"
|
||||
},
|
||||
{
|
||||
"emoji": "👨🍳",
|
||||
"title": "Man Cook"
|
||||
},
|
||||
{
|
||||
"emoji": "👩🍳",
|
||||
"title": "Woman Cook"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🔧",
|
||||
"title": "Mechanic"
|
||||
},
|
||||
{
|
||||
"emoji": "👨🔧",
|
||||
"title": "Man Mechanic"
|
||||
},
|
||||
{
|
||||
"emoji": "👩🔧",
|
||||
"title": "Woman Mechanic"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🏭",
|
||||
"title": "Factory Worker"
|
||||
},
|
||||
{
|
||||
"emoji": "👨🏭",
|
||||
"title": "Man Factory Worker"
|
||||
},
|
||||
{
|
||||
"emoji": "👩🏭",
|
||||
"title": "Woman Factory Worker"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑💼",
|
||||
"title": "Office Worker"
|
||||
},
|
||||
{
|
||||
"emoji": "👨💼",
|
||||
"title": "Man Office Worker"
|
||||
},
|
||||
{
|
||||
"emoji": "👩💼",
|
||||
"title": "Woman Office Worker"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🔬",
|
||||
"title": "Scientist"
|
||||
},
|
||||
{
|
||||
"emoji": "👨🔬",
|
||||
"title": "Man Scientist"
|
||||
},
|
||||
{
|
||||
"emoji": "👩🔬",
|
||||
"title": "Woman Scientist"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑💻",
|
||||
"title": "Technologist"
|
||||
},
|
||||
{
|
||||
"emoji": "👨💻",
|
||||
"title": "Man Technologist"
|
||||
},
|
||||
{
|
||||
"emoji": "👩💻",
|
||||
"title": "Woman Technologist"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🎤",
|
||||
"title": "Singer"
|
||||
},
|
||||
{
|
||||
"emoji": "👨🎤",
|
||||
"title": "Man Singer"
|
||||
},
|
||||
{
|
||||
"emoji": "👩🎤",
|
||||
"title": "Woman Singer"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🎨",
|
||||
"title": "Artist"
|
||||
},
|
||||
{
|
||||
"emoji": "👨🎨",
|
||||
"title": "Man Artist"
|
||||
},
|
||||
{
|
||||
"emoji": "👩🎨",
|
||||
"title": "Woman Artist"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑✈️",
|
||||
"title": "Pilot"
|
||||
},
|
||||
{
|
||||
"emoji": "👨✈️",
|
||||
"title": "Man Pilot"
|
||||
},
|
||||
{
|
||||
"emoji": "👩✈️",
|
||||
"title": "Woman Pilot"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🚀",
|
||||
"title": "Astronaut"
|
||||
},
|
||||
{
|
||||
"emoji": "👨🚀",
|
||||
"title": "Man Astronaut"
|
||||
},
|
||||
{
|
||||
"emoji": "👩🚀",
|
||||
"title": "Woman Astronaut"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🚒",
|
||||
"title": "Firefighter"
|
||||
},
|
||||
{
|
||||
"emoji": "👨🚒",
|
||||
"title": "Man Firefighter"
|
||||
},
|
||||
{
|
||||
"emoji": "👩🚒",
|
||||
"title": "Woman Firefighter"
|
||||
},
|
||||
{
|
||||
"emoji": "👮",
|
||||
"title": "Police Officer"
|
||||
},
|
||||
{
|
||||
"emoji": "👮♂️",
|
||||
"title": "Man Police Officer"
|
||||
},
|
||||
{
|
||||
"emoji": "👮♀️",
|
||||
"title": "Woman Police Officer"
|
||||
},
|
||||
{
|
||||
"emoji": "🕵️",
|
||||
"title": "Detective"
|
||||
},
|
||||
{
|
||||
"emoji": "🕵️♂️",
|
||||
"title": "Man Detective"
|
||||
},
|
||||
{
|
||||
"emoji": "🕵️♀️",
|
||||
"title": "Woman Detective"
|
||||
},
|
||||
{
|
||||
"emoji": "💂",
|
||||
"title": "Guard"
|
||||
},
|
||||
{
|
||||
"emoji": "💂♂️",
|
||||
"title": "Man Guard"
|
||||
},
|
||||
{
|
||||
"emoji": "💂♀️",
|
||||
"title": "Woman Guard"
|
||||
},
|
||||
{
|
||||
"emoji": "🥷",
|
||||
"title": "Ninja"
|
||||
},
|
||||
{
|
||||
"emoji": "👷",
|
||||
"title": "Construction Worker"
|
||||
},
|
||||
{
|
||||
"emoji": "👷♂️",
|
||||
"title": "Man Construction Worker"
|
||||
},
|
||||
{
|
||||
"emoji": "👷♀️",
|
||||
"title": "Woman Construction Worker"
|
||||
},
|
||||
{
|
||||
"emoji": "🤴",
|
||||
"title": "Prince"
|
||||
},
|
||||
{
|
||||
"emoji": "👸",
|
||||
"title": "Princess"
|
||||
},
|
||||
{
|
||||
"emoji": "👳",
|
||||
"title": "Person Wearing Turban"
|
||||
},
|
||||
{
|
||||
"emoji": "👳♂️",
|
||||
"title": "Man Wearing Turban"
|
||||
},
|
||||
{
|
||||
"emoji": "👳♀️",
|
||||
"title": "Woman Wearing Turban"
|
||||
},
|
||||
{
|
||||
"emoji": "👲",
|
||||
"title": "Person with Skullcap"
|
||||
},
|
||||
{
|
||||
"emoji": "🧕",
|
||||
"title": "Woman with Headscarf"
|
||||
},
|
||||
{
|
||||
"emoji": "🤵",
|
||||
"title": "Person in Tuxedo"
|
||||
},
|
||||
{
|
||||
"emoji": "🤵♂️",
|
||||
"title": "Man in Tuxedo"
|
||||
},
|
||||
{
|
||||
"emoji": "🤵♀️",
|
||||
"title": "Woman in Tuxedo"
|
||||
},
|
||||
{
|
||||
"emoji": "👰",
|
||||
"title": "Person with Veil"
|
||||
},
|
||||
{
|
||||
"emoji": "👰♂️",
|
||||
"title": "Man with Veil"
|
||||
},
|
||||
{
|
||||
"emoji": "👰♀️",
|
||||
"title": "Woman with Veil"
|
||||
},
|
||||
{
|
||||
"emoji": "🤰",
|
||||
"title": "Pregnant Woman"
|
||||
},
|
||||
{
|
||||
"emoji": "🤱",
|
||||
"title": "Breast-Feeding"
|
||||
},
|
||||
{
|
||||
"emoji": "👩🍼",
|
||||
"title": "Woman Feeding Baby"
|
||||
},
|
||||
{
|
||||
"emoji": "👨🍼",
|
||||
"title": "Man Feeding Baby"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🍼",
|
||||
"title": "Person Feeding Baby"
|
||||
},
|
||||
{
|
||||
"emoji": "👼",
|
||||
"title": "Baby Angel"
|
||||
},
|
||||
{
|
||||
"emoji": "🎅",
|
||||
"title": "Santa Claus"
|
||||
},
|
||||
{
|
||||
"emoji": "🤶",
|
||||
"title": "Mrs. Claus"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🎄",
|
||||
"title": "Mx Claus"
|
||||
},
|
||||
{
|
||||
"emoji": "🦸",
|
||||
"title": "Superhero"
|
||||
},
|
||||
{
|
||||
"emoji": "🦸♂️",
|
||||
"title": "Man Superhero"
|
||||
},
|
||||
{
|
||||
"emoji": "🦸♀️",
|
||||
"title": "Woman Superhero"
|
||||
},
|
||||
{
|
||||
"emoji": "🦹",
|
||||
"title": "Supervillain"
|
||||
},
|
||||
{
|
||||
"emoji": "🦹♂️",
|
||||
"title": "Man Supervillain"
|
||||
},
|
||||
{
|
||||
"emoji": "🦹♀️",
|
||||
"title": "Woman Supervillain"
|
||||
},
|
||||
{
|
||||
"emoji": "🧙",
|
||||
"title": "Mage"
|
||||
},
|
||||
{
|
||||
"emoji": "🧙♂️",
|
||||
"title": "Man Mage"
|
||||
},
|
||||
{
|
||||
"emoji": "🧙♀️",
|
||||
"title": "Woman Mage"
|
||||
},
|
||||
{
|
||||
"emoji": "🧚",
|
||||
"title": "Fairy"
|
||||
},
|
||||
{
|
||||
"emoji": "🧚♂️",
|
||||
"title": "Man Fairy"
|
||||
},
|
||||
{
|
||||
"emoji": "🧚♀️",
|
||||
"title": "Woman Fairy"
|
||||
},
|
||||
{
|
||||
"emoji": "🧛",
|
||||
"title": "Vampire"
|
||||
},
|
||||
{
|
||||
"emoji": "🧛♂️",
|
||||
"title": "Man Vampire"
|
||||
},
|
||||
{
|
||||
"emoji": "🧛♀️",
|
||||
"title": "Woman Vampire"
|
||||
},
|
||||
{
|
||||
"emoji": "🧜",
|
||||
"title": "Merperson"
|
||||
},
|
||||
{
|
||||
"emoji": "🧜♂️",
|
||||
"title": "Merman"
|
||||
},
|
||||
{
|
||||
"emoji": "🧜♀️",
|
||||
"title": "Mermaid"
|
||||
},
|
||||
{
|
||||
"emoji": "🧝",
|
||||
"title": "Elf"
|
||||
},
|
||||
{
|
||||
"emoji": "🧝♂️",
|
||||
"title": "Man Elf"
|
||||
},
|
||||
{
|
||||
"emoji": "🧝♀️",
|
||||
"title": "Woman Elf"
|
||||
},
|
||||
{
|
||||
"emoji": "🧞",
|
||||
"title": "Genie"
|
||||
},
|
||||
{
|
||||
"emoji": "🧞♂️",
|
||||
"title": "Man Genie"
|
||||
},
|
||||
{
|
||||
"emoji": "🧞♀️",
|
||||
"title": "Woman Genie"
|
||||
},
|
||||
{
|
||||
"emoji": "🧟",
|
||||
"title": "Zombie"
|
||||
},
|
||||
{
|
||||
"emoji": "🧟♂️",
|
||||
"title": "Man Zombie"
|
||||
},
|
||||
{
|
||||
"emoji": "🧟♀️",
|
||||
"title": "Woman Zombie"
|
||||
},
|
||||
{
|
||||
"emoji": "💆",
|
||||
"title": "Person Getting Massage"
|
||||
},
|
||||
{
|
||||
"emoji": "💆♂️",
|
||||
"title": "Man Getting Massage"
|
||||
},
|
||||
{
|
||||
"emoji": "💆♀️",
|
||||
"title": "Woman Getting Massage"
|
||||
},
|
||||
{
|
||||
"emoji": "💇",
|
||||
"title": "Person Getting Haircut"
|
||||
},
|
||||
{
|
||||
"emoji": "💇♂️",
|
||||
"title": "Man Getting Haircut"
|
||||
},
|
||||
{
|
||||
"emoji": "💇♀️",
|
||||
"title": "Woman Getting Haircut"
|
||||
},
|
||||
{
|
||||
"emoji": "🚶",
|
||||
"title": "Person Walking"
|
||||
},
|
||||
{
|
||||
"emoji": "🚶♂️",
|
||||
"title": "Man Walking"
|
||||
},
|
||||
{
|
||||
"emoji": "🚶♀️",
|
||||
"title": "Woman Walking"
|
||||
},
|
||||
{
|
||||
"emoji": "🧍",
|
||||
"title": "Person Standing"
|
||||
},
|
||||
{
|
||||
"emoji": "🧍♂️",
|
||||
"title": "Man Standing"
|
||||
},
|
||||
{
|
||||
"emoji": "🧍♀️",
|
||||
"title": "Woman Standing"
|
||||
},
|
||||
{
|
||||
"emoji": "🧎",
|
||||
"title": "Person Kneeling"
|
||||
},
|
||||
{
|
||||
"emoji": "🧎♂️",
|
||||
"title": "Man Kneeling"
|
||||
},
|
||||
{
|
||||
"emoji": "🧎♀️",
|
||||
"title": "Woman Kneeling"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🦯",
|
||||
"title": "Person with White Cane"
|
||||
},
|
||||
{
|
||||
"emoji": "👨🦯",
|
||||
"title": "Man with White Cane"
|
||||
},
|
||||
{
|
||||
"emoji": "👩🦯",
|
||||
"title": "Woman with White Cane"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🦼",
|
||||
"title": "Person in Motorized Wheelchair"
|
||||
},
|
||||
{
|
||||
"emoji": "👨🦼",
|
||||
"title": "Man in Motorized Wheelchair"
|
||||
},
|
||||
{
|
||||
"emoji": "👩🦼",
|
||||
"title": "Woman in Motorized Wheelchair"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🦽",
|
||||
"title": "Person in Manual Wheelchair"
|
||||
},
|
||||
{
|
||||
"emoji": "👨🦽",
|
||||
"title": "Man in Manual Wheelchair"
|
||||
},
|
||||
{
|
||||
"emoji": "👩🦽",
|
||||
"title": "Woman in Manual Wheelchair"
|
||||
},
|
||||
{
|
||||
"emoji": "🏃",
|
||||
"title": "Person Running"
|
||||
},
|
||||
{
|
||||
"emoji": "🏃♂️",
|
||||
"title": "Man Running"
|
||||
},
|
||||
{
|
||||
"emoji": "🏃♀️",
|
||||
"title": "Woman Running"
|
||||
},
|
||||
{
|
||||
"emoji": "💃",
|
||||
"title": "Woman Dancing"
|
||||
},
|
||||
{
|
||||
"emoji": "🕺",
|
||||
"title": "Man Dancing"
|
||||
},
|
||||
{
|
||||
"emoji": "🕴️",
|
||||
"title": "Person in Suit Levitating"
|
||||
},
|
||||
{
|
||||
"emoji": "👯",
|
||||
"title": "People with Bunny Ears"
|
||||
},
|
||||
{
|
||||
"emoji": "👯♂️",
|
||||
"title": "Men with Bunny Ears"
|
||||
},
|
||||
{
|
||||
"emoji": "👯♀️",
|
||||
"title": "Women with Bunny Ears"
|
||||
},
|
||||
{
|
||||
"emoji": "🧖",
|
||||
"title": "Person in Steamy Room"
|
||||
},
|
||||
{
|
||||
"emoji": "🧖♂️",
|
||||
"title": "Man in Steamy Room"
|
||||
},
|
||||
{
|
||||
"emoji": "🧖♀️",
|
||||
"title": "Woman in Steamy Room"
|
||||
},
|
||||
{
|
||||
"emoji": "🧘",
|
||||
"title": "Person in Lotus Position"
|
||||
},
|
||||
{
|
||||
"emoji": "🧑🤝🧑",
|
||||
"title": "People Holding Hands"
|
||||
},
|
||||
{
|
||||
"emoji": "👭",
|
||||
"title": "Women Holding Hands"
|
||||
},
|
||||
{
|
||||
"emoji": "👫",
|
||||
"title": "Woman and Man Holding Hands"
|
||||
},
|
||||
{
|
||||
"emoji": "👬",
|
||||
"title": "Men Holding Hands"
|
||||
},
|
||||
{
|
||||
"emoji": "💏",
|
||||
"title": "Kiss"
|
||||
},
|
||||
{
|
||||
"emoji": "👩❤️💋👨",
|
||||
"title": "Kiss: Woman, Man"
|
||||
},
|
||||
{
|
||||
"emoji": "👨❤️💋👨",
|
||||
"title": "Kiss: Man, Man"
|
||||
},
|
||||
{
|
||||
"emoji": "👩❤️💋👩",
|
||||
"title": "Kiss: Woman, Woman"
|
||||
},
|
||||
{
|
||||
"emoji": "💑",
|
||||
"title": "Couple with Heart"
|
||||
},
|
||||
{
|
||||
"emoji": "👩❤️👨",
|
||||
"title": "Couple with Heart: Woman, Man"
|
||||
},
|
||||
{
|
||||
"emoji": "👨❤️👨",
|
||||
"title": "Couple with Heart: Man, Man"
|
||||
},
|
||||
{
|
||||
"emoji": "👩❤️👩",
|
||||
"title": "Couple with Heart: Woman, Woman"
|
||||
},
|
||||
{
|
||||
"emoji": "👪",
|
||||
"title": "Family"
|
||||
},
|
||||
{
|
||||
"emoji": "👨👩👦",
|
||||
"title": "Family: Man, Woman, Boy"
|
||||
},
|
||||
{
|
||||
"emoji": "👨👩👧",
|
||||
"title": "Family: Man, Woman, Girl"
|
||||
},
|
||||
{
|
||||
"emoji": "👨👩👧👦",
|
||||
"title": "Family: Man, Woman, Girl, Boy"
|
||||
},
|
||||
{
|
||||
"emoji": "👨👩👦👦",
|
||||
"title": "Family: Man, Woman, Boy, Boy"
|
||||
},
|
||||
{
|
||||
"emoji": "👨👩👧👧",
|
||||
"title": "Family: Man, Woman, Girl, Girl"
|
||||
},
|
||||
{
|
||||
"emoji": "👨👨👦",
|
||||
"title": "Family: Man, Man, Boy"
|
||||
},
|
||||
{
|
||||
"emoji": "👨👨👧",
|
||||
"title": "Family: Man, Man, Girl"
|
||||
},
|
||||
{
|
||||
"emoji": "👨👨👧👦",
|
||||
"title": "Family: Man, Man, Girl, Boy"
|
||||
},
|
||||
{
|
||||
"emoji": "👨👨👦👦",
|
||||
"title": "Family: Man, Man, Boy, Boy"
|
||||
},
|
||||
{
|
||||
"emoji": "👨👨👧👧",
|
||||
"title": "Family: Man, Man, Girl, Girl"
|
||||
},
|
||||
{
|
||||
"emoji": "👩👩👦",
|
||||
"title": "Family: Woman, Woman, Boy"
|
||||
},
|
||||
{
|
||||
"emoji": "👩👩👧",
|
||||
"title": "Family: Woman, Woman, Girl"
|
||||
},
|
||||
{
|
||||
"emoji": "👩👩👧👦",
|
||||
"title": "Family: Woman, Woman, Girl, Boy"
|
||||
},
|
||||
{
|
||||
"emoji": "👩👩👦👦",
|
||||
"title": "Family: Woman, Woman, Boy, Boy"
|
||||
},
|
||||
{
|
||||
"emoji": "👩👩👧👧",
|
||||
"title": "Family: Woman, Woman, Girl, Girl"
|
||||
},
|
||||
{
|
||||
"emoji": "👨👦",
|
||||
"title": "Family: Man, Boy"
|
||||
},
|
||||
{
|
||||
"emoji": "👨👦👦",
|
||||
"title": "Family: Man, Boy, Boy"
|
||||
},
|
||||
{
|
||||
"emoji": "👨👧",
|
||||
"title": "Family: Man, Girl"
|
||||
},
|
||||
{
|
||||
"emoji": "👨👧👦",
|
||||
"title": "Family: Man, Girl, Boy"
|
||||
},
|
||||
{
|
||||
"emoji": "👨👧👧",
|
||||
"title": "Family: Man, Girl, Girl"
|
||||
},
|
||||
{
|
||||
"emoji": "👩👦",
|
||||
"title": "Family: Woman, Boy"
|
||||
},
|
||||
{
|
||||
"emoji": "👩👦👦",
|
||||
"title": "Family: Woman, Boy, Boy"
|
||||
},
|
||||
{
|
||||
"emoji": "👩👧",
|
||||
"title": "Family: Woman, Girl"
|
||||
},
|
||||
{
|
||||
"emoji": "👩👧👦",
|
||||
"title": "Family: Woman, Girl, Boy"
|
||||
},
|
||||
{
|
||||
"emoji": "👩👧👧",
|
||||
"title": "Family: Woman, Girl, Girl"
|
||||
},
|
||||
{
|
||||
"emoji": "🗣️",
|
||||
"title": "Speaking Head"
|
||||
},
|
||||
{
|
||||
"emoji": "👤",
|
||||
"title": "Bust in Silhouette"
|
||||
},
|
||||
{
|
||||
"emoji": "👥",
|
||||
"title": "Busts in Silhouette"
|
||||
},
|
||||
{
|
||||
"emoji": "🫂",
|
||||
"title": "People Hugging"
|
||||
},
|
||||
{
|
||||
"emoji": "👣",
|
||||
"title": "Footprints"
|
||||
},
|
||||
{
|
||||
"emoji": "🧳",
|
||||
"title": "Luggage"
|
||||
},
|
||||
{
|
||||
"emoji": "🌂",
|
||||
"title": "Closed Umbrella"
|
||||
},
|
||||
{
|
||||
"emoji": "☂️",
|
||||
"title": "Umbrella"
|
||||
},
|
||||
{
|
||||
"emoji": "🎃",
|
||||
"title": "Jack-O-Lantern"
|
||||
},
|
||||
{
|
||||
"emoji": "🧵",
|
||||
"title": "Thread"
|
||||
},
|
||||
{
|
||||
"emoji": "🧶",
|
||||
"title": "Yarn"
|
||||
},
|
||||
{
|
||||
"emoji": "👓",
|
||||
"title": "Glasses"
|
||||
},
|
||||
{
|
||||
"emoji": "🕶️",
|
||||
"title": "Sunglasses"
|
||||
},
|
||||
{
|
||||
"emoji": "🥽",
|
||||
"title": "Goggles"
|
||||
},
|
||||
{
|
||||
"emoji": "🥼",
|
||||
"title": "Lab Coat"
|
||||
},
|
||||
{
|
||||
"emoji": "🦺",
|
||||
"title": "Safety Vest"
|
||||
},
|
||||
{
|
||||
"emoji": "👔",
|
||||
"title": "Necktie"
|
||||
},
|
||||
{
|
||||
"emoji": "👕",
|
||||
"title": "T-Shirt"
|
||||
},
|
||||
{
|
||||
"emoji": "👖",
|
||||
"title": "Jeans"
|
||||
},
|
||||
{
|
||||
"emoji": "🧣",
|
||||
"title": "Scarf"
|
||||
},
|
||||
{
|
||||
"emoji": "🧤",
|
||||
"title": "Gloves"
|
||||
},
|
||||
{
|
||||
"emoji": "🧥",
|
||||
"title": "Coat"
|
||||
},
|
||||
{
|
||||
"emoji": "🧦",
|
||||
"title": "Socks"
|
||||
},
|
||||
{
|
||||
"emoji": "👗",
|
||||
"title": "Dress"
|
||||
},
|
||||
{
|
||||
"emoji": "👘",
|
||||
"title": "Kimono"
|
||||
},
|
||||
{
|
||||
"emoji": "🥻",
|
||||
"title": "Sari"
|
||||
},
|
||||
{
|
||||
"emoji": "🩱",
|
||||
"title": "One-Piece Swimsuit"
|
||||
},
|
||||
{
|
||||
"emoji": "🩲",
|
||||
"title": "Briefs"
|
||||
},
|
||||
{
|
||||
"emoji": "🩳",
|
||||
"title": "Shorts"
|
||||
},
|
||||
{
|
||||
"emoji": "👙",
|
||||
"title": "Bikini"
|
||||
},
|
||||
{
|
||||
"emoji": "👚",
|
||||
"title": "Woman’s Clothes"
|
||||
},
|
||||
{
|
||||
"emoji": "👛",
|
||||
"title": "Purse"
|
||||
},
|
||||
{
|
||||
"emoji": "👜",
|
||||
"title": "Handbag"
|
||||
},
|
||||
{
|
||||
"emoji": "👝",
|
||||
"title": "Clutch Bag"
|
||||
},
|
||||
{
|
||||
"emoji": "🎒",
|
||||
"title": "Backpack"
|
||||
},
|
||||
{
|
||||
"emoji": "🩴",
|
||||
"title": "Thong Sandal"
|
||||
},
|
||||
{
|
||||
"emoji": "👞",
|
||||
"title": "Man’s Shoe"
|
||||
},
|
||||
{
|
||||
"emoji": "👟",
|
||||
"title": "Running Shoe"
|
||||
},
|
||||
{
|
||||
"emoji": "🥾",
|
||||
"title": "Hiking Boot"
|
||||
},
|
||||
{
|
||||
"emoji": "🥿",
|
||||
"title": "Flat Shoe"
|
||||
},
|
||||
{
|
||||
"emoji": "👠",
|
||||
"title": "High-Heeled Shoe"
|
||||
},
|
||||
{
|
||||
"emoji": "👡",
|
||||
"title": "Woman’s Sandal"
|
||||
},
|
||||
{
|
||||
"emoji": "🩰",
|
||||
"title": "Ballet Shoes"
|
||||
},
|
||||
{
|
||||
"emoji": "👢",
|
||||
"title": "Woman’s Boot"
|
||||
},
|
||||
{
|
||||
"emoji": "👑",
|
||||
"title": "Crown"
|
||||
},
|
||||
{
|
||||
"emoji": "👒",
|
||||
"title": "Woman’s Hat"
|
||||
},
|
||||
{
|
||||
"emoji": "🎩",
|
||||
"title": "Top Hat"
|
||||
},
|
||||
{
|
||||
"emoji": "🎓",
|
||||
"title": "Graduation Cap"
|
||||
},
|
||||
{
|
||||
"emoji": "🧢",
|
||||
"title": "Billed Cap"
|
||||
},
|
||||
{
|
||||
"emoji": "🪖",
|
||||
"title": "Military Helmet"
|
||||
},
|
||||
{
|
||||
"emoji": "⛑️",
|
||||
"title": "Rescue Worker’s Helmet"
|
||||
},
|
||||
{
|
||||
"emoji": "💄",
|
||||
"title": "Lipstick"
|
||||
},
|
||||
{
|
||||
"emoji": "💍",
|
||||
"title": "Ring"
|
||||
},
|
||||
{
|
||||
"emoji": "💼",
|
||||
"title": "Briefcase"
|
||||
},
|
||||
{
|
||||
"emoji": "🩸",
|
||||
"title": "Drop of Blood"
|
||||
}
|
||||
],
|
||||
'Nature': [
|
||||
{
|
||||
"emoji": "🙈",
|
||||
"title": "See-No-Evil Monkey"
|
||||
},
|
||||
{
|
||||
"emoji": "🙉",
|
||||
"title": "Hear-No-Evil Monkey"
|
||||
},
|
||||
{
|
||||
"emoji": "🙊",
|
||||
"title": "Speak-No-Evil Monkey"
|
||||
},
|
||||
{
|
||||
"emoji": "💥",
|
||||
"title": "Collision"
|
||||
},
|
||||
{
|
||||
"emoji": "💫",
|
||||
"title": "Dizzy"
|
||||
},
|
||||
{
|
||||
"emoji": "💦",
|
||||
"title": "Sweat Droplets"
|
||||
},
|
||||
{
|
||||
"emoji": "💨",
|
||||
"title": "Dashing Away"
|
||||
},
|
||||
{
|
||||
"emoji": "🐵",
|
||||
"title": "Monkey Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🐒",
|
||||
"title": "Monkey"
|
||||
},
|
||||
{
|
||||
"emoji": "🦍",
|
||||
"title": "Gorilla"
|
||||
},
|
||||
{
|
||||
"emoji": "🦧",
|
||||
"title": "Orangutan"
|
||||
},
|
||||
{
|
||||
"emoji": "🐶",
|
||||
"title": "Dog Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🐕",
|
||||
"title": "Dog"
|
||||
},
|
||||
{
|
||||
"emoji": "🦮",
|
||||
"title": "Guide Dog"
|
||||
},
|
||||
{
|
||||
"emoji": "🐕🦺",
|
||||
"title": "Service Dog"
|
||||
},
|
||||
{
|
||||
"emoji": "🐩",
|
||||
"title": "Poodle"
|
||||
},
|
||||
{
|
||||
"emoji": "🐺",
|
||||
"title": "Wolf"
|
||||
},
|
||||
{
|
||||
"emoji": "🦊",
|
||||
"title": "Fox"
|
||||
},
|
||||
{
|
||||
"emoji": "🦝",
|
||||
"title": "Raccoon"
|
||||
},
|
||||
{
|
||||
"emoji": "🐱",
|
||||
"title": "Cat Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🐈",
|
||||
"title": "Cat"
|
||||
},
|
||||
{
|
||||
"emoji": "🐈⬛",
|
||||
"title": "Black Cat"
|
||||
},
|
||||
{
|
||||
"emoji": "🦁",
|
||||
"title": "Lion"
|
||||
},
|
||||
{
|
||||
"emoji": "🐯",
|
||||
"title": "Tiger Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🐅",
|
||||
"title": "Tiger"
|
||||
},
|
||||
{
|
||||
"emoji": "🐆",
|
||||
"title": "Leopard"
|
||||
},
|
||||
{
|
||||
"emoji": "🐴",
|
||||
"title": "Horse Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🐎",
|
||||
"title": "Horse"
|
||||
},
|
||||
{
|
||||
"emoji": "🦄",
|
||||
"title": "Unicorn"
|
||||
},
|
||||
{
|
||||
"emoji": "🦓",
|
||||
"title": "Zebra"
|
||||
},
|
||||
{
|
||||
"emoji": "🦌",
|
||||
"title": "Deer"
|
||||
},
|
||||
{
|
||||
"emoji": "🦬",
|
||||
"title": "Bison"
|
||||
},
|
||||
{
|
||||
"emoji": "🐮",
|
||||
"title": "Cow Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🐂",
|
||||
"title": "Ox"
|
||||
},
|
||||
{
|
||||
"emoji": "🐃",
|
||||
"title": "Water Buffalo"
|
||||
},
|
||||
{
|
||||
"emoji": "🐄",
|
||||
"title": "Cow"
|
||||
},
|
||||
{
|
||||
"emoji": "🐷",
|
||||
"title": "Pig Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🐖",
|
||||
"title": "Pig"
|
||||
},
|
||||
{
|
||||
"emoji": "🐗",
|
||||
"title": "Boar"
|
||||
},
|
||||
{
|
||||
"emoji": "🐽",
|
||||
"title": "Pig Nose"
|
||||
},
|
||||
{
|
||||
"emoji": "🐏",
|
||||
"title": "Ram"
|
||||
},
|
||||
{
|
||||
"emoji": "🐑",
|
||||
"title": "Ewe"
|
||||
},
|
||||
{
|
||||
"emoji": "🐐",
|
||||
"title": "Goat"
|
||||
},
|
||||
{
|
||||
"emoji": "🐪",
|
||||
"title": "Camel"
|
||||
},
|
||||
{
|
||||
"emoji": "🐫",
|
||||
"title": "Two-Hump Camel"
|
||||
},
|
||||
{
|
||||
"emoji": "🦙",
|
||||
"title": "Llama"
|
||||
},
|
||||
{
|
||||
"emoji": "🦒",
|
||||
"title": "Giraffe"
|
||||
},
|
||||
{
|
||||
"emoji": "🐘",
|
||||
"title": "Elephant"
|
||||
},
|
||||
{
|
||||
"emoji": "🦣",
|
||||
"title": "Mammoth"
|
||||
},
|
||||
{
|
||||
"emoji": "🦏",
|
||||
"title": "Rhinoceros"
|
||||
},
|
||||
{
|
||||
"emoji": "🦛",
|
||||
"title": "Hippopotamus"
|
||||
},
|
||||
{
|
||||
"emoji": "🐭",
|
||||
"title": "Mouse Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🐁",
|
||||
"title": "Mouse"
|
||||
},
|
||||
{
|
||||
"emoji": "🐀",
|
||||
"title": "Rat"
|
||||
},
|
||||
{
|
||||
"emoji": "🐹",
|
||||
"title": "Hamster"
|
||||
},
|
||||
{
|
||||
"emoji": "🐰",
|
||||
"title": "Rabbit Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🐇",
|
||||
"title": "Rabbit"
|
||||
},
|
||||
{
|
||||
"emoji": "🐿️",
|
||||
"title": "Chipmunk"
|
||||
},
|
||||
{
|
||||
"emoji": "🦫",
|
||||
"title": "Beaver"
|
||||
},
|
||||
{
|
||||
"emoji": "🦔",
|
||||
"title": "Hedgehog"
|
||||
},
|
||||
{
|
||||
"emoji": "🦇",
|
||||
"title": "Bat"
|
||||
},
|
||||
{
|
||||
"emoji": "🐻",
|
||||
"title": "Bear"
|
||||
},
|
||||
{
|
||||
"emoji": "🐻❄️",
|
||||
"title": "Polar Bear"
|
||||
},
|
||||
{
|
||||
"emoji": "🐨",
|
||||
"title": "Koala"
|
||||
},
|
||||
{
|
||||
"emoji": "🐼",
|
||||
"title": "Panda"
|
||||
},
|
||||
{
|
||||
"emoji": "🦥",
|
||||
"title": "Sloth"
|
||||
},
|
||||
{
|
||||
"emoji": "🦦",
|
||||
"title": "Otter"
|
||||
},
|
||||
{
|
||||
"emoji": "🦨",
|
||||
"title": "Skunk"
|
||||
},
|
||||
{
|
||||
"emoji": "🦘",
|
||||
"title": "Kangaroo"
|
||||
},
|
||||
{
|
||||
"emoji": "🦡",
|
||||
"title": "Badger"
|
||||
},
|
||||
{
|
||||
"emoji": "🐾",
|
||||
"title": "Paw Prints"
|
||||
},
|
||||
{
|
||||
"emoji": "🦃",
|
||||
"title": "Turkey"
|
||||
},
|
||||
{
|
||||
"emoji": "🐔",
|
||||
"title": "Chicken"
|
||||
},
|
||||
{
|
||||
"emoji": "🐓",
|
||||
"title": "Rooster"
|
||||
},
|
||||
{
|
||||
"emoji": "🐣",
|
||||
"title": "Hatching Chick"
|
||||
},
|
||||
{
|
||||
"emoji": "🐤",
|
||||
"title": "Baby Chick"
|
||||
},
|
||||
{
|
||||
"emoji": "🐥",
|
||||
"title": "Front-Facing Baby Chick"
|
||||
},
|
||||
{
|
||||
"emoji": "🐦",
|
||||
"title": "Bird"
|
||||
},
|
||||
{
|
||||
"emoji": "🐧",
|
||||
"title": "Penguin"
|
||||
},
|
||||
{
|
||||
"emoji": "🕊️",
|
||||
"title": "Dove"
|
||||
},
|
||||
{
|
||||
"emoji": "🦅",
|
||||
"title": "Eagle"
|
||||
},
|
||||
{
|
||||
"emoji": "🦆",
|
||||
"title": "Duck"
|
||||
},
|
||||
{
|
||||
"emoji": "🦢",
|
||||
"title": "Swan"
|
||||
},
|
||||
{
|
||||
"emoji": "🦉",
|
||||
"title": "Owl"
|
||||
},
|
||||
{
|
||||
"emoji": "🦤",
|
||||
"title": "Dodo"
|
||||
},
|
||||
{
|
||||
"emoji": "🪶",
|
||||
"title": "Feather"
|
||||
},
|
||||
{
|
||||
"emoji": "🦩",
|
||||
"title": "Flamingo"
|
||||
},
|
||||
{
|
||||
"emoji": "🦚",
|
||||
"title": "Peacock"
|
||||
},
|
||||
{
|
||||
"emoji": "🦜",
|
||||
"title": "Parrot"
|
||||
},
|
||||
{
|
||||
"emoji": "🐸",
|
||||
"title": "Frog"
|
||||
},
|
||||
{
|
||||
"emoji": "🐊",
|
||||
"title": "Crocodile"
|
||||
},
|
||||
{
|
||||
"emoji": "🐢",
|
||||
"title": "Turtle"
|
||||
},
|
||||
{
|
||||
"emoji": "🦎",
|
||||
"title": "Lizard"
|
||||
},
|
||||
{
|
||||
"emoji": "🐍",
|
||||
"title": "Snake"
|
||||
},
|
||||
{
|
||||
"emoji": "🐲",
|
||||
"title": "Dragon Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🐉",
|
||||
"title": "Dragon"
|
||||
},
|
||||
{
|
||||
"emoji": "🦕",
|
||||
"title": "Sauropod"
|
||||
},
|
||||
{
|
||||
"emoji": "🦖",
|
||||
"title": "T-Rex"
|
||||
},
|
||||
{
|
||||
"emoji": "🐳",
|
||||
"title": "Spouting Whale"
|
||||
},
|
||||
{
|
||||
"emoji": "🐋",
|
||||
"title": "Whale"
|
||||
},
|
||||
{
|
||||
"emoji": "🐬",
|
||||
"title": "Dolphin"
|
||||
},
|
||||
{
|
||||
"emoji": "🦭",
|
||||
"title": "Seal"
|
||||
},
|
||||
{
|
||||
"emoji": "🐟",
|
||||
"title": "Fish"
|
||||
},
|
||||
{
|
||||
"emoji": "🐠",
|
||||
"title": "Tropical Fish"
|
||||
},
|
||||
{
|
||||
"emoji": "🐡",
|
||||
"title": "Blowfish"
|
||||
},
|
||||
{
|
||||
"emoji": "🦈",
|
||||
"title": "Shark"
|
||||
},
|
||||
{
|
||||
"emoji": "🐙",
|
||||
"title": "Octopus"
|
||||
},
|
||||
{
|
||||
"emoji": "🐚",
|
||||
"title": "Spiral Shell"
|
||||
},
|
||||
{
|
||||
"emoji": "🐌",
|
||||
"title": "Snail"
|
||||
},
|
||||
{
|
||||
"emoji": "🦋",
|
||||
"title": "Butterfly"
|
||||
},
|
||||
{
|
||||
"emoji": "🐛",
|
||||
"title": "Bug"
|
||||
},
|
||||
{
|
||||
"emoji": "🐜",
|
||||
"title": "Ant"
|
||||
},
|
||||
{
|
||||
"emoji": "🐝",
|
||||
"title": "Honeybee"
|
||||
},
|
||||
{
|
||||
"emoji": "🪲",
|
||||
"title": "Beetle"
|
||||
},
|
||||
{
|
||||
"emoji": "🐞",
|
||||
"title": "Lady Beetle"
|
||||
},
|
||||
{
|
||||
"emoji": "🦗",
|
||||
"title": "Cricket"
|
||||
},
|
||||
{
|
||||
"emoji": "🪳",
|
||||
"title": "Cockroach"
|
||||
},
|
||||
{
|
||||
"emoji": "🕷️",
|
||||
"title": "Spider"
|
||||
},
|
||||
{
|
||||
"emoji": "🕸️",
|
||||
"title": "Spider Web"
|
||||
},
|
||||
{
|
||||
"emoji": "🦂",
|
||||
"title": "Scorpion"
|
||||
},
|
||||
{
|
||||
"emoji": "🦟",
|
||||
"title": "Mosquito"
|
||||
},
|
||||
{
|
||||
"emoji": "🪰",
|
||||
"title": "Fly"
|
||||
},
|
||||
{
|
||||
"emoji": "🪱",
|
||||
"title": "Worm"
|
||||
},
|
||||
{
|
||||
"emoji": "🦠",
|
||||
"title": "Microbe"
|
||||
},
|
||||
{
|
||||
"emoji": "💐",
|
||||
"title": "Bouquet"
|
||||
},
|
||||
{
|
||||
"emoji": "🌸",
|
||||
"title": "Cherry Blossom"
|
||||
},
|
||||
{
|
||||
"emoji": "💮",
|
||||
"title": "White Flower"
|
||||
},
|
||||
{
|
||||
"emoji": "🏵️",
|
||||
"title": "Rosette"
|
||||
},
|
||||
{
|
||||
"emoji": "🌹",
|
||||
"title": "Rose"
|
||||
},
|
||||
{
|
||||
"emoji": "🥀",
|
||||
"title": "Wilted Flower"
|
||||
},
|
||||
{
|
||||
"emoji": "🌺",
|
||||
"title": "Hibiscus"
|
||||
},
|
||||
{
|
||||
"emoji": "🌻",
|
||||
"title": "Sunflower"
|
||||
},
|
||||
{
|
||||
"emoji": "🌼",
|
||||
"title": "Blossom"
|
||||
},
|
||||
{
|
||||
"emoji": "🌷",
|
||||
"title": "Tulip"
|
||||
},
|
||||
{
|
||||
"emoji": "🌱",
|
||||
"title": "Seedling"
|
||||
},
|
||||
{
|
||||
"emoji": "🪴",
|
||||
"title": "Potted Plant"
|
||||
},
|
||||
{
|
||||
"emoji": "🌲",
|
||||
"title": "Evergreen Tree"
|
||||
},
|
||||
{
|
||||
"emoji": "🌳",
|
||||
"title": "Deciduous Tree"
|
||||
},
|
||||
{
|
||||
"emoji": "🌴",
|
||||
"title": "Palm Tree"
|
||||
},
|
||||
{
|
||||
"emoji": "🌵",
|
||||
"title": "Cactus"
|
||||
},
|
||||
{
|
||||
"emoji": "🌾",
|
||||
"title": "Sheaf of Rice"
|
||||
},
|
||||
{
|
||||
"emoji": "🌿",
|
||||
"title": "Herb"
|
||||
},
|
||||
{
|
||||
"emoji": "☘️",
|
||||
"title": "Shamrock"
|
||||
},
|
||||
{
|
||||
"emoji": "🍀",
|
||||
"title": "Four Leaf Clover"
|
||||
},
|
||||
{
|
||||
"emoji": "🍁",
|
||||
"title": "Maple Leaf"
|
||||
},
|
||||
{
|
||||
"emoji": "🍂",
|
||||
"title": "Fallen Leaf"
|
||||
},
|
||||
{
|
||||
"emoji": "🍃",
|
||||
"title": "Leaf Fluttering in Wind"
|
||||
},
|
||||
{
|
||||
"emoji": "🍄",
|
||||
"title": "Mushroom"
|
||||
},
|
||||
{
|
||||
"emoji": "🌰",
|
||||
"title": "Chestnut"
|
||||
},
|
||||
{
|
||||
"emoji": "🦀",
|
||||
"title": "Crab"
|
||||
},
|
||||
{
|
||||
"emoji": "🦞",
|
||||
"title": "Lobster"
|
||||
},
|
||||
{
|
||||
"emoji": "🦐",
|
||||
"title": "Shrimp"
|
||||
},
|
||||
{
|
||||
"emoji": "🦑",
|
||||
"title": "Squid"
|
||||
},
|
||||
{
|
||||
"emoji": "🌍",
|
||||
"title": "Globe Showing Europe-Africa"
|
||||
},
|
||||
{
|
||||
"emoji": "🌎",
|
||||
"title": "Globe Showing Americas"
|
||||
},
|
||||
{
|
||||
"emoji": "🌏",
|
||||
"title": "Globe Showing Asia-Australia"
|
||||
},
|
||||
{
|
||||
"emoji": "🌐",
|
||||
"title": "Globe with Meridians"
|
||||
},
|
||||
{
|
||||
"emoji": "🪨",
|
||||
"title": "Rock"
|
||||
},
|
||||
{
|
||||
"emoji": "🌑",
|
||||
"title": "New Moon"
|
||||
},
|
||||
{
|
||||
"emoji": "🌒",
|
||||
"title": "Waxing Crescent Moon"
|
||||
},
|
||||
{
|
||||
"emoji": "🌓",
|
||||
"title": "First Quarter Moon"
|
||||
},
|
||||
{
|
||||
"emoji": "🌔",
|
||||
"title": "Waxing Gibbous Moon"
|
||||
},
|
||||
{
|
||||
"emoji": "🌕",
|
||||
"title": "Full Moon"
|
||||
},
|
||||
{
|
||||
"emoji": "🌖",
|
||||
"title": "Waning Gibbous Moon"
|
||||
},
|
||||
{
|
||||
"emoji": "🌗",
|
||||
"title": "Last Quarter Moon"
|
||||
},
|
||||
{
|
||||
"emoji": "🌘",
|
||||
"title": "Waning Crescent Moon"
|
||||
},
|
||||
{
|
||||
"emoji": "🌙",
|
||||
"title": "Crescent Moon"
|
||||
},
|
||||
{
|
||||
"emoji": "🌚",
|
||||
"title": "New Moon Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🌛",
|
||||
"title": "First Quarter Moon Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🌜",
|
||||
"title": "Last Quarter Moon Face"
|
||||
},
|
||||
{
|
||||
"emoji": "☀️",
|
||||
"title": "Sun"
|
||||
},
|
||||
{
|
||||
"emoji": "🌝",
|
||||
"title": "Full Moon Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🌞",
|
||||
"title": "Sun with Face"
|
||||
},
|
||||
{
|
||||
"emoji": "⭐",
|
||||
"title": "Star"
|
||||
},
|
||||
{
|
||||
"emoji": "🌟",
|
||||
"title": "Glowing Star"
|
||||
},
|
||||
{
|
||||
"emoji": "🌠",
|
||||
"title": "Shooting Star"
|
||||
},
|
||||
{
|
||||
"emoji": "☁️",
|
||||
"title": "Cloud"
|
||||
},
|
||||
{
|
||||
"emoji": "⛅",
|
||||
"title": "Sun Behind Cloud"
|
||||
},
|
||||
{
|
||||
"emoji": "⛈️",
|
||||
"title": "Cloud with Lightning and Rain"
|
||||
},
|
||||
{
|
||||
"emoji": "🌤️",
|
||||
"title": "Sun Behind Small Cloud"
|
||||
},
|
||||
{
|
||||
"emoji": "🌥️",
|
||||
"title": "Sun Behind Large Cloud"
|
||||
},
|
||||
{
|
||||
"emoji": "🌦️",
|
||||
"title": "Sun Behind Rain Cloud"
|
||||
},
|
||||
{
|
||||
"emoji": "🌧️",
|
||||
"title": "Cloud with Rain"
|
||||
},
|
||||
{
|
||||
"emoji": "🌨️",
|
||||
"title": "Cloud with Snow"
|
||||
},
|
||||
{
|
||||
"emoji": "🌩️",
|
||||
"title": "Cloud with Lightning"
|
||||
},
|
||||
{
|
||||
"emoji": "🌪️",
|
||||
"title": "Tornado"
|
||||
},
|
||||
{
|
||||
"emoji": "🌫️",
|
||||
"title": "Fog"
|
||||
},
|
||||
{
|
||||
"emoji": "🌬️",
|
||||
"title": "Wind Face"
|
||||
},
|
||||
{
|
||||
"emoji": "🌈",
|
||||
"title": "Rainbow"
|
||||
},
|
||||
{
|
||||
"emoji": "☂️",
|
||||
"title": "Umbrella"
|
||||
},
|
||||
{
|
||||
"emoji": "☔",
|
||||
"title": "Umbrella with Rain Drops"
|
||||
},
|
||||
{
|
||||
"emoji": "⚡",
|
||||
"title": "High Voltage"
|
||||
},
|
||||
{
|
||||
"emoji": "❄️",
|
||||
"title": "Snowflake"
|
||||
},
|
||||
{
|
||||
"emoji": "☃️",
|
||||
"title": "Snowman"
|
||||
},
|
||||
{
|
||||
"emoji": "⛄",
|
||||
"title": "Snowman Without Snow"
|
||||
},
|
||||
{
|
||||
"emoji": "☄️",
|
||||
"title": "Comet"
|
||||
},
|
||||
{
|
||||
"emoji": "🔥",
|
||||
"title": "Fire"
|
||||
},
|
||||
{
|
||||
"emoji": "💧",
|
||||
"title": "Droplet"
|
||||
},
|
||||
{
|
||||
"emoji": "🌊",
|
||||
"title": "Water Wave"
|
||||
},
|
||||
{
|
||||
"emoji": "🎄",
|
||||
"title": "Christmas Tree"
|
||||
},
|
||||
{
|
||||
"emoji": "✨",
|
||||
"title": "Sparkles"
|
||||
},
|
||||
{
|
||||
"emoji": "🎋",
|
||||
"title": "Tanabata Tree"
|
||||
},
|
||||
{
|
||||
"emoji": "🎍",
|
||||
"title": "Pine Decoration"
|
||||
}
|
||||
],
|
||||
'Food-dring': [
|
||||
{
|
||||
"emoji": "🍇",
|
||||
"title": "Grapes"
|
||||
},
|
||||
{
|
||||
"emoji": "🍈",
|
||||
"title": "Melon"
|
||||
},
|
||||
{
|
||||
"emoji": "🍉",
|
||||
"title": "Watermelon"
|
||||
},
|
||||
{
|
||||
"emoji": "🍊",
|
||||
"title": "Tangerine"
|
||||
},
|
||||
{
|
||||
"emoji": "🍋",
|
||||
"title": "Lemon"
|
||||
},
|
||||
{
|
||||
"emoji": "🍌",
|
||||
"title": "Banana"
|
||||
},
|
||||
{
|
||||
"emoji": "🍍",
|
||||
"title": "Pineapple"
|
||||
},
|
||||
{
|
||||
"emoji": "🥭",
|
||||
"title": "Mango"
|
||||
},
|
||||
{
|
||||
"emoji": "🍎",
|
||||
"title": "Red Apple"
|
||||
},
|
||||
{
|
||||
"emoji": "🍏",
|
||||
"title": "Green Apple"
|
||||
},
|
||||
{
|
||||
"emoji": "🍐",
|
||||
"title": "Pear"
|
||||
},
|
||||
{
|
||||
"emoji": "🍑",
|
||||
"title": "Peach"
|
||||
},
|
||||
{
|
||||
"emoji": "🍒",
|
||||
"title": "Cherries"
|
||||
},
|
||||
{
|
||||
"emoji": "🍓",
|
||||
"title": "Strawberry"
|
||||
},
|
||||
{
|
||||
"emoji": "🫐",
|
||||
"title": "Blueberries"
|
||||
},
|
||||
{
|
||||
"emoji": "🥝",
|
||||
"title": "Kiwi Fruit"
|
||||
},
|
||||
{
|
||||
"emoji": "🍅",
|
||||
"title": "Tomato"
|
||||
},
|
||||
{
|
||||
"emoji": "🫒",
|
||||
"title": "Olive"
|
||||
},
|
||||
{
|
||||
"emoji": "🥥",
|
||||
"title": "Coconut"
|
||||
},
|
||||
{
|
||||
"emoji": "🥑",
|
||||
"title": "Avocado"
|
||||
},
|
||||
{
|
||||
"emoji": "🍆",
|
||||
"title": "Eggplant"
|
||||
},
|
||||
{
|
||||
"emoji": "🥔",
|
||||
"title": "Potato"
|
||||
},
|
||||
{
|
||||
"emoji": "🥕",
|
||||
"title": "Carrot"
|
||||
},
|
||||
{
|
||||
"emoji": "🌽",
|
||||
"title": "Ear of Corn"
|
||||
},
|
||||
{
|
||||
"emoji": "🌶️",
|
||||
"title": "Hot Pepper"
|
||||
},
|
||||
{
|
||||
"emoji": "🫑",
|
||||
"title": "Bell Pepper"
|
||||
},
|
||||
{
|
||||
"emoji": "🥒",
|
||||
"title": "Cucumber"
|
||||
},
|
||||
{
|
||||
"emoji": "🥬",
|
||||
"title": "Leafy Green"
|
||||
},
|
||||
{
|
||||
"emoji": "🥦",
|
||||
"title": "Broccoli"
|
||||
},
|
||||
{
|
||||
"emoji": "🧄",
|
||||
"title": "Garlic"
|
||||
},
|
||||
{
|
||||
"emoji": "🧅",
|
||||
"title": "Onion"
|
||||
},
|
||||
{
|
||||
"emoji": "🍄",
|
||||
"title": "Mushroom"
|
||||
},
|
||||
{
|
||||
"emoji": "🥜",
|
||||
"title": "Peanuts"
|
||||
},
|
||||
{
|
||||
"emoji": "🌰",
|
||||
"title": "Chestnut"
|
||||
},
|
||||
{
|
||||
"emoji": "🍞",
|
||||
"title": "Bread"
|
||||
},
|
||||
{
|
||||
"emoji": "🥐",
|
||||
"title": "Croissant"
|
||||
},
|
||||
{
|
||||
"emoji": "🥖",
|
||||
"title": "Baguette Bread"
|
||||
},
|
||||
{
|
||||
"emoji": "🫓",
|
||||
"title": "Flatbread"
|
||||
},
|
||||
{
|
||||
"emoji": "🥨",
|
||||
"title": "Pretzel"
|
||||
},
|
||||
{
|
||||
"emoji": "🥯",
|
||||
"title": "Bagel"
|
||||
},
|
||||
{
|
||||
"emoji": "🥞",
|
||||
"title": "Pancakes"
|
||||
},
|
||||
{
|
||||
"emoji": "🧇",
|
||||
"title": "Waffle"
|
||||
},
|
||||
{
|
||||
"emoji": "🧀",
|
||||
"title": "Cheese Wedge"
|
||||
},
|
||||
{
|
||||
"emoji": "🍖",
|
||||
"title": "Meat on Bone"
|
||||
},
|
||||
{
|
||||
"emoji": "🍗",
|
||||
"title": "Poultry Leg"
|
||||
},
|
||||
{
|
||||
"emoji": "🥩",
|
||||
"title": "Cut of Meat"
|
||||
},
|
||||
{
|
||||
"emoji": "🥓",
|
||||
"title": "Bacon"
|
||||
},
|
||||
{
|
||||
"emoji": "🍔",
|
||||
"title": "Hamburger"
|
||||
},
|
||||
{
|
||||
"emoji": "🍟",
|
||||
"title": "French Fries"
|
||||
},
|
||||
{
|
||||
"emoji": "🍕",
|
||||
"title": "Pizza"
|
||||
},
|
||||
{
|
||||
"emoji": "🌭",
|
||||
"title": "Hot Dog"
|
||||
},
|
||||
{
|
||||
"emoji": "🥪",
|
||||
"title": "Sandwich"
|
||||
},
|
||||
{
|
||||
"emoji": "🌮",
|
||||
"title": "Taco"
|
||||
},
|
||||
{
|
||||
"emoji": "🌯",
|
||||
"title": "Burrito"
|
||||
},
|
||||
{
|
||||
"emoji": "🫔",
|
||||
"title": "Tamale"
|
||||
},
|
||||
{
|
||||
"emoji": "🥙",
|
||||
"title": "Stuffed Flatbread"
|
||||
},
|
||||
{
|
||||
"emoji": "🧆",
|
||||
"title": "Falafel"
|
||||
},
|
||||
{
|
||||
"emoji": "🥚",
|
||||
"title": "Egg"
|
||||
},
|
||||
{
|
||||
"emoji": "🍳",
|
||||
"title": "Cooking"
|
||||
},
|
||||
{
|
||||
"emoji": "🥘",
|
||||
"title": "Shallow Pan of Food"
|
||||
},
|
||||
{
|
||||
"emoji": "🍲",
|
||||
"title": "Pot of Food"
|
||||
},
|
||||
{
|
||||
"emoji": "🫕",
|
||||
"title": "Fondue"
|
||||
},
|
||||
{
|
||||
"emoji": "🥣",
|
||||
"title": "Bowl with Spoon"
|
||||
},
|
||||
{
|
||||
"emoji": "🥗",
|
||||
"title": "Green Salad"
|
||||
},
|
||||
{
|
||||
"emoji": "🍿",
|
||||
"title": "Popcorn"
|
||||
},
|
||||
{
|
||||
"emoji": "🧈",
|
||||
"title": "Butter"
|
||||
},
|
||||
{
|
||||
"emoji": "🧂",
|
||||
"title": "Salt"
|
||||
},
|
||||
{
|
||||
"emoji": "🥫",
|
||||
"title": "Canned Food"
|
||||
},
|
||||
{
|
||||
"emoji": "🍱",
|
||||
"title": "Bento Box"
|
||||
},
|
||||
{
|
||||
"emoji": "🍘",
|
||||
"title": "Rice Cracker"
|
||||
},
|
||||
{
|
||||
"emoji": "🍙",
|
||||
"title": "Rice Ball"
|
||||
},
|
||||
{
|
||||
"emoji": "🍚",
|
||||
"title": "Cooked Rice"
|
||||
},
|
||||
{
|
||||
"emoji": "🍛",
|
||||
"title": "Curry Rice"
|
||||
},
|
||||
{
|
||||
"emoji": "🍜",
|
||||
"title": "Steaming Bowl"
|
||||
},
|
||||
{
|
||||
"emoji": "🍝",
|
||||
"title": "Spaghetti"
|
||||
},
|
||||
{
|
||||
"emoji": "🍠",
|
||||
"title": "Roasted Sweet Potato"
|
||||
},
|
||||
{
|
||||
"emoji": "🍢",
|
||||
"title": "Oden"
|
||||
},
|
||||
{
|
||||
"emoji": "🍣",
|
||||
"title": "Sushi"
|
||||
},
|
||||
{
|
||||
"emoji": "🍤",
|
||||
"title": "Fried Shrimp"
|
||||
},
|
||||
{
|
||||
"emoji": "🍥",
|
||||
"title": "Fish Cake with Swirl"
|
||||
},
|
||||
{
|
||||
"emoji": "🥮",
|
||||
"title": "Moon Cake"
|
||||
},
|
||||
{
|
||||
"emoji": "🍡",
|
||||
"title": "Dango"
|
||||
},
|
||||
{
|
||||
"emoji": "🥟",
|
||||
"title": "Dumpling"
|
||||
},
|
||||
{
|
||||
"emoji": "🥠",
|
||||
"title": "Fortune Cookie"
|
||||
},
|
||||
{
|
||||
"emoji": "🥡",
|
||||
"title": "Takeout Box"
|
||||
},
|
||||
{
|
||||
"emoji": "🦪",
|
||||
"title": "Oyster"
|
||||
},
|
||||
{
|
||||
"emoji": "🍦",
|
||||
"title": "Soft Ice Cream"
|
||||
},
|
||||
{
|
||||
"emoji": "🍧",
|
||||
"title": "Shaved Ice"
|
||||
},
|
||||
{
|
||||
"emoji": "🍨",
|
||||
"title": "Ice Cream"
|
||||
},
|
||||
{
|
||||
"emoji": "🍩",
|
||||
"title": "Doughnut"
|
||||
},
|
||||
{
|
||||
"emoji": "🍪",
|
||||
"title": "Cookie"
|
||||
},
|
||||
{
|
||||
"emoji": "🎂",
|
||||
"title": "Birthday Cake"
|
||||
},
|
||||
{
|
||||
"emoji": "🍰",
|
||||
"title": "Shortcake"
|
||||
},
|
||||
{
|
||||
"emoji": "🧁",
|
||||
"title": "Cupcake"
|
||||
},
|
||||
{
|
||||
"emoji": "🥧",
|
||||
"title": "Pie"
|
||||
},
|
||||
{
|
||||
"emoji": "🍫",
|
||||
"title": "Chocolate Bar"
|
||||
},
|
||||
{
|
||||
"emoji": "🍬",
|
||||
"title": "Candy"
|
||||
},
|
||||
{
|
||||
"emoji": "🍭",
|
||||
"title": "Lollipop"
|
||||
},
|
||||
{
|
||||
"emoji": "🍮",
|
||||
"title": "Custard"
|
||||
},
|
||||
{
|
||||
"emoji": "🍯",
|
||||
"title": "Honey Pot"
|
||||
},
|
||||
{
|
||||
"emoji": "🍼",
|
||||
"title": "Baby Bottle"
|
||||
},
|
||||
{
|
||||
"emoji": "🥛",
|
||||
"title": "Glass of Milk"
|
||||
},
|
||||
{
|
||||
"emoji": "☕",
|
||||
"title": "Hot Beverage"
|
||||
},
|
||||
{
|
||||
"emoji": "🫖",
|
||||
"title": "Teapot"
|
||||
},
|
||||
{
|
||||
"emoji": "🍵",
|
||||
"title": "Teacup Without Handle"
|
||||
},
|
||||
{
|
||||
"emoji": "🍶",
|
||||
"title": "Sake"
|
||||
},
|
||||
{
|
||||
"emoji": "🍾",
|
||||
"title": "Bottle with Popping Cork"
|
||||
},
|
||||
{
|
||||
"emoji": "🍷",
|
||||
"title": "Wine Glass"
|
||||
},
|
||||
{
|
||||
"emoji": "🍸",
|
||||
"title": "Cocktail Glass"
|
||||
},
|
||||
{
|
||||
"emoji": "🍹",
|
||||
"title": "Tropical Drink"
|
||||
},
|
||||
{
|
||||
"emoji": "🍺",
|
||||
"title": "Beer Mug"
|
||||
},
|
||||
{
|
||||
"emoji": "🍻",
|
||||
"title": "Clinking Beer Mugs"
|
||||
},
|
||||
{
|
||||
"emoji": "🥂",
|
||||
"title": "Clinking Glasses"
|
||||
},
|
||||
{
|
||||
"emoji": "🥃",
|
||||
"title": "Tumbler Glass"
|
||||
},
|
||||
{
|
||||
"emoji": "🥤",
|
||||
"title": "Cup with Straw"
|
||||
},
|
||||
{
|
||||
"emoji": "🧋",
|
||||
"title": "Bubble Tea"
|
||||
},
|
||||
{
|
||||
"emoji": "🧃",
|
||||
"title": "Beverage Box"
|
||||
},
|
||||
{
|
||||
"emoji": "🧉",
|
||||
"title": "Mate"
|
||||
},
|
||||
{
|
||||
"emoji": "🧊",
|
||||
"title": "Ice"
|
||||
},
|
||||
{
|
||||
"emoji": "🥢",
|
||||
"title": "Chopsticks"
|
||||
},
|
||||
{
|
||||
"emoji": "🍽️",
|
||||
"title": "Fork and Knife with Plate"
|
||||
},
|
||||
{
|
||||
"emoji": "🍴",
|
||||
"title": "Fork and Knife"
|
||||
},
|
||||
{
|
||||
"emoji": "🥄",
|
||||
"title": "Spoon"
|
||||
}
|
||||
],
|
||||
'Activity': [
|
||||
{
|
||||
"emoji": "🕴️",
|
||||
"title": "Person in Suit Levitating"
|
||||
},
|
||||
{
|
||||
"emoji": "🧗",
|
||||
"title": "Person Climbing"
|
||||
},
|
||||
{
|
||||
"emoji": "🧗♂️",
|
||||
"title": "Man Climbing"
|
||||
},
|
||||
{
|
||||
"emoji": "🧗♀️",
|
||||
"title": "Woman Climbing"
|
||||
},
|
||||
{
|
||||
"emoji": "🤺",
|
||||
"title": "Person Fencing"
|
||||
},
|
||||
{
|
||||
"emoji": "🏇",
|
||||
"title": "Horse Racing"
|
||||
},
|
||||
{
|
||||
"emoji": "⛷️",
|
||||
"title": "Skier"
|
||||
},
|
||||
{
|
||||
"emoji": "🏂",
|
||||
"title": "Snowboarder"
|
||||
},
|
||||
{
|
||||
"emoji": "🏌️",
|
||||
"title": "Person Golfing"
|
||||
},
|
||||
{
|
||||
"emoji": "🏌️♂️",
|
||||
"title": "Man Golfing"
|
||||
},
|
||||
{
|
||||
"emoji": "🏌️♀️",
|
||||
"title": "Woman Golfing"
|
||||
},
|
||||
{
|
||||
"emoji": "🏄",
|
||||
"title": "Person Surfing"
|
||||
},
|
||||
{
|
||||
"emoji": "🏄♂️",
|
||||
"title": "Man Surfing"
|
||||
},
|
||||
{
|
||||
"emoji": "🏄♀️",
|
||||
"title": "Woman Surfing"
|
||||
},
|
||||
{
|
||||
"emoji": "🚣",
|
||||
"title": "Person Rowing Boat"
|
||||
},
|
||||
{
|
||||
"emoji": "🚣♂️",
|
||||
"title": "Man Rowing Boat"
|
||||
},
|
||||
{
|
||||
"emoji": "🚣♀️",
|
||||
"title": "Woman Rowing Boat"
|
||||
},
|
||||
{
|
||||
"emoji": "🏊",
|
||||
"title": "Person Swimming"
|
||||
},
|
||||
{
|
||||
"emoji": "🏊♂️",
|
||||
"title": "Man Swimming"
|
||||
},
|
||||
{
|
||||
"emoji": "🏊♀️",
|
||||
"title": "Woman Swimming"
|
||||
},
|
||||
{
|
||||
"emoji": "⛹️",
|
||||
"title": "Person Bouncing Ball"
|
||||
},
|
||||
{
|
||||
"emoji": "⛹️♂️",
|
||||
"title": "Man Bouncing Ball"
|
||||
},
|
||||
{
|
||||
"emoji": "⛹️♀️",
|
||||
"title": "Woman Bouncing Ball"
|
||||
},
|
||||
{
|
||||
"emoji": "🏋️",
|
||||
"title": "Person Lifting Weights"
|
||||
},
|
||||
{
|
||||
"emoji": "🏋️♂️",
|
||||
"title": "Man Lifting Weights"
|
||||
},
|
||||
{
|
||||
"emoji": "🏋️♀️",
|
||||
"title": "Woman Lifting Weights"
|
||||
},
|
||||
{
|
||||
"emoji": "🚴",
|
||||
"title": "Person Biking"
|
||||
},
|
||||
{
|
||||
"emoji": "🚴♂️",
|
||||
"title": "Man Biking"
|
||||
},
|
||||
{
|
||||
"emoji": "🚴♀️",
|
||||
"title": "Woman Biking"
|
||||
},
|
||||
{
|
||||
"emoji": "🚵",
|
||||
"title": "Person Mountain Biking"
|
||||
},
|
||||
{
|
||||
"emoji": "🚵♂️",
|
||||
"title": "Man Mountain Biking"
|
||||
},
|
||||
{
|
||||
"emoji": "🚵♀️",
|
||||
"title": "Woman Mountain Biking"
|
||||
},
|
||||
{
|
||||
"emoji": "🤸",
|
||||
"title": "Person Cartwheeling"
|
||||
},
|
||||
{
|
||||
"emoji": "🤸♂️",
|
||||
"title": "Man Cartwheeling"
|
||||
},
|
||||
{
|
||||
"emoji": "🤸♀️",
|
||||
"title": "Woman Cartwheeling"
|
||||
},
|
||||
{
|
||||
"emoji": "🤼",
|
||||
"title": "People Wrestling"
|
||||
},
|
||||
{
|
||||
"emoji": "🤼♂️",
|
||||
"title": "Men Wrestling"
|
||||
},
|
||||
{
|
||||
"emoji": "🤼♀️",
|
||||
"title": "Women Wrestling"
|
||||
},
|
||||
{
|
||||
"emoji": "🤽",
|
||||
"title": "Person Playing Water Polo"
|
||||
},
|
||||
{
|
||||
"emoji": "🤽♂️",
|
||||
"title": "Man Playing Water Polo"
|
||||
},
|
||||
{
|
||||
"emoji": "🤽♀️",
|
||||
"title": "Woman Playing Water Polo"
|
||||
},
|
||||
{
|
||||
"emoji": "🤾",
|
||||
"title": "Person Playing Handball"
|
||||
},
|
||||
{
|
||||
"emoji": "🤾♂️",
|
||||
"title": "Man Playing Handball"
|
||||
},
|
||||
{
|
||||
"emoji": "🤾♀️",
|
||||
"title": "Woman Playing Handball"
|
||||
},
|
||||
{
|
||||
"emoji": "🤹",
|
||||
"title": "Person Juggling"
|
||||
},
|
||||
{
|
||||
"emoji": "🤹♂️",
|
||||
"title": "Man Juggling"
|
||||
},
|
||||
{
|
||||
"emoji": "🤹♀️",
|
||||
"title": "Woman Juggling"
|
||||
},
|
||||
{
|
||||
"emoji": "🧘",
|
||||
"title": "Person in Lotus Position"
|
||||
},
|
||||
{
|
||||
"emoji": "🧘♂️",
|
||||
"title": "Man in Lotus Position"
|
||||
},
|
||||
{
|
||||
"emoji": "🧘♀️",
|
||||
"title": "Woman in Lotus Position"
|
||||
},
|
||||
{
|
||||
"emoji": "🎪",
|
||||
"title": "Circus Tent"
|
||||
},
|
||||
{
|
||||
"emoji": "🛹",
|
||||
"title": "Skateboard"
|
||||
},
|
||||
{
|
||||
"emoji": "🛼",
|
||||
"title": "Roller Skate"
|
||||
},
|
||||
{
|
||||
"emoji": "🛶",
|
||||
"title": "Canoe"
|
||||
},
|
||||
{
|
||||
"emoji": "🎗️",
|
||||
"title": "Reminder Ribbon"
|
||||
},
|
||||
{
|
||||
"emoji": "🎟️",
|
||||
"title": "Admission Tickets"
|
||||
},
|
||||
{
|
||||
"emoji": "🎫",
|
||||
"title": "Ticket"
|
||||
},
|
||||
{
|
||||
"emoji": "🎖️",
|
||||
"title": "Military Medal"
|
||||
},
|
||||
{
|
||||
"emoji": "🏆",
|
||||
"title": "Trophy"
|
||||
},
|
||||
{
|
||||
"emoji": "🏅",
|
||||
"title": "Sports Medal"
|
||||
},
|
||||
{
|
||||
"emoji": "🥇",
|
||||
"title": "1st Place Medal"
|
||||
},
|
||||
{
|
||||
"emoji": "🥈",
|
||||
"title": "2nd Place Medal"
|
||||
},
|
||||
{
|
||||
"emoji": "🥉",
|
||||
"title": "3rd Place Medal"
|
||||
},
|
||||
{
|
||||
"emoji": "⚽",
|
||||
"title": "Soccer Ball"
|
||||
},
|
||||
{
|
||||
"emoji": "⚾",
|
||||
"title": "Baseball"
|
||||
},
|
||||
{
|
||||
"emoji": "🥎",
|
||||
"title": "Softball"
|
||||
},
|
||||
{
|
||||
"emoji": "🏀",
|
||||
"title": "Basketball"
|
||||
},
|
||||
{
|
||||
"emoji": "🏐",
|
||||
"title": "Volleyball"
|
||||
},
|
||||
{
|
||||
"emoji": "🏈",
|
||||
"title": "American Football"
|
||||
},
|
||||
{
|
||||
"emoji": "🏉",
|
||||
"title": "Rugby Football"
|
||||
},
|
||||
{
|
||||
"emoji": "🎾",
|
||||
"title": "Tennis"
|
||||
},
|
||||
{
|
||||
"emoji": "🥏",
|
||||
"title": "Flying Disc"
|
||||
},
|
||||
{
|
||||
"emoji": "🎳",
|
||||
"title": "Bowling"
|
||||
},
|
||||
{
|
||||
"emoji": "🏏",
|
||||
"title": "Cricket Game"
|
||||
},
|
||||
{
|
||||
"emoji": "🏑",
|
||||
"title": "Field Hockey"
|
||||
},
|
||||
{
|
||||
"emoji": "🏒",
|
||||
"title": "Ice Hockey"
|
||||
},
|
||||
{
|
||||
"emoji": "🥍",
|
||||
"title": "Lacrosse"
|
||||
},
|
||||
{
|
||||
"emoji": "🏓",
|
||||
"title": "Ping Pong"
|
||||
},
|
||||
{
|
||||
"emoji": "🏸",
|
||||
"title": "Badminton"
|
||||
},
|
||||
{
|
||||
"emoji": "🥊",
|
||||
"title": "Boxing Glove"
|
||||
},
|
||||
{
|
||||
"emoji": "🥋",
|
||||
"title": "Martial Arts Uniform"
|
||||
},
|
||||
{
|
||||
"emoji": "🥅",
|
||||
"title": "Goal Net"
|
||||
},
|
||||
{
|
||||
"emoji": "⛳",
|
||||
"title": "Flag in Hole"
|
||||
},
|
||||
{
|
||||
"emoji": "⛸️",
|
||||
"title": "Ice Skate"
|
||||
},
|
||||
{
|
||||
"emoji": "🎣",
|
||||
"title": "Fishing Pole"
|
||||
},
|
||||
{
|
||||
"emoji": "🎽",
|
||||
"title": "Running Shirt"
|
||||
},
|
||||
{
|
||||
"emoji": "🎿",
|
||||
"title": "Skis"
|
||||
},
|
||||
{
|
||||
"emoji": "🛷",
|
||||
"title": "Sled"
|
||||
},
|
||||
{
|
||||
"emoji": "🥌",
|
||||
"title": "Curling Stone"
|
||||
},
|
||||
{
|
||||
"emoji": "🎯",
|
||||
"title": "Bullseye"
|
||||
},
|
||||
{
|
||||
"emoji": "🎱",
|
||||
"title": "Pool 8 Ball"
|
||||
},
|
||||
{
|
||||
"emoji": "🎮",
|
||||
"title": "Video Game"
|
||||
},
|
||||
{
|
||||
"emoji": "🎰",
|
||||
"title": "Slot Machine"
|
||||
},
|
||||
{
|
||||
"emoji": "🎲",
|
||||
"title": "Game Die"
|
||||
},
|
||||
{
|
||||
"emoji": "🧩",
|
||||
"title": "Puzzle Piece"
|
||||
},
|
||||
{
|
||||
"emoji": "♟️",
|
||||
"title": "Chess Pawn"
|
||||
},
|
||||
{
|
||||
"emoji": "🎭",
|
||||
"title": "Performing Arts"
|
||||
},
|
||||
{
|
||||
"emoji": "🎨",
|
||||
"title": "Artist Palette"
|
||||
},
|
||||
{
|
||||
"emoji": "🧵",
|
||||
"title": "Thread"
|
||||
},
|
||||
{
|
||||
"emoji": "🧶",
|
||||
"title": "Yarn"
|
||||
},
|
||||
{
|
||||
"emoji": "🎼",
|
||||
"title": "Musical Score"
|
||||
},
|
||||
{
|
||||
"emoji": "🎤",
|
||||
"title": "Microphone"
|
||||
},
|
||||
{
|
||||
"emoji": "🎧",
|
||||
"title": "Headphone"
|
||||
},
|
||||
{
|
||||
"emoji": "🎷",
|
||||
"title": "Saxophone"
|
||||
},
|
||||
{
|
||||
"emoji": "🪗",
|
||||
"title": "Accordion"
|
||||
},
|
||||
{
|
||||
"emoji": "🎸",
|
||||
"title": "Guitar"
|
||||
},
|
||||
{
|
||||
"emoji": "🎹",
|
||||
"title": "Musical Keyboard"
|
||||
},
|
||||
{
|
||||
"emoji": "🎺",
|
||||
"title": "Trumpet"
|
||||
},
|
||||
{
|
||||
"emoji": "🎻",
|
||||
"title": "Violin"
|
||||
},
|
||||
{
|
||||
"emoji": "🥁",
|
||||
"title": "Drum"
|
||||
},
|
||||
{
|
||||
"emoji": "🪘",
|
||||
"title": "Long Drum"
|
||||
},
|
||||
{
|
||||
"emoji": "🎬",
|
||||
"title": "Clapper Board"
|
||||
},
|
||||
{
|
||||
"emoji": "🏹",
|
||||
"title": "Bow and Arrow"
|
||||
}
|
||||
],
|
||||
'Travel-places': [
|
||||
{
|
||||
"emoji": "🚣",
|
||||
"title": "Person Rowing Boat"
|
||||
},
|
||||
{
|
||||
"emoji": "🗾",
|
||||
"title": "Map of Japan"
|
||||
},
|
||||
{
|
||||
"emoji": "🏔️",
|
||||
"title": "Snow-Capped Mountain"
|
||||
},
|
||||
{
|
||||
"emoji": "⛰️",
|
||||
"title": "Mountain"
|
||||
},
|
||||
{
|
||||
"emoji": "🌋",
|
||||
"title": "Volcano"
|
||||
},
|
||||
{
|
||||
"emoji": "🗻",
|
||||
"title": "Mount Fuji"
|
||||
},
|
||||
{
|
||||
"emoji": "🏕️",
|
||||
"title": "Camping"
|
||||
},
|
||||
{
|
||||
"emoji": "🏖️",
|
||||
"title": "Beach with Umbrella"
|
||||
},
|
||||
{
|
||||
"emoji": "🏜️",
|
||||
"title": "Desert"
|
||||
},
|
||||
{
|
||||
"emoji": "🏝️",
|
||||
"title": "Desert Island"
|
||||
},
|
||||
{
|
||||
"emoji": "🏞️",
|
||||
"title": "National Park"
|
||||
},
|
||||
{
|
||||
"emoji": "🏟️",
|
||||
"title": "Stadium"
|
||||
},
|
||||
{
|
||||
"emoji": "🏛️",
|
||||
"title": "Classical Building"
|
||||
},
|
||||
{
|
||||
"emoji": "🏗️",
|
||||
"title": "Building Construction"
|
||||
},
|
||||
{
|
||||
"emoji": "🛖",
|
||||
"title": "Hut"
|
||||
},
|
||||
{
|
||||
"emoji": "🏘️",
|
||||
"title": "Houses"
|
||||
},
|
||||
{
|
||||
"emoji": "🏚️",
|
||||
"title": "Derelict House"
|
||||
},
|
||||
{
|
||||
"emoji": "🏠",
|
||||
"title": "House"
|
||||
},
|
||||
{
|
||||
"emoji": "🏡",
|
||||
"title": "House with Garden"
|
||||
},
|
||||
{
|
||||
"emoji": "🏢",
|
||||
"title": "Office Building"
|
||||
},
|
||||
{
|
||||
"emoji": "🏣",
|
||||
"title": "Japanese Post Office"
|
||||
},
|
||||
{
|
||||
"emoji": "🏤",
|
||||
"title": "Post Office"
|
||||
},
|
||||
{
|
||||
"emoji": "🏥",
|
||||
"title": "Hospital"
|
||||
},
|
||||
{
|
||||
"emoji": "🏦",
|
||||
"title": "Bank"
|
||||
},
|
||||
{
|
||||
"emoji": "🏨",
|
||||
"title": "Hotel"
|
||||
},
|
||||
{
|
||||
"emoji": "🏩",
|
||||
"title": "Love Hotel"
|
||||
},
|
||||
{
|
||||
"emoji": "🏪",
|
||||
"title": "Convenience Store"
|
||||
},
|
||||
{
|
||||
"emoji": "🏫",
|
||||
"title": "School"
|
||||
},
|
||||
{
|
||||
"emoji": "🏬",
|
||||
"title": "Department Store"
|
||||
},
|
||||
{
|
||||
"emoji": "🏭",
|
||||
"title": "Factory"
|
||||
},
|
||||
{
|
||||
"emoji": "🏯",
|
||||
"title": "Japanese Castle"
|
||||
},
|
||||
{
|
||||
"emoji": "🏰",
|
||||
"title": "Castle"
|
||||
},
|
||||
{
|
||||
"emoji": "💒",
|
||||
"title": "Wedding"
|
||||
},
|
||||
{
|
||||
"emoji": "🗼",
|
||||
"title": "Tokyo Tower"
|
||||
},
|
||||
{
|
||||
"emoji": "🗽",
|
||||
"title": "Statue of Liberty"
|
||||
},
|
||||
{
|
||||
"emoji": "⛪",
|
||||
"title": "Church"
|
||||
},
|
||||
{
|
||||
"emoji": "🕌",
|
||||
"title": "Mosque"
|
||||
},
|
||||
{
|
||||
"emoji": "🛕",
|
||||
"title": "Hindu Temple"
|
||||
},
|
||||
{
|
||||
"emoji": "🕍",
|
||||
"title": "Synagogue"
|
||||
},
|
||||
{
|
||||
"emoji": "⛩️",
|
||||
"title": "Shinto Shrine"
|
||||
},
|
||||
{
|
||||
"emoji": "🕋",
|
||||
"title": "Kaaba"
|
||||
},
|
||||
{
|
||||
"emoji": "⛲",
|
||||
"title": "Fountain"
|
||||
},
|
||||
{
|
||||
"emoji": "⛺",
|
||||
"title": "Tent"
|
||||
},
|
||||
{
|
||||
"emoji": "🌁",
|
||||
"title": "Foggy"
|
||||
},
|
||||
{
|
||||
"emoji": "🌃",
|
||||
"title": "Night with Stars"
|
||||
},
|
||||
{
|
||||
"emoji": "🏙️",
|
||||
"title": "Cityscape"
|
||||
},
|
||||
{
|
||||
"emoji": "🌄",
|
||||
"title": "Sunrise Over Mountains"
|
||||
},
|
||||
{
|
||||
"emoji": "🌅",
|
||||
"title": "Sunrise"
|
||||
},
|
||||
{
|
||||
"emoji": "🌆",
|
||||
"title": "Cityscape at Dusk"
|
||||
},
|
||||
{
|
||||
"emoji": "🌇",
|
||||
"title": "Sunset"
|
||||
},
|
||||
{
|
||||
"emoji": "🌉",
|
||||
"title": "Bridge at Night"
|
||||
},
|
||||
{
|
||||
"emoji": "🎠",
|
||||
"title": "Carousel Horse"
|
||||
},
|
||||
{
|
||||
"emoji": "🎡",
|
||||
"title": "Ferris Wheel"
|
||||
},
|
||||
{
|
||||
"emoji": "🎢",
|
||||
"title": "Roller Coaster"
|
||||
},
|
||||
{
|
||||
"emoji": "🚂",
|
||||
"title": "Locomotive"
|
||||
},
|
||||
{
|
||||
"emoji": "🚃",
|
||||
"title": "Railway Car"
|
||||
},
|
||||
{
|
||||
"emoji": "🚄",
|
||||
"title": "High-Speed Train"
|
||||
},
|
||||
{
|
||||
"emoji": "🚅",
|
||||
"title": "Bullet Train"
|
||||
},
|
||||
{
|
||||
"emoji": "🚆",
|
||||
"title": "Train"
|
||||
},
|
||||
{
|
||||
"emoji": "🚇",
|
||||
"title": "Metro"
|
||||
},
|
||||
{
|
||||
"emoji": "🚈",
|
||||
"title": "Light Rail"
|
||||
},
|
||||
{
|
||||
"emoji": "🚉",
|
||||
"title": "Station"
|
||||
},
|
||||
{
|
||||
"emoji": "🚊",
|
||||
"title": "Tram"
|
||||
},
|
||||
{
|
||||
"emoji": "🚝",
|
||||
"title": "Monorail"
|
||||
},
|
||||
{
|
||||
"emoji": "🚞",
|
||||
"title": "Mountain Railway"
|
||||
},
|
||||
{
|
||||
"emoji": "🚋",
|
||||
"title": "Tram Car"
|
||||
},
|
||||
{
|
||||
"emoji": "🚌",
|
||||
"title": "Bus"
|
||||
},
|
||||
{
|
||||
"emoji": "🚍",
|
||||
"title": "Oncoming Bus"
|
||||
},
|
||||
{
|
||||
"emoji": "🚎",
|
||||
"title": "Trolleybus"
|
||||
},
|
||||
{
|
||||
"emoji": "🚐",
|
||||
"title": "Minibus"
|
||||
},
|
||||
{
|
||||
"emoji": "🚑",
|
||||
"title": "Ambulance"
|
||||
},
|
||||
{
|
||||
"emoji": "🚒",
|
||||
"title": "Fire Engine"
|
||||
},
|
||||
{
|
||||
"emoji": "🚓",
|
||||
"title": "Police Car"
|
||||
},
|
||||
{
|
||||
"emoji": "🚔",
|
||||
"title": "Oncoming Police Car"
|
||||
},
|
||||
{
|
||||
"emoji": "🚕",
|
||||
"title": "Taxi"
|
||||
},
|
||||
{
|
||||
"emoji": "🚖",
|
||||
"title": "Oncoming Taxi"
|
||||
},
|
||||
{
|
||||
"emoji": "🚗",
|
||||
"title": "Automobile"
|
||||
},
|
||||
{
|
||||
"emoji": "🚘",
|
||||
"title": "Oncoming Automobile"
|
||||
},
|
||||
{
|
||||
"emoji": "🚙",
|
||||
"title": "Sport Utility Vehicle"
|
||||
},
|
||||
{
|
||||
"emoji": "🛻",
|
||||
"title": "Pickup Truck"
|
||||
},
|
||||
{
|
||||
"emoji": "🚚",
|
||||
"title": "Delivery Truck"
|
||||
},
|
||||
{
|
||||
"emoji": "🚛",
|
||||
"title": "Articulated Lorry"
|
||||
},
|
||||
{
|
||||
"emoji": "🚜",
|
||||
"title": "Tractor"
|
||||
},
|
||||
{
|
||||
"emoji": "🏎️",
|
||||
"title": "Racing Car"
|
||||
},
|
||||
{
|
||||
"emoji": "🏍️",
|
||||
"title": "Motorcycle"
|
||||
},
|
||||
{
|
||||
"emoji": "🛵",
|
||||
"title": "Motor Scooter"
|
||||
},
|
||||
{
|
||||
"emoji": "🛺",
|
||||
"title": "Auto Rickshaw"
|
||||
},
|
||||
{
|
||||
"emoji": "🚲",
|
||||
"title": "Bicycle"
|
||||
},
|
||||
{
|
||||
"emoji": "🛴",
|
||||
"title": "Kick Scooter"
|
||||
},
|
||||
{
|
||||
"emoji": "🚏",
|
||||
"title": "Bus Stop"
|
||||
},
|
||||
{
|
||||
"emoji": "🛣️",
|
||||
"title": "Motorway"
|
||||
},
|
||||
{
|
||||
"emoji": "🛤️",
|
||||
"title": "Railway Track"
|
||||
},
|
||||
{
|
||||
"emoji": "⛽",
|
||||
"title": "Fuel Pump"
|
||||
},
|
||||
{
|
||||
"emoji": "🚨",
|
||||
"title": "Police Car Light"
|
||||
},
|
||||
{
|
||||
"emoji": "🚥",
|
||||
"title": "Horizontal Traffic Light"
|
||||
},
|
||||
{
|
||||
"emoji": "🚦",
|
||||
"title": "Vertical Traffic Light"
|
||||
},
|
||||
{
|
||||
"emoji": "🚧",
|
||||
"title": "Construction"
|
||||
},
|
||||
{
|
||||
"emoji": "⚓",
|
||||
"title": "Anchor"
|
||||
},
|
||||
{
|
||||
"emoji": "⛵",
|
||||
"title": "Sailboat"
|
||||
},
|
||||
{
|
||||
"emoji": "🚤",
|
||||
"title": "Speedboat"
|
||||
},
|
||||
{
|
||||
"emoji": "🛳️",
|
||||
"title": "Passenger Ship"
|
||||
},
|
||||
{
|
||||
"emoji": "⛴️",
|
||||
"title": "Ferry"
|
||||
},
|
||||
{
|
||||
"emoji": "🛥️",
|
||||
"title": "Motor Boat"
|
||||
},
|
||||
{
|
||||
"emoji": "🚢",
|
||||
"title": "Ship"
|
||||
},
|
||||
{
|
||||
"emoji": "✈️",
|
||||
"title": "Airplane"
|
||||
},
|
||||
{
|
||||
"emoji": "🛩️",
|
||||
"title": "Small Airplane"
|
||||
},
|
||||
{
|
||||
"emoji": "🛫",
|
||||
"title": "Airplane Departure"
|
||||
},
|
||||
{
|
||||
"emoji": "🛬",
|
||||
"title": "Airplane Arrival"
|
||||
},
|
||||
{
|
||||
"emoji": "🪂",
|
||||
"title": "Parachute"
|
||||
},
|
||||
{
|
||||
"emoji": "💺",
|
||||
"title": "Seat"
|
||||
},
|
||||
{
|
||||
"emoji": "🚁",
|
||||
"title": "Helicopter"
|
||||
},
|
||||
{
|
||||
"emoji": "🚟",
|
||||
"title": "Suspension Railway"
|
||||
},
|
||||
{
|
||||
"emoji": "🚠",
|
||||
"title": "Mountain Cableway"
|
||||
},
|
||||
{
|
||||
"emoji": "🚡",
|
||||
"title": "Aerial Tramway"
|
||||
},
|
||||
{
|
||||
"emoji": "🛰️",
|
||||
"title": "Satellite"
|
||||
},
|
||||
{
|
||||
"emoji": "🚀",
|
||||
"title": "Rocket"
|
||||
},
|
||||
{
|
||||
"emoji": "🛸",
|
||||
"title": "Flying Saucer"
|
||||
},
|
||||
{
|
||||
"emoji": "🪐",
|
||||
"title": "Ringed Planet"
|
||||
},
|
||||
{
|
||||
"emoji": "🌠",
|
||||
"title": "Shooting Star"
|
||||
},
|
||||
{
|
||||
"emoji": "🌌",
|
||||
"title": "Milky Way"
|
||||
},
|
||||
{
|
||||
"emoji": "⛱️",
|
||||
"title": "Umbrella on Ground"
|
||||
},
|
||||
{
|
||||
"emoji": "🎆",
|
||||
"title": "Fireworks"
|
||||
},
|
||||
{
|
||||
"emoji": "🎇",
|
||||
"title": "Sparkler"
|
||||
},
|
||||
{
|
||||
"emoji": "🎑",
|
||||
"title": "Moon Viewing Ceremony"
|
||||
},
|
||||
{
|
||||
"emoji": "💴",
|
||||
"title": "Yen Banknote"
|
||||
},
|
||||
{
|
||||
"emoji": "💵",
|
||||
"title": "Dollar Banknote"
|
||||
},
|
||||
{
|
||||
"emoji": "💶",
|
||||
"title": "Euro Banknote"
|
||||
},
|
||||
{
|
||||
"emoji": "💷",
|
||||
"title": "Pound Banknote"
|
||||
},
|
||||
{
|
||||
"emoji": "🗿",
|
||||
"title": "Moai"
|
||||
},
|
||||
{
|
||||
"emoji": "🛂",
|
||||
"title": "Passport Control"
|
||||
},
|
||||
{
|
||||
"emoji": "🛃",
|
||||
"title": "Customs"
|
||||
},
|
||||
{
|
||||
"emoji": "🛄",
|
||||
"title": "Baggage Claim"
|
||||
},
|
||||
{
|
||||
"emoji": "🛅",
|
||||
"title": "Left Luggage"
|
||||
}
|
||||
],
|
||||
'Objects': [
|
||||
{
|
||||
"emoji": "💌",
|
||||
"title": "Love Letter"
|
||||
},
|
||||
{
|
||||
"emoji": "🕳️",
|
||||
"title": "Hole"
|
||||
},
|
||||
{
|
||||
"emoji": "💣",
|
||||
"title": "Bomb"
|
||||
},
|
||||
{
|
||||
"emoji": "🛀",
|
||||
"title": "Person Taking Bath"
|
||||
},
|
||||
{
|
||||
"emoji": "🛌",
|
||||
"title": "Person in Bed"
|
||||
},
|
||||
{
|
||||
"emoji": "🔪",
|
||||
"title": "Kitchen Knife"
|
||||
},
|
||||
{
|
||||
"emoji": "🏺",
|
||||
"title": "Amphora"
|
||||
},
|
||||
{
|
||||
"emoji": "🗺️",
|
||||
"title": "World Map"
|
||||
},
|
||||
{
|
||||
"emoji": "🧭",
|
||||
"title": "Compass"
|
||||
},
|
||||
{
|
||||
"emoji": "🧱",
|
||||
"title": "Brick"
|
||||
},
|
||||
{
|
||||
"emoji": "💈",
|
||||
"title": "Barber Pole"
|
||||
},
|
||||
{
|
||||
"emoji": "🦽",
|
||||
"title": "Manual Wheelchair"
|
||||
},
|
||||
{
|
||||
"emoji": "🦼",
|
||||
"title": "Motorized Wheelchair"
|
||||
},
|
||||
{
|
||||
"emoji": "🛢️",
|
||||
"title": "Oil Drum"
|
||||
},
|
||||
{
|
||||
"emoji": "🛎️",
|
||||
"title": "Bellhop Bell"
|
||||
},
|
||||
{
|
||||
"emoji": "🧳",
|
||||
"title": "Luggage"
|
||||
},
|
||||
{
|
||||
"emoji": "⌛",
|
||||
"title": "Hourglass Done"
|
||||
},
|
||||
{
|
||||
"emoji": "⏳",
|
||||
"title": "Hourglass Not Done"
|
||||
},
|
||||
{
|
||||
"emoji": "⌚",
|
||||
"title": "Watch"
|
||||
},
|
||||
{
|
||||
"emoji": "⏰",
|
||||
"title": "Alarm Clock"
|
||||
},
|
||||
{
|
||||
"emoji": "⏱️",
|
||||
"title": "Stopwatch"
|
||||
},
|
||||
{
|
||||
"emoji": "⏲️",
|
||||
"title": "Timer Clock"
|
||||
},
|
||||
{
|
||||
"emoji": "🕰️",
|
||||
"title": "Mantelpiece Clock"
|
||||
},
|
||||
{
|
||||
"emoji": "🌡️",
|
||||
"title": "Thermometer"
|
||||
},
|
||||
{
|
||||
"emoji": "⛱️",
|
||||
"title": "Umbrella on Ground"
|
||||
},
|
||||
{
|
||||
"emoji": "🧨",
|
||||
"title": "Firecracker"
|
||||
},
|
||||
{
|
||||
"emoji": "🎈",
|
||||
"title": "Balloon"
|
||||
},
|
||||
{
|
||||
"emoji": "🎉",
|
||||
"title": "Party Popper"
|
||||
},
|
||||
{
|
||||
"emoji": "🎊",
|
||||
"title": "Confetti Ball"
|
||||
},
|
||||
{
|
||||
"emoji": "🎎",
|
||||
"title": "Japanese Dolls"
|
||||
},
|
||||
{
|
||||
"emoji": "🎏",
|
||||
"title": "Carp Streamer"
|
||||
},
|
||||
{
|
||||
"emoji": "🎐",
|
||||
"title": "Wind Chime"
|
||||
},
|
||||
{
|
||||
"emoji": "🧧",
|
||||
"title": "Red Envelope"
|
||||
},
|
||||
{
|
||||
"emoji": "🎀",
|
||||
"title": "Ribbon"
|
||||
},
|
||||
{
|
||||
"emoji": "🎁",
|
||||
"title": "Wrapped Gift"
|
||||
},
|
||||
{
|
||||
"emoji": "🤿",
|
||||
"title": "Diving Mask"
|
||||
},
|
||||
{
|
||||
"emoji": "🪀",
|
||||
"title": "Yo-Yo"
|
||||
},
|
||||
{
|
||||
"emoji": "🪁",
|
||||
"title": "Kite"
|
||||
},
|
||||
{
|
||||
"emoji": "🔮",
|
||||
"title": "Crystal Ball"
|
||||
},
|
||||
{
|
||||
"emoji": "🪄",
|
||||
"title": "Magic Wand"
|
||||
},
|
||||
{
|
||||
"emoji": "🧿",
|
||||
"title": "Nazar Amulet"
|
||||
},
|
||||
{
|
||||
"emoji": "🕹️",
|
||||
"title": "Joystick"
|
||||
},
|
||||
{
|
||||
"emoji": "🧸",
|
||||
"title": "Teddy Bear"
|
||||
},
|
||||
{
|
||||
"emoji": "🪅",
|
||||
"title": "Piñata"
|
||||
},
|
||||
{
|
||||
"emoji": "🪆",
|
||||
"title": "Nesting Dolls"
|
||||
},
|
||||
{
|
||||
"emoji": "🖼️",
|
||||
"title": "Framed Picture"
|
||||
},
|
||||
{
|
||||
"emoji": "🧵",
|
||||
"title": "Thread"
|
||||
},
|
||||
{
|
||||
"emoji": "🪡",
|
||||
"title": "Sewing Needle"
|
||||
},
|
||||
{
|
||||
"emoji": "🧶",
|
||||
"title": "Yarn"
|
||||
},
|
||||
{
|
||||
"emoji": "🪢",
|
||||
"title": "Knot"
|
||||
},
|
||||
{
|
||||
"emoji": "🛍️",
|
||||
"title": "Shopping Bags"
|
||||
},
|
||||
{
|
||||
"emoji": "📿",
|
||||
"title": "Prayer Beads"
|
||||
},
|
||||
{
|
||||
"emoji": "💎",
|
||||
"title": "Gem Stone"
|
||||
},
|
||||
{
|
||||
"emoji": "📯",
|
||||
"title": "Postal Horn"
|
||||
},
|
||||
{
|
||||
"emoji": "🎙️",
|
||||
"title": "Studio Microphone"
|
||||
},
|
||||
{
|
||||
"emoji": "🎚️",
|
||||
"title": "Level Slider"
|
||||
},
|
||||
{
|
||||
"emoji": "🎛️",
|
||||
"title": "Control Knobs"
|
||||
},
|
||||
{
|
||||
"emoji": "📻",
|
||||
"title": "Radio"
|
||||
},
|
||||
{
|
||||
"emoji": "🪕",
|
||||
"title": "Banjo"
|
||||
},
|
||||
{
|
||||
"emoji": "📱",
|
||||
"title": "Mobile Phone"
|
||||
},
|
||||
{
|
||||
"emoji": "📲",
|
||||
"title": "Mobile Phone with Arrow"
|
||||
},
|
||||
{
|
||||
"emoji": "☎️",
|
||||
"title": "Telephone"
|
||||
},
|
||||
{
|
||||
"emoji": "📞",
|
||||
"title": "Telephone Receiver"
|
||||
},
|
||||
{
|
||||
"emoji": "📟",
|
||||
"title": "Pager"
|
||||
},
|
||||
{
|
||||
"emoji": "📠",
|
||||
"title": "Fax Machine"
|
||||
},
|
||||
{
|
||||
"emoji": "🔋",
|
||||
"title": "Battery"
|
||||
},
|
||||
{
|
||||
"emoji": "🔌",
|
||||
"title": "Electric Plug"
|
||||
},
|
||||
{
|
||||
"emoji": "💻",
|
||||
"title": "Laptop"
|
||||
},
|
||||
{
|
||||
"emoji": "🖥️",
|
||||
"title": "Desktop Computer"
|
||||
},
|
||||
{
|
||||
"emoji": "🖨️",
|
||||
"title": "Printer"
|
||||
},
|
||||
{
|
||||
"emoji": "⌨️",
|
||||
"title": "Keyboard"
|
||||
},
|
||||
{
|
||||
"emoji": "🖱️",
|
||||
"title": "Computer Mouse"
|
||||
},
|
||||
{
|
||||
"emoji": "🖲️",
|
||||
"title": "Trackball"
|
||||
},
|
||||
{
|
||||
"emoji": "💽",
|
||||
"title": "Computer Disk"
|
||||
},
|
||||
{
|
||||
"emoji": "💾",
|
||||
"title": "Floppy Disk"
|
||||
},
|
||||
{
|
||||
"emoji": "💿",
|
||||
"title": "Optical Disk"
|
||||
},
|
||||
{
|
||||
"emoji": "📀",
|
||||
"title": "DVD"
|
||||
},
|
||||
{
|
||||
"emoji": "🧮",
|
||||
"title": "Abacus"
|
||||
},
|
||||
{
|
||||
"emoji": "🎥",
|
||||
"title": "Movie Camera"
|
||||
},
|
||||
{
|
||||
"emoji": "🎞️",
|
||||
"title": "Film Frames"
|
||||
},
|
||||
{
|
||||
"emoji": "📽️",
|
||||
"title": "Film Projector"
|
||||
},
|
||||
{
|
||||
"emoji": "📺",
|
||||
"title": "Television"
|
||||
},
|
||||
{
|
||||
"emoji": "📷",
|
||||
"title": "Camera"
|
||||
},
|
||||
{
|
||||
"emoji": "📸",
|
||||
"title": "Camera with Flash"
|
||||
},
|
||||
{
|
||||
"emoji": "📹",
|
||||
"title": "Video Camera"
|
||||
},
|
||||
{
|
||||
"emoji": "📼",
|
||||
"title": "Videocassette"
|
||||
},
|
||||
{
|
||||
"emoji": "🔍",
|
||||
"title": "Magnifying Glass Tilted Left"
|
||||
},
|
||||
{
|
||||
"emoji": "🔎",
|
||||
"title": "Magnifying Glass Tilted Right"
|
||||
},
|
||||
{
|
||||
"emoji": "🕯️",
|
||||
"title": "Candle"
|
||||
},
|
||||
{
|
||||
"emoji": "💡",
|
||||
"title": "Light Bulb"
|
||||
},
|
||||
{
|
||||
"emoji": "🔦",
|
||||
"title": "Flashlight"
|
||||
},
|
||||
{
|
||||
"emoji": "🏮",
|
||||
"title": "Red Paper Lantern"
|
||||
},
|
||||
{
|
||||
"emoji": "🪔",
|
||||
"title": "Diya Lamp"
|
||||
},
|
||||
{
|
||||
"emoji": "📔",
|
||||
"title": "Notebook with Decorative Cover"
|
||||
},
|
||||
{
|
||||
"emoji": "📕",
|
||||
"title": "Closed Book"
|
||||
},
|
||||
{
|
||||
"emoji": "📖",
|
||||
"title": "Open Book"
|
||||
},
|
||||
{
|
||||
"emoji": "📗",
|
||||
"title": "Green Book"
|
||||
},
|
||||
{
|
||||
"emoji": "📘",
|
||||
"title": "Blue Book"
|
||||
},
|
||||
{
|
||||
"emoji": "📙",
|
||||
"title": "Orange Book"
|
||||
},
|
||||
{
|
||||
"emoji": "📚",
|
||||
"title": "Books"
|
||||
},
|
||||
{
|
||||
"emoji": "📓",
|
||||
"title": "Notebook"
|
||||
},
|
||||
{
|
||||
"emoji": "📒",
|
||||
"title": "Ledger"
|
||||
},
|
||||
{
|
||||
"emoji": "📃",
|
||||
"title": "Page with Curl"
|
||||
},
|
||||
{
|
||||
"emoji": "📜",
|
||||
"title": "Scroll"
|
||||
},
|
||||
{
|
||||
"emoji": "📄",
|
||||
"title": "Page Facing Up"
|
||||
},
|
||||
{
|
||||
"emoji": "📰",
|
||||
"title": "Newspaper"
|
||||
},
|
||||
{
|
||||
"emoji": "🗞️",
|
||||
"title": "Rolled-Up Newspaper"
|
||||
},
|
||||
{
|
||||
"emoji": "📑",
|
||||
"title": "Bookmark Tabs"
|
||||
},
|
||||
{
|
||||
"emoji": "🔖",
|
||||
"title": "Bookmark"
|
||||
},
|
||||
{
|
||||
"emoji": "🏷️",
|
||||
"title": "Label"
|
||||
},
|
||||
{
|
||||
"emoji": "💰",
|
||||
"title": "Money Bag"
|
||||
},
|
||||
{
|
||||
"emoji": "🪙",
|
||||
"title": "Coin"
|
||||
},
|
||||
{
|
||||
"emoji": "💴",
|
||||
"title": "Yen Banknote"
|
||||
},
|
||||
{
|
||||
"emoji": "💵",
|
||||
"title": "Dollar Banknote"
|
||||
},
|
||||
{
|
||||
"emoji": "💶",
|
||||
"title": "Euro Banknote"
|
||||
},
|
||||
{
|
||||
"emoji": "💷",
|
||||
"title": "Pound Banknote"
|
||||
},
|
||||
{
|
||||
"emoji": "💸",
|
||||
"title": "Money with Wings"
|
||||
},
|
||||
{
|
||||
"emoji": "💳",
|
||||
"title": "Credit Card"
|
||||
},
|
||||
{
|
||||
"emoji": "🧾",
|
||||
"title": "Receipt"
|
||||
},
|
||||
{
|
||||
"emoji": "✉️",
|
||||
"title": "Envelope"
|
||||
},
|
||||
{
|
||||
"emoji": "📧",
|
||||
"title": "E-Mail"
|
||||
},
|
||||
{
|
||||
"emoji": "📨",
|
||||
"title": "Incoming Envelope"
|
||||
},
|
||||
{
|
||||
"emoji": "📩",
|
||||
"title": "Envelope with Arrow"
|
||||
},
|
||||
{
|
||||
"emoji": "📤",
|
||||
"title": "Outbox Tray"
|
||||
},
|
||||
{
|
||||
"emoji": "📥",
|
||||
"title": "Inbox Tray"
|
||||
},
|
||||
{
|
||||
"emoji": "📦",
|
||||
"title": "Package"
|
||||
},
|
||||
{
|
||||
"emoji": "📫",
|
||||
"title": "Closed Mailbox with Raised Flag"
|
||||
},
|
||||
{
|
||||
"emoji": "📪",
|
||||
"title": "Closed Mailbox with Lowered Flag"
|
||||
},
|
||||
{
|
||||
"emoji": "📬",
|
||||
"title": "Open Mailbox with Raised Flag"
|
||||
},
|
||||
{
|
||||
"emoji": "📭",
|
||||
"title": "Open Mailbox with Lowered Flag"
|
||||
},
|
||||
{
|
||||
"emoji": "📮",
|
||||
"title": "Postbox"
|
||||
},
|
||||
{
|
||||
"emoji": "🗳️",
|
||||
"title": "Ballot Box with Ballot"
|
||||
},
|
||||
{
|
||||
"emoji": "✏️",
|
||||
"title": "Pencil"
|
||||
},
|
||||
{
|
||||
"emoji": "✒️",
|
||||
"title": "Black Nib"
|
||||
},
|
||||
{
|
||||
"emoji": "🖋️",
|
||||
"title": "Fountain Pen"
|
||||
},
|
||||
{
|
||||
"emoji": "🖊️",
|
||||
"title": "Pen"
|
||||
},
|
||||
{
|
||||
"emoji": "🖌️",
|
||||
"title": "Paintbrush"
|
||||
},
|
||||
{
|
||||
"emoji": "🖍️",
|
||||
"title": "Crayon"
|
||||
},
|
||||
{
|
||||
"emoji": "📝",
|
||||
"title": "Memo"
|
||||
},
|
||||
{
|
||||
"emoji": "📁",
|
||||
"title": "File Folder"
|
||||
},
|
||||
{
|
||||
"emoji": "📂",
|
||||
"title": "Open File Folder"
|
||||
},
|
||||
{
|
||||
"emoji": "🗂️",
|
||||
"title": "Card Index Dividers"
|
||||
},
|
||||
{
|
||||
"emoji": "📅",
|
||||
"title": "Calendar"
|
||||
},
|
||||
{
|
||||
"emoji": "📆",
|
||||
"title": "Tear-Off Calendar"
|
||||
},
|
||||
{
|
||||
"emoji": "🗒️",
|
||||
"title": "Spiral Notepad"
|
||||
},
|
||||
{
|
||||
"emoji": "🗓️",
|
||||
"title": "Spiral Calendar"
|
||||
},
|
||||
{
|
||||
"emoji": "📇",
|
||||
"title": "Card Index"
|
||||
},
|
||||
{
|
||||
"emoji": "📈",
|
||||
"title": "Chart Increasing"
|
||||
},
|
||||
{
|
||||
"emoji": "📉",
|
||||
"title": "Chart Decreasing"
|
||||
},
|
||||
{
|
||||
"emoji": "📊",
|
||||
"title": "Bar Chart"
|
||||
},
|
||||
{
|
||||
"emoji": "📋",
|
||||
"title": "Clipboard"
|
||||
},
|
||||
{
|
||||
"emoji": "📌",
|
||||
"title": "Pushpin"
|
||||
},
|
||||
{
|
||||
"emoji": "📍",
|
||||
"title": "Round Pushpin"
|
||||
},
|
||||
{
|
||||
"emoji": "📎",
|
||||
"title": "Paperclip"
|
||||
},
|
||||
{
|
||||
"emoji": "🖇️",
|
||||
"title": "Linked Paperclips"
|
||||
},
|
||||
{
|
||||
"emoji": "📏",
|
||||
"title": "Straight Ruler"
|
||||
},
|
||||
{
|
||||
"emoji": "📐",
|
||||
"title": "Triangular Ruler"
|
||||
},
|
||||
{
|
||||
"emoji": "✂️",
|
||||
"title": "Scissors"
|
||||
},
|
||||
{
|
||||
"emoji": "🗃️",
|
||||
"title": "Card File Box"
|
||||
},
|
||||
{
|
||||
"emoji": "🗄️",
|
||||
"title": "File Cabinet"
|
||||
},
|
||||
{
|
||||
"emoji": "🗑️",
|
||||
"title": "Wastebasket"
|
||||
},
|
||||
{
|
||||
"emoji": "🔒",
|
||||
"title": "Locked"
|
||||
},
|
||||
{
|
||||
"emoji": "🔓",
|
||||
"title": "Unlocked"
|
||||
},
|
||||
{
|
||||
"emoji": "🔏",
|
||||
"title": "Locked with Pen"
|
||||
},
|
||||
{
|
||||
"emoji": "🔐",
|
||||
"title": "Locked with Key"
|
||||
},
|
||||
{
|
||||
"emoji": "🔑",
|
||||
"title": "Key"
|
||||
},
|
||||
{
|
||||
"emoji": "🗝️",
|
||||
"title": "Old Key"
|
||||
},
|
||||
{
|
||||
"emoji": "🔨",
|
||||
"title": "Hammer"
|
||||
},
|
||||
{
|
||||
"emoji": "🪓",
|
||||
"title": "Axe"
|
||||
},
|
||||
{
|
||||
"emoji": "⛏️",
|
||||
"title": "Pick"
|
||||
},
|
||||
{
|
||||
"emoji": "⚒️",
|
||||
"title": "Hammer and Pick"
|
||||
},
|
||||
{
|
||||
"emoji": "🛠️",
|
||||
"title": "Hammer and Wrench"
|
||||
},
|
||||
{
|
||||
"emoji": "🗡️",
|
||||
"title": "Dagger"
|
||||
},
|
||||
{
|
||||
"emoji": "⚔️",
|
||||
"title": "Crossed Swords"
|
||||
},
|
||||
{
|
||||
"emoji": "🔫",
|
||||
"title": "Water Pistol"
|
||||
},
|
||||
{
|
||||
"emoji": "🪃",
|
||||
"title": "Boomerang"
|
||||
},
|
||||
{
|
||||
"emoji": "🛡️",
|
||||
"title": "Shield"
|
||||
},
|
||||
{
|
||||
"emoji": "🪚",
|
||||
"title": "Carpentry Saw"
|
||||
},
|
||||
{
|
||||
"emoji": "🔧",
|
||||
"title": "Wrench"
|
||||
},
|
||||
{
|
||||
"emoji": "🪛",
|
||||
"title": "Screwdriver"
|
||||
},
|
||||
{
|
||||
"emoji": "🔩",
|
||||
"title": "Nut and Bolt"
|
||||
},
|
||||
{
|
||||
"emoji": "⚙️",
|
||||
"title": "Gear"
|
||||
},
|
||||
{
|
||||
"emoji": "🗜️",
|
||||
"title": "Clamp"
|
||||
},
|
||||
{
|
||||
"emoji": "⚖️",
|
||||
"title": "Balance Scale"
|
||||
},
|
||||
{
|
||||
"emoji": "🦯",
|
||||
"title": "White Cane"
|
||||
},
|
||||
{
|
||||
"emoji": "🔗",
|
||||
"title": "Link"
|
||||
},
|
||||
{
|
||||
"emoji": "⛓️",
|
||||
"title": "Chains"
|
||||
},
|
||||
{
|
||||
"emoji": "🪝",
|
||||
"title": "Hook"
|
||||
},
|
||||
{
|
||||
"emoji": "🧰",
|
||||
"title": "Toolbox"
|
||||
},
|
||||
{
|
||||
"emoji": "🧲",
|
||||
"title": "Magnet"
|
||||
},
|
||||
{
|
||||
"emoji": "🪜",
|
||||
"title": "Ladder"
|
||||
},
|
||||
{
|
||||
"emoji": "⚗️",
|
||||
"title": "Alembic"
|
||||
},
|
||||
{
|
||||
"emoji": "🧪",
|
||||
"title": "Test Tube"
|
||||
},
|
||||
{
|
||||
"emoji": "🧫",
|
||||
"title": "Petri Dish"
|
||||
},
|
||||
{
|
||||
"emoji": "🧬",
|
||||
"title": "DNA"
|
||||
},
|
||||
{
|
||||
"emoji": "🔬",
|
||||
"title": "Microscope"
|
||||
},
|
||||
{
|
||||
"emoji": "🔭",
|
||||
"title": "Telescope"
|
||||
},
|
||||
{
|
||||
"emoji": "📡",
|
||||
"title": "Satellite Antenna"
|
||||
},
|
||||
{
|
||||
"emoji": "💉",
|
||||
"title": "Syringe"
|
||||
},
|
||||
{
|
||||
"emoji": "🩸",
|
||||
"title": "Drop of Blood"
|
||||
},
|
||||
{
|
||||
"emoji": "💊",
|
||||
"title": "Pill"
|
||||
},
|
||||
{
|
||||
"emoji": "🩹",
|
||||
"title": "Adhesive Bandage"
|
||||
},
|
||||
{
|
||||
"emoji": "🩺",
|
||||
"title": "Stethoscope"
|
||||
},
|
||||
{
|
||||
"emoji": "🚪",
|
||||
"title": "Door"
|
||||
},
|
||||
{
|
||||
"emoji": "🪞",
|
||||
"title": "Mirror"
|
||||
},
|
||||
{
|
||||
"emoji": "🪟",
|
||||
"title": "Window"
|
||||
},
|
||||
{
|
||||
"emoji": "🛏️",
|
||||
"title": "Bed"
|
||||
},
|
||||
{
|
||||
"emoji": "🛋️",
|
||||
"title": "Couch and Lamp"
|
||||
},
|
||||
{
|
||||
"emoji": "🪑",
|
||||
"title": "Chair"
|
||||
},
|
||||
{
|
||||
"emoji": "🚽",
|
||||
"title": "Toilet"
|
||||
},
|
||||
{
|
||||
"emoji": "🪠",
|
||||
"title": "Plunger"
|
||||
},
|
||||
{
|
||||
"emoji": "🚿",
|
||||
"title": "Shower"
|
||||
},
|
||||
{
|
||||
"emoji": "🛁",
|
||||
"title": "Bathtub"
|
||||
},
|
||||
{
|
||||
"emoji": "🪤",
|
||||
"title": "Mouse Trap"
|
||||
},
|
||||
{
|
||||
"emoji": "🪒",
|
||||
"title": "Razor"
|
||||
},
|
||||
{
|
||||
"emoji": "🧴",
|
||||
"title": "Lotion Bottle"
|
||||
},
|
||||
{
|
||||
"emoji": "🧷",
|
||||
"title": "Safety Pin"
|
||||
},
|
||||
{
|
||||
"emoji": "🧹",
|
||||
"title": "Broom"
|
||||
},
|
||||
{
|
||||
"emoji": "🧺",
|
||||
"title": "Basket"
|
||||
},
|
||||
{
|
||||
"emoji": "🧻",
|
||||
"title": "Roll of Paper"
|
||||
},
|
||||
{
|
||||
"emoji": "🪣",
|
||||
"title": "Bucket"
|
||||
},
|
||||
{
|
||||
"emoji": "🧼",
|
||||
"title": "Soap"
|
||||
},
|
||||
{
|
||||
"emoji": "🪥",
|
||||
"title": "Toothbrush"
|
||||
},
|
||||
{
|
||||
"emoji": "🧽",
|
||||
"title": "Sponge"
|
||||
},
|
||||
{
|
||||
"emoji": "🧯",
|
||||
"title": "Fire Extinguisher"
|
||||
},
|
||||
{
|
||||
"emoji": "🛒",
|
||||
"title": "Shopping Cart"
|
||||
},
|
||||
{
|
||||
"emoji": "🚬",
|
||||
"title": "Cigarette"
|
||||
},
|
||||
{
|
||||
"emoji": "⚰️",
|
||||
"title": "Coffin"
|
||||
},
|
||||
{
|
||||
"emoji": "🪦",
|
||||
"title": "Headstone"
|
||||
},
|
||||
{
|
||||
"emoji": "⚱️",
|
||||
"title": "Funeral Urn"
|
||||
},
|
||||
{
|
||||
"emoji": "🗿",
|
||||
"title": "Moai"
|
||||
},
|
||||
{
|
||||
"emoji": "🪧",
|
||||
"title": "Placard"
|
||||
},
|
||||
{
|
||||
"emoji": "🚰",
|
||||
"title": "Potable Water"
|
||||
}
|
||||
],
|
||||
'Symbols': [
|
||||
{
|
||||
"emoji": "💘",
|
||||
"title": "Heart with Arrow"
|
||||
},
|
||||
{
|
||||
"emoji": "💝",
|
||||
"title": "Heart with Ribbon"
|
||||
},
|
||||
{
|
||||
"emoji": "💖",
|
||||
"title": "Sparkling Heart"
|
||||
},
|
||||
{
|
||||
"emoji": "💗",
|
||||
"title": "Growing Heart"
|
||||
},
|
||||
{
|
||||
"emoji": "💓",
|
||||
"title": "Beating Heart"
|
||||
},
|
||||
{
|
||||
"emoji": "💞",
|
||||
"title": "Revolving Hearts"
|
||||
},
|
||||
{
|
||||
"emoji": "💕",
|
||||
"title": "Two Hearts"
|
||||
},
|
||||
{
|
||||
"emoji": "💟",
|
||||
"title": "Heart Decoration"
|
||||
},
|
||||
{
|
||||
"emoji": "❣️",
|
||||
"title": "Heart Exclamation"
|
||||
},
|
||||
{
|
||||
"emoji": "💔",
|
||||
"title": "Broken Heart"
|
||||
},
|
||||
{
|
||||
"emoji": "❤️🔥",
|
||||
"title": "Heart on Fire"
|
||||
},
|
||||
{
|
||||
"emoji": "❤️🩹",
|
||||
"title": "Mending Heart"
|
||||
},
|
||||
{
|
||||
"emoji": "❤️",
|
||||
"title": "Red Heart"
|
||||
},
|
||||
{
|
||||
"emoji": "🧡",
|
||||
"title": "Orange Heart"
|
||||
},
|
||||
{
|
||||
"emoji": "💛",
|
||||
"title": "Yellow Heart"
|
||||
},
|
||||
{
|
||||
"emoji": "💚",
|
||||
"title": "Green Heart"
|
||||
},
|
||||
{
|
||||
"emoji": "💙",
|
||||
"title": "Blue Heart"
|
||||
},
|
||||
{
|
||||
"emoji": "💜",
|
||||
"title": "Purple Heart"
|
||||
},
|
||||
{
|
||||
"emoji": "🤎",
|
||||
"title": "Brown Heart"
|
||||
},
|
||||
{
|
||||
"emoji": "🖤",
|
||||
"title": "Black Heart"
|
||||
},
|
||||
{
|
||||
"emoji": "🤍",
|
||||
"title": "White Heart"
|
||||
},
|
||||
{
|
||||
"emoji": "💯",
|
||||
"title": "Hundred Points"
|
||||
},
|
||||
{
|
||||
"emoji": "💢",
|
||||
"title": "Anger Symbol"
|
||||
},
|
||||
{
|
||||
"emoji": "💬",
|
||||
"title": "Speech Balloon"
|
||||
},
|
||||
{
|
||||
"emoji": "👁️🗨️",
|
||||
"title": "Eye in Speech Bubble"
|
||||
},
|
||||
{
|
||||
"emoji": "🗨️",
|
||||
"title": "Left Speech Bubble"
|
||||
},
|
||||
{
|
||||
"emoji": "🗯️",
|
||||
"title": "Right Anger Bubble"
|
||||
},
|
||||
{
|
||||
"emoji": "💭",
|
||||
"title": "Thought Balloon"
|
||||
},
|
||||
{
|
||||
"emoji": "💤",
|
||||
"title": "Zzz"
|
||||
},
|
||||
{
|
||||
"emoji": "💮",
|
||||
"title": "White Flower"
|
||||
},
|
||||
{
|
||||
"emoji": "♨️",
|
||||
"title": "Hot Springs"
|
||||
},
|
||||
{
|
||||
"emoji": "💈",
|
||||
"title": "Barber Pole"
|
||||
},
|
||||
{
|
||||
"emoji": "🛑",
|
||||
"title": "Stop Sign"
|
||||
},
|
||||
{
|
||||
"emoji": "🕛",
|
||||
"title": "Twelve O’Clock"
|
||||
},
|
||||
{
|
||||
"emoji": "🕧",
|
||||
"title": "Twelve-Thirty"
|
||||
},
|
||||
{
|
||||
"emoji": "🕐",
|
||||
"title": "One O’Clock"
|
||||
},
|
||||
{
|
||||
"emoji": "🕜",
|
||||
"title": "One-Thirty"
|
||||
},
|
||||
{
|
||||
"emoji": "🕑",
|
||||
"title": "Two O’Clock"
|
||||
},
|
||||
{
|
||||
"emoji": "🕝",
|
||||
"title": "Two-Thirty"
|
||||
},
|
||||
{
|
||||
"emoji": "🕒",
|
||||
"title": "Three O’Clock"
|
||||
},
|
||||
{
|
||||
"emoji": "🕞",
|
||||
"title": "Three-Thirty"
|
||||
},
|
||||
{
|
||||
"emoji": "🕓",
|
||||
"title": "Four O’Clock"
|
||||
},
|
||||
{
|
||||
"emoji": "🕟",
|
||||
"title": "Four-Thirty"
|
||||
},
|
||||
{
|
||||
"emoji": "🕔",
|
||||
"title": "Five O’Clock"
|
||||
},
|
||||
{
|
||||
"emoji": "🕠",
|
||||
"title": "Five-Thirty"
|
||||
},
|
||||
{
|
||||
"emoji": "🕕",
|
||||
"title": "Six O’Clock"
|
||||
},
|
||||
{
|
||||
"emoji": "🕡",
|
||||
"title": "Six-Thirty"
|
||||
},
|
||||
{
|
||||
"emoji": "🕖",
|
||||
"title": "Seven O’Clock"
|
||||
},
|
||||
{
|
||||
"emoji": "🕢",
|
||||
"title": "Seven-Thirty"
|
||||
},
|
||||
{
|
||||
"emoji": "🕗",
|
||||
"title": "Eight O’Clock"
|
||||
},
|
||||
{
|
||||
"emoji": "🕣",
|
||||
"title": "Eight-Thirty"
|
||||
},
|
||||
{
|
||||
"emoji": "🕘",
|
||||
"title": "Nine O’Clock"
|
||||
},
|
||||
{
|
||||
"emoji": "🕤",
|
||||
"title": "Nine-Thirty"
|
||||
},
|
||||
{
|
||||
"emoji": "🕙",
|
||||
"title": "Ten O’Clock"
|
||||
},
|
||||
{
|
||||
"emoji": "🕥",
|
||||
"title": "Ten-Thirty"
|
||||
},
|
||||
{
|
||||
"emoji": "🕚",
|
||||
"title": "Eleven O’Clock"
|
||||
},
|
||||
{
|
||||
"emoji": "🕦",
|
||||
"title": "Eleven-Thirty"
|
||||
},
|
||||
{
|
||||
"emoji": "🌀",
|
||||
"title": "Cyclone"
|
||||
},
|
||||
{
|
||||
"emoji": "♠️",
|
||||
"title": "Spade Suit"
|
||||
},
|
||||
{
|
||||
"emoji": "♥️",
|
||||
"title": "Heart Suit"
|
||||
},
|
||||
{
|
||||
"emoji": "♦️",
|
||||
"title": "Diamond Suit"
|
||||
},
|
||||
{
|
||||
"emoji": "♣️",
|
||||
"title": "Club Suit"
|
||||
},
|
||||
{
|
||||
"emoji": "🃏",
|
||||
"title": "Joker"
|
||||
},
|
||||
{
|
||||
"emoji": "🀄",
|
||||
"title": "Mahjong Red Dragon"
|
||||
},
|
||||
{
|
||||
"emoji": "🎴",
|
||||
"title": "Flower Playing Cards"
|
||||
},
|
||||
{
|
||||
"emoji": "🔇",
|
||||
"title": "Muted Speaker"
|
||||
},
|
||||
{
|
||||
"emoji": "🔈",
|
||||
"title": "Speaker Low Volume"
|
||||
},
|
||||
{
|
||||
"emoji": "🔉",
|
||||
"title": "Speaker Medium Volume"
|
||||
},
|
||||
{
|
||||
"emoji": "🔊",
|
||||
"title": "Speaker High Volume"
|
||||
},
|
||||
{
|
||||
"emoji": "📢",
|
||||
"title": "Loudspeaker"
|
||||
},
|
||||
{
|
||||
"emoji": "📣",
|
||||
"title": "Megaphone"
|
||||
},
|
||||
{
|
||||
"emoji": "📯",
|
||||
"title": "Postal Horn"
|
||||
},
|
||||
{
|
||||
"emoji": "🔔",
|
||||
"title": "Bell"
|
||||
},
|
||||
{
|
||||
"emoji": "🔕",
|
||||
"title": "Bell with Slash"
|
||||
},
|
||||
{
|
||||
"emoji": "🎵",
|
||||
"title": "Musical Note"
|
||||
},
|
||||
{
|
||||
"emoji": "🎶",
|
||||
"title": "Musical Notes"
|
||||
},
|
||||
{
|
||||
"emoji": "💹",
|
||||
"title": "Chart Increasing with Yen"
|
||||
},
|
||||
{
|
||||
"emoji": "🛗",
|
||||
"title": "Elevator"
|
||||
},
|
||||
{
|
||||
"emoji": "🏧",
|
||||
"title": "ATM Sign"
|
||||
},
|
||||
{
|
||||
"emoji": "🚮",
|
||||
"title": "Litter in Bin Sign"
|
||||
},
|
||||
{
|
||||
"emoji": "🚰",
|
||||
"title": "Potable Water"
|
||||
},
|
||||
{
|
||||
"emoji": "♿",
|
||||
"title": "Wheelchair Symbol"
|
||||
},
|
||||
{
|
||||
"emoji": "🚹",
|
||||
"title": "Men’s Room"
|
||||
},
|
||||
{
|
||||
"emoji": "🚺",
|
||||
"title": "Women’s Room"
|
||||
},
|
||||
{
|
||||
"emoji": "🚻",
|
||||
"title": "Restroom"
|
||||
},
|
||||
{
|
||||
"emoji": "🚼",
|
||||
"title": "Baby Symbol"
|
||||
},
|
||||
{
|
||||
"emoji": "🚾",
|
||||
"title": "Water Closet"
|
||||
},
|
||||
{
|
||||
"emoji": "⚠️",
|
||||
"title": "Warning"
|
||||
},
|
||||
{
|
||||
"emoji": "🚸",
|
||||
"title": "Children Crossing"
|
||||
},
|
||||
{
|
||||
"emoji": "⛔",
|
||||
"title": "No Entry"
|
||||
},
|
||||
{
|
||||
"emoji": "🚫",
|
||||
"title": "Prohibited"
|
||||
},
|
||||
{
|
||||
"emoji": "🚳",
|
||||
"title": "No Bicycles"
|
||||
},
|
||||
{
|
||||
"emoji": "🚭",
|
||||
"title": "No Smoking"
|
||||
},
|
||||
{
|
||||
"emoji": "🚯",
|
||||
"title": "No Littering"
|
||||
},
|
||||
{
|
||||
"emoji": "🚱",
|
||||
"title": "Non-Potable Water"
|
||||
},
|
||||
{
|
||||
"emoji": "🚷",
|
||||
"title": "No Pedestrians"
|
||||
},
|
||||
{
|
||||
"emoji": "📵",
|
||||
"title": "No Mobile Phones"
|
||||
},
|
||||
{
|
||||
"emoji": "🔞",
|
||||
"title": "No One Under Eighteen"
|
||||
},
|
||||
{
|
||||
"emoji": "☢️",
|
||||
"title": "Radioactive"
|
||||
},
|
||||
{
|
||||
"emoji": "☣️",
|
||||
"title": "Biohazard"
|
||||
},
|
||||
{
|
||||
"emoji": "⬆️",
|
||||
"title": "Up Arrow"
|
||||
},
|
||||
{
|
||||
"emoji": "↗️",
|
||||
"title": "Up-Right Arrow"
|
||||
},
|
||||
{
|
||||
"emoji": "➡️",
|
||||
"title": "Right Arrow"
|
||||
},
|
||||
{
|
||||
"emoji": "↘️",
|
||||
"title": "Down-Right Arrow"
|
||||
},
|
||||
{
|
||||
"emoji": "⬇️",
|
||||
"title": "Down Arrow"
|
||||
},
|
||||
{
|
||||
"emoji": "↙️",
|
||||
"title": "Down-Left Arrow"
|
||||
},
|
||||
{
|
||||
"emoji": "⬅️",
|
||||
"title": "Left Arrow"
|
||||
},
|
||||
{
|
||||
"emoji": "↖️",
|
||||
"title": "Up-Left Arrow"
|
||||
},
|
||||
{
|
||||
"emoji": "↕️",
|
||||
"title": "Up-Down Arrow"
|
||||
},
|
||||
{
|
||||
"emoji": "↔️",
|
||||
"title": "Left-Right Arrow"
|
||||
},
|
||||
{
|
||||
"emoji": "↩️",
|
||||
"title": "Right Arrow Curving Left"
|
||||
},
|
||||
{
|
||||
"emoji": "↪️",
|
||||
"title": "Left Arrow Curving Right"
|
||||
},
|
||||
{
|
||||
"emoji": "⤴️",
|
||||
"title": "Right Arrow Curving Up"
|
||||
},
|
||||
{
|
||||
"emoji": "⤵️",
|
||||
"title": "Right Arrow Curving Down"
|
||||
},
|
||||
{
|
||||
"emoji": "🔃",
|
||||
"title": "Clockwise Vertical Arrows"
|
||||
},
|
||||
{
|
||||
"emoji": "🔄",
|
||||
"title": "Counterclockwise Arrows Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🔙",
|
||||
"title": "Back Arrow"
|
||||
},
|
||||
{
|
||||
"emoji": "🔚",
|
||||
"title": "End Arrow"
|
||||
},
|
||||
{
|
||||
"emoji": "🔛",
|
||||
"title": "On! Arrow"
|
||||
},
|
||||
{
|
||||
"emoji": "🔜",
|
||||
"title": "Soon Arrow"
|
||||
},
|
||||
{
|
||||
"emoji": "🔝",
|
||||
"title": "Top Arrow"
|
||||
},
|
||||
{
|
||||
"emoji": "🛐",
|
||||
"title": "Place of Worship"
|
||||
},
|
||||
{
|
||||
"emoji": "⚛️",
|
||||
"title": "Atom Symbol"
|
||||
},
|
||||
{
|
||||
"emoji": "🕉️",
|
||||
"title": "Om"
|
||||
},
|
||||
{
|
||||
"emoji": "✡️",
|
||||
"title": "Star of David"
|
||||
},
|
||||
{
|
||||
"emoji": "☸️",
|
||||
"title": "Wheel of Dharma"
|
||||
},
|
||||
{
|
||||
"emoji": "☯️",
|
||||
"title": "Yin Yang"
|
||||
},
|
||||
{
|
||||
"emoji": "✝️",
|
||||
"title": "Latin Cross"
|
||||
},
|
||||
{
|
||||
"emoji": "☦️",
|
||||
"title": "Orthodox Cross"
|
||||
},
|
||||
{
|
||||
"emoji": "☪️",
|
||||
"title": "Star and Crescent"
|
||||
},
|
||||
{
|
||||
"emoji": "☮️",
|
||||
"title": "Peace Symbol"
|
||||
},
|
||||
{
|
||||
"emoji": "🕎",
|
||||
"title": "Menorah"
|
||||
},
|
||||
{
|
||||
"emoji": "🔯",
|
||||
"title": "Dotted Six-Pointed Star"
|
||||
},
|
||||
{
|
||||
"emoji": "♈",
|
||||
"title": "Aries"
|
||||
},
|
||||
{
|
||||
"emoji": "♉",
|
||||
"title": "Taurus"
|
||||
},
|
||||
{
|
||||
"emoji": "♊",
|
||||
"title": "Gemini"
|
||||
},
|
||||
{
|
||||
"emoji": "♋",
|
||||
"title": "Cancer"
|
||||
},
|
||||
{
|
||||
"emoji": "♌",
|
||||
"title": "Leo"
|
||||
},
|
||||
{
|
||||
"emoji": "♍",
|
||||
"title": "Virgo"
|
||||
},
|
||||
{
|
||||
"emoji": "♎",
|
||||
"title": "Libra"
|
||||
},
|
||||
{
|
||||
"emoji": "♏",
|
||||
"title": "Scorpio"
|
||||
},
|
||||
{
|
||||
"emoji": "♐",
|
||||
"title": "Sagittarius"
|
||||
},
|
||||
{
|
||||
"emoji": "♑",
|
||||
"title": "Capricorn"
|
||||
},
|
||||
{
|
||||
"emoji": "♒",
|
||||
"title": "Aquarius"
|
||||
},
|
||||
{
|
||||
"emoji": "♓",
|
||||
"title": "Pisces"
|
||||
},
|
||||
{
|
||||
"emoji": "⛎",
|
||||
"title": "Ophiuchus"
|
||||
},
|
||||
{
|
||||
"emoji": "🔀",
|
||||
"title": "Shuffle Tracks Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🔁",
|
||||
"title": "Repeat Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🔂",
|
||||
"title": "Repeat Single Button"
|
||||
},
|
||||
{
|
||||
"emoji": "▶️",
|
||||
"title": "Play Button"
|
||||
},
|
||||
{
|
||||
"emoji": "⏩",
|
||||
"title": "Fast-Forward Button"
|
||||
},
|
||||
{
|
||||
"emoji": "⏭️",
|
||||
"title": "Next Track Button"
|
||||
},
|
||||
{
|
||||
"emoji": "⏯️",
|
||||
"title": "Play or Pause Button"
|
||||
},
|
||||
{
|
||||
"emoji": "◀️",
|
||||
"title": "Reverse Button"
|
||||
},
|
||||
{
|
||||
"emoji": "⏪",
|
||||
"title": "Fast Reverse Button"
|
||||
},
|
||||
{
|
||||
"emoji": "⏮️",
|
||||
"title": "Last Track Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🔼",
|
||||
"title": "Upwards Button"
|
||||
},
|
||||
{
|
||||
"emoji": "⏫",
|
||||
"title": "Fast Up Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🔽",
|
||||
"title": "Downwards Button"
|
||||
},
|
||||
{
|
||||
"emoji": "⏬",
|
||||
"title": "Fast Down Button"
|
||||
},
|
||||
{
|
||||
"emoji": "⏸️",
|
||||
"title": "Pause Button"
|
||||
},
|
||||
{
|
||||
"emoji": "⏹️",
|
||||
"title": "Stop Button"
|
||||
},
|
||||
{
|
||||
"emoji": "⏺️",
|
||||
"title": "Record Button"
|
||||
},
|
||||
{
|
||||
"emoji": "⏏️",
|
||||
"title": "Eject Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🎦",
|
||||
"title": "Cinema"
|
||||
},
|
||||
{
|
||||
"emoji": "🔅",
|
||||
"title": "Dim Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🔆",
|
||||
"title": "Bright Button"
|
||||
},
|
||||
{
|
||||
"emoji": "📶",
|
||||
"title": "Antenna Bars"
|
||||
},
|
||||
{
|
||||
"emoji": "📳",
|
||||
"title": "Vibration Mode"
|
||||
},
|
||||
{
|
||||
"emoji": "📴",
|
||||
"title": "Mobile Phone Off"
|
||||
},
|
||||
{
|
||||
"emoji": "♀️",
|
||||
"title": "Female Sign"
|
||||
},
|
||||
{
|
||||
"emoji": "♂️",
|
||||
"title": "Male Sign"
|
||||
},
|
||||
{
|
||||
"emoji": "✖️",
|
||||
"title": "Multiply"
|
||||
},
|
||||
{
|
||||
"emoji": "➕",
|
||||
"title": "Plus"
|
||||
},
|
||||
{
|
||||
"emoji": "➖",
|
||||
"title": "Minus"
|
||||
},
|
||||
{
|
||||
"emoji": "➗",
|
||||
"title": "Divide"
|
||||
},
|
||||
{
|
||||
"emoji": "♾️",
|
||||
"title": "Infinity"
|
||||
},
|
||||
{
|
||||
"emoji": "‼️",
|
||||
"title": "‼ Double Exclamation Mark"
|
||||
},
|
||||
{
|
||||
"emoji": "⁉️",
|
||||
"title": "⁉ Exclamation Question Mark"
|
||||
},
|
||||
{
|
||||
"emoji": "❓",
|
||||
"title": "Red Question Mark"
|
||||
},
|
||||
{
|
||||
"emoji": "❔",
|
||||
"title": "White Question Mark"
|
||||
},
|
||||
{
|
||||
"emoji": "❕",
|
||||
"title": "White Exclamation Mark"
|
||||
},
|
||||
{
|
||||
"emoji": "❗",
|
||||
"title": "Red Exclamation Mark"
|
||||
},
|
||||
{
|
||||
"emoji": "〰️",
|
||||
"title": "〰 Wavy Dash"
|
||||
},
|
||||
{
|
||||
"emoji": "💱",
|
||||
"title": "Currency Exchange"
|
||||
},
|
||||
{
|
||||
"emoji": "💲",
|
||||
"title": "Heavy Dollar Sign"
|
||||
},
|
||||
{
|
||||
"emoji": "⚕️",
|
||||
"title": "Medical Symbol"
|
||||
},
|
||||
{
|
||||
"emoji": "♻️",
|
||||
"title": "Recycling Symbol"
|
||||
},
|
||||
{
|
||||
"emoji": "⚜️",
|
||||
"title": "Fleur-de-lis"
|
||||
},
|
||||
{
|
||||
"emoji": "🔱",
|
||||
"title": "Trident Emblem"
|
||||
},
|
||||
{
|
||||
"emoji": "📛",
|
||||
"title": "Name Badge"
|
||||
},
|
||||
{
|
||||
"emoji": "🔰",
|
||||
"title": "Japanese Symbol for Beginner"
|
||||
},
|
||||
{
|
||||
"emoji": "⭕",
|
||||
"title": "Hollow Red Circle"
|
||||
},
|
||||
{
|
||||
"emoji": "✅",
|
||||
"title": "Check Mark Button"
|
||||
},
|
||||
{
|
||||
"emoji": "☑️",
|
||||
"title": "Check Box with Check"
|
||||
},
|
||||
{
|
||||
"emoji": "✔️",
|
||||
"title": "Check Mark"
|
||||
},
|
||||
{
|
||||
"emoji": "❌",
|
||||
"title": "Cross Mark"
|
||||
},
|
||||
{
|
||||
"emoji": "❎",
|
||||
"title": "Cross Mark Button"
|
||||
},
|
||||
{
|
||||
"emoji": "➰",
|
||||
"title": "Curly Loop"
|
||||
},
|
||||
{
|
||||
"emoji": "➿",
|
||||
"title": "Double Curly Loop"
|
||||
},
|
||||
{
|
||||
"emoji": "〽️",
|
||||
"title": "〽 Part Alternation Mark"
|
||||
},
|
||||
{
|
||||
"emoji": "✳️",
|
||||
"title": "Eight-Spoked Asterisk"
|
||||
},
|
||||
{
|
||||
"emoji": "✴️",
|
||||
"title": "Eight-Pointed Star"
|
||||
},
|
||||
{
|
||||
"emoji": "❇️",
|
||||
"title": "Sparkle"
|
||||
},
|
||||
{
|
||||
"emoji": "©️",
|
||||
"title": "Copyright"
|
||||
},
|
||||
{
|
||||
"emoji": "®️",
|
||||
"title": "Registered"
|
||||
},
|
||||
{
|
||||
"emoji": "™️",
|
||||
"title": "Trade Mark"
|
||||
},
|
||||
{
|
||||
"emoji": "#️⃣",
|
||||
"title": "# Keycap Number Sign"
|
||||
},
|
||||
{
|
||||
"emoji": "*️⃣",
|
||||
"title": "* Keycap Asterisk"
|
||||
},
|
||||
{
|
||||
"emoji": "0️⃣",
|
||||
"title": "0 Keycap Digit Zero"
|
||||
},
|
||||
{
|
||||
"emoji": "1️⃣",
|
||||
"title": "1 Keycap Digit One"
|
||||
},
|
||||
{
|
||||
"emoji": "2️⃣",
|
||||
"title": "2 Keycap Digit Two"
|
||||
},
|
||||
{
|
||||
"emoji": "3️⃣",
|
||||
"title": "3 Keycap Digit Three"
|
||||
},
|
||||
{
|
||||
"emoji": "4️⃣",
|
||||
"title": "4 Keycap Digit Four"
|
||||
},
|
||||
{
|
||||
"emoji": "5️⃣",
|
||||
"title": "5 Keycap Digit Five"
|
||||
},
|
||||
{
|
||||
"emoji": "6️⃣",
|
||||
"title": "6 Keycap Digit Six"
|
||||
},
|
||||
{
|
||||
"emoji": "7️⃣",
|
||||
"title": "7 Keycap Digit Seven"
|
||||
},
|
||||
{
|
||||
"emoji": "8️⃣",
|
||||
"title": "8 Keycap Digit Eight"
|
||||
},
|
||||
{
|
||||
"emoji": "9️⃣",
|
||||
"title": "9 Keycap Digit Nine"
|
||||
},
|
||||
{
|
||||
"emoji": "🔟",
|
||||
"title": "Keycap: 10"
|
||||
},
|
||||
{
|
||||
"emoji": "🔠",
|
||||
"title": "Input Latin Uppercase"
|
||||
},
|
||||
{
|
||||
"emoji": "🔡",
|
||||
"title": "Input Latin Lowercase"
|
||||
},
|
||||
{
|
||||
"emoji": "🔢",
|
||||
"title": "Input Numbers"
|
||||
},
|
||||
{
|
||||
"emoji": "🔣",
|
||||
"title": "Input Symbols"
|
||||
},
|
||||
{
|
||||
"emoji": "🔤",
|
||||
"title": "Input Latin Letters"
|
||||
},
|
||||
{
|
||||
"emoji": "🅰️",
|
||||
"title": "A Button (Blood Type)"
|
||||
},
|
||||
{
|
||||
"emoji": "🆎",
|
||||
"title": "AB Button (Blood Type)"
|
||||
},
|
||||
{
|
||||
"emoji": "🅱️",
|
||||
"title": "B Button (Blood Type)"
|
||||
},
|
||||
{
|
||||
"emoji": "🆑",
|
||||
"title": "CL Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🆒",
|
||||
"title": "Cool Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🆓",
|
||||
"title": "Free Button"
|
||||
},
|
||||
{
|
||||
"emoji": "ℹ️",
|
||||
"title": "ℹ Information"
|
||||
},
|
||||
{
|
||||
"emoji": "🆔",
|
||||
"title": "ID Button"
|
||||
},
|
||||
{
|
||||
"emoji": "Ⓜ️",
|
||||
"title": "Circled M"
|
||||
},
|
||||
{
|
||||
"emoji": "🆕",
|
||||
"title": "New Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🆖",
|
||||
"title": "NG Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🅾️",
|
||||
"title": "O Button (Blood Type)"
|
||||
},
|
||||
{
|
||||
"emoji": "🆗",
|
||||
"title": "OK Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🅿️",
|
||||
"title": "P Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🆘",
|
||||
"title": "SOS Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🆙",
|
||||
"title": "Up! Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🆚",
|
||||
"title": "Vs Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🈁",
|
||||
"title": "Japanese “Here” Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🈂️",
|
||||
"title": "Japanese “Service Charge” Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🈷️",
|
||||
"title": "Japanese “Monthly Amount” Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🈶",
|
||||
"title": "Japanese “Not Free of Charge” Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🈯",
|
||||
"title": "Japanese “Reserved” Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🉐",
|
||||
"title": "Japanese “Bargain” Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🈹",
|
||||
"title": "Japanese “Discount” Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🈚",
|
||||
"title": "Japanese “Free of Charge” Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🈲",
|
||||
"title": "Japanese “Prohibited” Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🉑",
|
||||
"title": "Japanese “Acceptable” Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🈸",
|
||||
"title": "Japanese “Application” Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🈴",
|
||||
"title": "Japanese “Passing Grade” Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🈳",
|
||||
"title": "Japanese “Vacancy” Button"
|
||||
},
|
||||
{
|
||||
"emoji": "㊗️",
|
||||
"title": "Japanese “Congratulations” Button"
|
||||
},
|
||||
{
|
||||
"emoji": "㊙️",
|
||||
"title": "Japanese “Secret” Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🈺",
|
||||
"title": "Japanese “Open for Business” Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🈵",
|
||||
"title": "Japanese “No Vacancy” Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🔴",
|
||||
"title": "Red Circle"
|
||||
},
|
||||
{
|
||||
"emoji": "🟠",
|
||||
"title": "Orange Circle"
|
||||
},
|
||||
{
|
||||
"emoji": "🟡",
|
||||
"title": "Yellow Circle"
|
||||
},
|
||||
{
|
||||
"emoji": "🟢",
|
||||
"title": "Green Circle"
|
||||
},
|
||||
{
|
||||
"emoji": "🔵",
|
||||
"title": "Blue Circle"
|
||||
},
|
||||
{
|
||||
"emoji": "🟣",
|
||||
"title": "Purple Circle"
|
||||
},
|
||||
{
|
||||
"emoji": "🟤",
|
||||
"title": "Brown Circle"
|
||||
},
|
||||
{
|
||||
"emoji": "⚫",
|
||||
"title": "Black Circle"
|
||||
},
|
||||
{
|
||||
"emoji": "⚪",
|
||||
"title": "White Circle"
|
||||
},
|
||||
{
|
||||
"emoji": "🟥",
|
||||
"title": "Red Square"
|
||||
},
|
||||
{
|
||||
"emoji": "🟧",
|
||||
"title": "Orange Square"
|
||||
},
|
||||
{
|
||||
"emoji": "🟨",
|
||||
"title": "Yellow Square"
|
||||
},
|
||||
{
|
||||
"emoji": "🟩",
|
||||
"title": "Green Square"
|
||||
},
|
||||
{
|
||||
"emoji": "🟦",
|
||||
"title": "Blue Square"
|
||||
},
|
||||
{
|
||||
"emoji": "🟪",
|
||||
"title": "Purple Square"
|
||||
},
|
||||
{
|
||||
"emoji": "🟫",
|
||||
"title": "Brown Square"
|
||||
},
|
||||
{
|
||||
"emoji": "⬛",
|
||||
"title": "Black Large Square"
|
||||
},
|
||||
{
|
||||
"emoji": "⬜",
|
||||
"title": "White Large Square"
|
||||
},
|
||||
{
|
||||
"emoji": "◼️",
|
||||
"title": "Black Medium Square"
|
||||
},
|
||||
{
|
||||
"emoji": "◻️",
|
||||
"title": "White Medium Square"
|
||||
},
|
||||
{
|
||||
"emoji": "◾",
|
||||
"title": "Black Medium-Small Square"
|
||||
},
|
||||
{
|
||||
"emoji": "◽",
|
||||
"title": "White Medium-Small Square"
|
||||
},
|
||||
{
|
||||
"emoji": "▪️",
|
||||
"title": "Black Small Square"
|
||||
},
|
||||
{
|
||||
"emoji": "▫️",
|
||||
"title": "White Small Square"
|
||||
},
|
||||
{
|
||||
"emoji": "🔶",
|
||||
"title": "Large Orange Diamond"
|
||||
},
|
||||
{
|
||||
"emoji": "🔷",
|
||||
"title": "Large Blue Diamond"
|
||||
},
|
||||
{
|
||||
"emoji": "🔸",
|
||||
"title": "Small Orange Diamond"
|
||||
},
|
||||
{
|
||||
"emoji": "🔹",
|
||||
"title": "Small Blue Diamond"
|
||||
},
|
||||
{
|
||||
"emoji": "🔺",
|
||||
"title": "Red Triangle Pointed Up"
|
||||
},
|
||||
{
|
||||
"emoji": "🔻",
|
||||
"title": "Red Triangle Pointed Down"
|
||||
},
|
||||
{
|
||||
"emoji": "💠",
|
||||
"title": "Diamond with a Dot"
|
||||
},
|
||||
{
|
||||
"emoji": "🔘",
|
||||
"title": "Radio Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🔳",
|
||||
"title": "White Square Button"
|
||||
},
|
||||
{
|
||||
"emoji": "🔲",
|
||||
"title": "Black Square Button"
|
||||
}
|
||||
],
|
||||
'Flags': [
|
||||
{
|
||||
"emoji": "🏁",
|
||||
"title": "Chequered Flag"
|
||||
},
|
||||
{
|
||||
"emoji": "🚩",
|
||||
"title": "Triangular Flag"
|
||||
},
|
||||
{
|
||||
"emoji": "🎌",
|
||||
"title": "Crossed Flags"
|
||||
},
|
||||
{
|
||||
"emoji": "🏴",
|
||||
"title": "Black Flag"
|
||||
},
|
||||
{
|
||||
"emoji": "🏳️",
|
||||
"title": "White Flag"
|
||||
},
|
||||
{
|
||||
"emoji": "🏳️🌈",
|
||||
"title": "Rainbow Flag"
|
||||
},
|
||||
{
|
||||
"emoji": "🏳️⚧️",
|
||||
"title": "Transgender Flag"
|
||||
},
|
||||
{
|
||||
"emoji": "🏴☠️",
|
||||
"title": "Pirate Flag"
|
||||
},
|
||||
{
|
||||
"emoji": "🇦🇨",
|
||||
"title": "Flag: Ascension Island"
|
||||
},
|
||||
{
|
||||
"emoji": "🇦🇩",
|
||||
"title": "Flag: Andorra"
|
||||
},
|
||||
{
|
||||
"emoji": "🇦🇪",
|
||||
"title": "Flag: United Arab Emirates"
|
||||
},
|
||||
{
|
||||
"emoji": "🇦🇫",
|
||||
"title": "Flag: Afghanistan"
|
||||
},
|
||||
{
|
||||
"emoji": "🇦🇬",
|
||||
"title": "Flag: Antigua & Barbuda"
|
||||
},
|
||||
{
|
||||
"emoji": "🇦🇮",
|
||||
"title": "Flag: Anguilla"
|
||||
},
|
||||
{
|
||||
"emoji": "🇦🇱",
|
||||
"title": "Flag: Albania"
|
||||
},
|
||||
{
|
||||
"emoji": "🇦🇲",
|
||||
"title": "Flag: Armenia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇦🇴",
|
||||
"title": "Flag: Angola"
|
||||
},
|
||||
{
|
||||
"emoji": "🇦🇶",
|
||||
"title": "Flag: Antarctica"
|
||||
},
|
||||
{
|
||||
"emoji": "🇦🇷",
|
||||
"title": "Flag: Argentina"
|
||||
},
|
||||
{
|
||||
"emoji": "🇦🇸",
|
||||
"title": "Flag: American Samoa"
|
||||
},
|
||||
{
|
||||
"emoji": "🇦🇹",
|
||||
"title": "Flag: Austria"
|
||||
},
|
||||
{
|
||||
"emoji": "🇦🇺",
|
||||
"title": "Flag: Australia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇦🇼",
|
||||
"title": "Flag: Aruba"
|
||||
},
|
||||
{
|
||||
"emoji": "🇦🇽",
|
||||
"title": "Flag: Åland Islands"
|
||||
},
|
||||
{
|
||||
"emoji": "🇦🇿",
|
||||
"title": "Flag: Azerbaijan"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇦",
|
||||
"title": "Flag: Bosnia & Herzegovina"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇧",
|
||||
"title": "Flag: Barbados"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇩",
|
||||
"title": "Flag: Bangladesh"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇪",
|
||||
"title": "Flag: Belgium"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇫",
|
||||
"title": "Flag: Burkina Faso"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇬",
|
||||
"title": "Flag: Bulgaria"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇭",
|
||||
"title": "Flag: Bahrain"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇮",
|
||||
"title": "Flag: Burundi"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇯",
|
||||
"title": "Flag: Benin"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇱",
|
||||
"title": "Flag: St. Barthélemy"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇲",
|
||||
"title": "Flag: Bermuda"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇳",
|
||||
"title": "Flag: Brunei"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇴",
|
||||
"title": "Flag: Bolivia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇶",
|
||||
"title": "Flag: Caribbean Netherlands"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇷",
|
||||
"title": "Flag: Brazil"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇸",
|
||||
"title": "Flag: Bahamas"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇹",
|
||||
"title": "Flag: Bhutan"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇻",
|
||||
"title": "Flag: Bouvet Island"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇼",
|
||||
"title": "Flag: Botswana"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇾",
|
||||
"title": "Flag: Belarus"
|
||||
},
|
||||
{
|
||||
"emoji": "🇧🇿",
|
||||
"title": "Flag: Belize"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇦",
|
||||
"title": "Flag: Canada"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇨",
|
||||
"title": "Flag: Cocos (Keeling) Islands"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇩",
|
||||
"title": "Flag: Congo - Kinshasa"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇫",
|
||||
"title": "Flag: Central African Republic"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇬",
|
||||
"title": "Flag: Congo - Brazzaville"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇭",
|
||||
"title": "Flag: Switzerland"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇮",
|
||||
"title": "Flag: Côte d’Ivoire"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇰",
|
||||
"title": "Flag: Cook Islands"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇱",
|
||||
"title": "Flag: Chile"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇲",
|
||||
"title": "Flag: Cameroon"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇳",
|
||||
"title": "Flag: China"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇴",
|
||||
"title": "Flag: Colombia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇵",
|
||||
"title": "Flag: Clipperton Island"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇷",
|
||||
"title": "Flag: Costa Rica"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇺",
|
||||
"title": "Flag: Cuba"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇻",
|
||||
"title": "Flag: Cape Verde"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇼",
|
||||
"title": "Flag: Curaçao"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇽",
|
||||
"title": "Flag: Christmas Island"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇾",
|
||||
"title": "Flag: Cyprus"
|
||||
},
|
||||
{
|
||||
"emoji": "🇨🇿",
|
||||
"title": "Flag: Czechia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇩🇪",
|
||||
"title": "Flag: Germany"
|
||||
},
|
||||
{
|
||||
"emoji": "🇩🇬",
|
||||
"title": "Flag: Diego Garcia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇩🇯",
|
||||
"title": "Flag: Djibouti"
|
||||
},
|
||||
{
|
||||
"emoji": "🇩🇰",
|
||||
"title": "Flag: Denmark"
|
||||
},
|
||||
{
|
||||
"emoji": "🇩🇲",
|
||||
"title": "Flag: Dominica"
|
||||
},
|
||||
{
|
||||
"emoji": "🇩🇴",
|
||||
"title": "Flag: Dominican Republic"
|
||||
},
|
||||
{
|
||||
"emoji": "🇩🇿",
|
||||
"title": "Flag: Algeria"
|
||||
},
|
||||
{
|
||||
"emoji": "🇪🇦",
|
||||
"title": "Flag: Ceuta & Melilla"
|
||||
},
|
||||
{
|
||||
"emoji": "🇪🇨",
|
||||
"title": "Flag: Ecuador"
|
||||
},
|
||||
{
|
||||
"emoji": "🇪🇪",
|
||||
"title": "Flag: Estonia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇪🇬",
|
||||
"title": "Flag: Egypt"
|
||||
},
|
||||
{
|
||||
"emoji": "🇪🇭",
|
||||
"title": "Flag: Western Sahara"
|
||||
},
|
||||
{
|
||||
"emoji": "🇪🇷",
|
||||
"title": "Flag: Eritrea"
|
||||
},
|
||||
{
|
||||
"emoji": "🇪🇸",
|
||||
"title": "Flag: Spain"
|
||||
},
|
||||
{
|
||||
"emoji": "🇪🇹",
|
||||
"title": "Flag: Ethiopia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇪🇺",
|
||||
"title": "Flag: European Union"
|
||||
},
|
||||
{
|
||||
"emoji": "🇫🇮",
|
||||
"title": "Flag: Finland"
|
||||
},
|
||||
{
|
||||
"emoji": "🇫🇯",
|
||||
"title": "Flag: Fiji"
|
||||
},
|
||||
{
|
||||
"emoji": "🇫🇰",
|
||||
"title": "Flag: Falkland Islands"
|
||||
},
|
||||
{
|
||||
"emoji": "🇫🇲",
|
||||
"title": "Flag: Micronesia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇫🇴",
|
||||
"title": "Flag: Faroe Islands"
|
||||
},
|
||||
{
|
||||
"emoji": "🇫🇷",
|
||||
"title": "Flag: France"
|
||||
},
|
||||
{
|
||||
"emoji": "🇬🇦",
|
||||
"title": "Flag: Gabon"
|
||||
},
|
||||
{
|
||||
"emoji": "🇬🇧",
|
||||
"title": "Flag: United Kingdom"
|
||||
},
|
||||
{
|
||||
"emoji": "🇬🇩",
|
||||
"title": "Flag: Grenada"
|
||||
},
|
||||
{
|
||||
"emoji": "🇬🇪",
|
||||
"title": "Flag: Georgia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇬🇫",
|
||||
"title": "Flag: French Guiana"
|
||||
},
|
||||
{
|
||||
"emoji": "🇬🇬",
|
||||
"title": "Flag: Guernsey"
|
||||
},
|
||||
{
|
||||
"emoji": "🇬🇭",
|
||||
"title": "Flag: Ghana"
|
||||
},
|
||||
{
|
||||
"emoji": "🇬🇮",
|
||||
"title": "Flag: Gibraltar"
|
||||
},
|
||||
{
|
||||
"emoji": "🇬🇱",
|
||||
"title": "Flag: Greenland"
|
||||
},
|
||||
{
|
||||
"emoji": "🇬🇲",
|
||||
"title": "Flag: Gambia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇬🇳",
|
||||
"title": "Flag: Guinea"
|
||||
},
|
||||
{
|
||||
"emoji": "🇬🇵",
|
||||
"title": "Flag: Guadeloupe"
|
||||
},
|
||||
{
|
||||
"emoji": "🇬🇶",
|
||||
"title": "Flag: Equatorial Guinea"
|
||||
},
|
||||
{
|
||||
"emoji": "🇬🇷",
|
||||
"title": "Flag: Greece"
|
||||
},
|
||||
{
|
||||
"emoji": "🇬🇸",
|
||||
"title": "Flag: South Georgia & South Sandwich Islands"
|
||||
},
|
||||
{
|
||||
"emoji": "🇬🇹",
|
||||
"title": "Flag: Guatemala"
|
||||
},
|
||||
{
|
||||
"emoji": "🇬🇺",
|
||||
"title": "Flag: Guam"
|
||||
},
|
||||
{
|
||||
"emoji": "🇬🇼",
|
||||
"title": "Flag: Guinea-Bissau"
|
||||
},
|
||||
{
|
||||
"emoji": "🇬🇾",
|
||||
"title": "Flag: Guyana"
|
||||
},
|
||||
{
|
||||
"emoji": "🇭🇰",
|
||||
"title": "Flag: Hong Kong SAR China"
|
||||
},
|
||||
{
|
||||
"emoji": "🇭🇲",
|
||||
"title": "Flag: Heard & McDonald Islands"
|
||||
},
|
||||
{
|
||||
"emoji": "🇭🇳",
|
||||
"title": "Flag: Honduras"
|
||||
},
|
||||
{
|
||||
"emoji": "🇭🇷",
|
||||
"title": "Flag: Croatia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇭🇹",
|
||||
"title": "Flag: Haiti"
|
||||
},
|
||||
{
|
||||
"emoji": "🇭🇺",
|
||||
"title": "Flag: Hungary"
|
||||
},
|
||||
{
|
||||
"emoji": "🇮🇨",
|
||||
"title": "Flag: Canary Islands"
|
||||
},
|
||||
{
|
||||
"emoji": "🇮🇩",
|
||||
"title": "Flag: Indonesia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇮🇪",
|
||||
"title": "Flag: Ireland"
|
||||
},
|
||||
{
|
||||
"emoji": "🇮🇱",
|
||||
"title": "Flag: Israel"
|
||||
},
|
||||
{
|
||||
"emoji": "🇮🇲",
|
||||
"title": "Flag: Isle of Man"
|
||||
},
|
||||
{
|
||||
"emoji": "🇮🇳",
|
||||
"title": "Flag: India"
|
||||
},
|
||||
{
|
||||
"emoji": "🇮🇴",
|
||||
"title": "Flag: British Indian Ocean Territory"
|
||||
},
|
||||
{
|
||||
"emoji": "🇮🇶",
|
||||
"title": "Flag: Iraq"
|
||||
},
|
||||
{
|
||||
"emoji": "🇮🇷",
|
||||
"title": "Flag: Iran"
|
||||
},
|
||||
{
|
||||
"emoji": "🇮🇸",
|
||||
"title": "Flag: Iceland"
|
||||
},
|
||||
{
|
||||
"emoji": "🇮🇹",
|
||||
"title": "Flag: Italy"
|
||||
},
|
||||
{
|
||||
"emoji": "🇯🇪",
|
||||
"title": "Flag: Jersey"
|
||||
},
|
||||
{
|
||||
"emoji": "🇯🇲",
|
||||
"title": "Flag: Jamaica"
|
||||
},
|
||||
{
|
||||
"emoji": "🇯🇴",
|
||||
"title": "Flag: Jordan"
|
||||
},
|
||||
{
|
||||
"emoji": "🇯🇵",
|
||||
"title": "Flag: Japan"
|
||||
},
|
||||
{
|
||||
"emoji": "🇰🇪",
|
||||
"title": "Flag: Kenya"
|
||||
},
|
||||
{
|
||||
"emoji": "🇰🇬",
|
||||
"title": "Flag: Kyrgyzstan"
|
||||
},
|
||||
{
|
||||
"emoji": "🇰🇭",
|
||||
"title": "Flag: Cambodia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇰🇮",
|
||||
"title": "Flag: Kiribati"
|
||||
},
|
||||
{
|
||||
"emoji": "🇰🇲",
|
||||
"title": "Flag: Comoros"
|
||||
},
|
||||
{
|
||||
"emoji": "🇰🇳",
|
||||
"title": "Flag: St. Kitts & Nevis"
|
||||
},
|
||||
{
|
||||
"emoji": "🇰🇵",
|
||||
"title": "Flag: North Korea"
|
||||
},
|
||||
{
|
||||
"emoji": "🇰🇷",
|
||||
"title": "Flag: South Korea"
|
||||
},
|
||||
{
|
||||
"emoji": "🇰🇼",
|
||||
"title": "Flag: Kuwait"
|
||||
},
|
||||
{
|
||||
"emoji": "🇰🇾",
|
||||
"title": "Flag: Cayman Islands"
|
||||
},
|
||||
{
|
||||
"emoji": "🇰🇿",
|
||||
"title": "Flag: Kazakhstan"
|
||||
},
|
||||
{
|
||||
"emoji": "🇱🇦",
|
||||
"title": "Flag: Laos"
|
||||
},
|
||||
{
|
||||
"emoji": "🇱🇧",
|
||||
"title": "Flag: Lebanon"
|
||||
},
|
||||
{
|
||||
"emoji": "🇱🇨",
|
||||
"title": "Flag: St. Lucia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇱🇮",
|
||||
"title": "Flag: Liechtenstein"
|
||||
},
|
||||
{
|
||||
"emoji": "🇱🇰",
|
||||
"title": "Flag: Sri Lanka"
|
||||
},
|
||||
{
|
||||
"emoji": "🇱🇷",
|
||||
"title": "Flag: Liberia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇱🇸",
|
||||
"title": "Flag: Lesotho"
|
||||
},
|
||||
{
|
||||
"emoji": "🇱🇹",
|
||||
"title": "Flag: Lithuania"
|
||||
},
|
||||
{
|
||||
"emoji": "🇱🇺",
|
||||
"title": "Flag: Luxembourg"
|
||||
},
|
||||
{
|
||||
"emoji": "🇱🇻",
|
||||
"title": "Flag: Latvia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇱🇾",
|
||||
"title": "Flag: Libya"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇦",
|
||||
"title": "Flag: Morocco"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇨",
|
||||
"title": "Flag: Monaco"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇩",
|
||||
"title": "Flag: Moldova"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇪",
|
||||
"title": "Flag: Montenegro"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇫",
|
||||
"title": "Flag: St. Martin"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇬",
|
||||
"title": "Flag: Madagascar"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇭",
|
||||
"title": "Flag: Marshall Islands"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇰",
|
||||
"title": "Flag: North Macedonia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇱",
|
||||
"title": "Flag: Mali"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇲",
|
||||
"title": "Flag: Myanmar (Burma)"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇳",
|
||||
"title": "Flag: Mongolia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇴",
|
||||
"title": "Flag: Macao Sar China"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇵",
|
||||
"title": "Flag: Northern Mariana Islands"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇶",
|
||||
"title": "Flag: Martinique"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇷",
|
||||
"title": "Flag: Mauritania"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇸",
|
||||
"title": "Flag: Montserrat"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇹",
|
||||
"title": "Flag: Malta"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇺",
|
||||
"title": "Flag: Mauritius"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇻",
|
||||
"title": "Flag: Maldives"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇼",
|
||||
"title": "Flag: Malawi"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇽",
|
||||
"title": "Flag: Mexico"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇾",
|
||||
"title": "Flag: Malaysia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇲🇿",
|
||||
"title": "Flag: Mozambique"
|
||||
},
|
||||
{
|
||||
"emoji": "🇳🇦",
|
||||
"title": "Flag: Namibia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇳🇨",
|
||||
"title": "Flag: New Caledonia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇳🇪",
|
||||
"title": "Flag: Niger"
|
||||
},
|
||||
{
|
||||
"emoji": "🇳🇫",
|
||||
"title": "Flag: Norfolk Island"
|
||||
},
|
||||
{
|
||||
"emoji": "🇳🇬",
|
||||
"title": "Flag: Nigeria"
|
||||
},
|
||||
{
|
||||
"emoji": "🇳🇮",
|
||||
"title": "Flag: Nicaragua"
|
||||
},
|
||||
{
|
||||
"emoji": "🇳🇱",
|
||||
"title": "Flag: Netherlands"
|
||||
},
|
||||
{
|
||||
"emoji": "🇳🇴",
|
||||
"title": "Flag: Norway"
|
||||
},
|
||||
{
|
||||
"emoji": "🇳🇵",
|
||||
"title": "Flag: Nepal"
|
||||
},
|
||||
{
|
||||
"emoji": "🇳🇷",
|
||||
"title": "Flag: Nauru"
|
||||
},
|
||||
{
|
||||
"emoji": "🇳🇺",
|
||||
"title": "Flag: Niue"
|
||||
},
|
||||
{
|
||||
"emoji": "🇳🇿",
|
||||
"title": "Flag: New Zealand"
|
||||
},
|
||||
{
|
||||
"emoji": "🇴🇲",
|
||||
"title": "Flag: Oman"
|
||||
},
|
||||
{
|
||||
"emoji": "🇵🇦",
|
||||
"title": "Flag: Panama"
|
||||
},
|
||||
{
|
||||
"emoji": "🇵🇪",
|
||||
"title": "Flag: Peru"
|
||||
},
|
||||
{
|
||||
"emoji": "🇵🇫",
|
||||
"title": "Flag: French Polynesia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇵🇬",
|
||||
"title": "Flag: Papua New Guinea"
|
||||
},
|
||||
{
|
||||
"emoji": "🇵🇭",
|
||||
"title": "Flag: Philippines"
|
||||
},
|
||||
{
|
||||
"emoji": "🇵🇰",
|
||||
"title": "Flag: Pakistan"
|
||||
},
|
||||
{
|
||||
"emoji": "🇵🇱",
|
||||
"title": "Flag: Poland"
|
||||
},
|
||||
{
|
||||
"emoji": "🇵🇲",
|
||||
"title": "Flag: St. Pierre & Miquelon"
|
||||
},
|
||||
{
|
||||
"emoji": "🇵🇳",
|
||||
"title": "Flag: Pitcairn Islands"
|
||||
},
|
||||
{
|
||||
"emoji": "🇵🇷",
|
||||
"title": "Flag: Puerto Rico"
|
||||
},
|
||||
{
|
||||
"emoji": "🇵🇸",
|
||||
"title": "Flag: Palestinian Territories"
|
||||
},
|
||||
{
|
||||
"emoji": "🇵🇹",
|
||||
"title": "Flag: Portugal"
|
||||
},
|
||||
{
|
||||
"emoji": "🇵🇼",
|
||||
"title": "Flag: Palau"
|
||||
},
|
||||
{
|
||||
"emoji": "🇵🇾",
|
||||
"title": "Flag: Paraguay"
|
||||
},
|
||||
{
|
||||
"emoji": "🇶🇦",
|
||||
"title": "Flag: Qatar"
|
||||
},
|
||||
{
|
||||
"emoji": "🇷🇪",
|
||||
"title": "Flag: Réunion"
|
||||
},
|
||||
{
|
||||
"emoji": "🇷🇴",
|
||||
"title": "Flag: Romania"
|
||||
},
|
||||
{
|
||||
"emoji": "🇷🇸",
|
||||
"title": "Flag: Serbia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇷🇺",
|
||||
"title": "Flag: Russia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇷🇼",
|
||||
"title": "Flag: Rwanda"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇦",
|
||||
"title": "Flag: Saudi Arabia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇧",
|
||||
"title": "Flag: Solomon Islands"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇨",
|
||||
"title": "Flag: Seychelles"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇩",
|
||||
"title": "Flag: Sudan"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇪",
|
||||
"title": "Flag: Sweden"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇬",
|
||||
"title": "Flag: Singapore"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇭",
|
||||
"title": "Flag: St. Helena"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇮",
|
||||
"title": "Flag: Slovenia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇯",
|
||||
"title": "Flag: Svalbard & Jan Mayen"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇰",
|
||||
"title": "Flag: Slovakia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇱",
|
||||
"title": "Flag: Sierra Leone"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇲",
|
||||
"title": "Flag: San Marino"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇳",
|
||||
"title": "Flag: Senegal"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇴",
|
||||
"title": "Flag: Somalia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇷",
|
||||
"title": "Flag: Suriname"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇸",
|
||||
"title": "Flag: South Sudan"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇹",
|
||||
"title": "Flag: São Tomé & Príncipe"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇻",
|
||||
"title": "Flag: El Salvador"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇽",
|
||||
"title": "Flag: Sint Maarten"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇾",
|
||||
"title": "Flag: Syria"
|
||||
},
|
||||
{
|
||||
"emoji": "🇸🇿",
|
||||
"title": "Flag: Eswatini"
|
||||
},
|
||||
{
|
||||
"emoji": "🇹🇦",
|
||||
"title": "Flag: Tristan Da Cunha"
|
||||
},
|
||||
{
|
||||
"emoji": "🇹🇨",
|
||||
"title": "Flag: Turks & Caicos Islands"
|
||||
},
|
||||
{
|
||||
"emoji": "🇹🇩",
|
||||
"title": "Flag: Chad"
|
||||
},
|
||||
{
|
||||
"emoji": "🇹🇫",
|
||||
"title": "Flag: French Southern Territories"
|
||||
},
|
||||
{
|
||||
"emoji": "🇹🇬",
|
||||
"title": "Flag: Togo"
|
||||
},
|
||||
{
|
||||
"emoji": "🇹🇭",
|
||||
"title": "Flag: Thailand"
|
||||
},
|
||||
{
|
||||
"emoji": "🇹🇯",
|
||||
"title": "Flag: Tajikistan"
|
||||
},
|
||||
{
|
||||
"emoji": "🇹🇰",
|
||||
"title": "Flag: Tokelau"
|
||||
},
|
||||
{
|
||||
"emoji": "🇹🇱",
|
||||
"title": "Flag: Timor-Leste"
|
||||
},
|
||||
{
|
||||
"emoji": "🇹🇲",
|
||||
"title": "Flag: Turkmenistan"
|
||||
},
|
||||
{
|
||||
"emoji": "🇹🇳",
|
||||
"title": "Flag: Tunisia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇹🇴",
|
||||
"title": "Flag: Tonga"
|
||||
},
|
||||
{
|
||||
"emoji": "🇹🇷",
|
||||
"title": "Flag: Turkey"
|
||||
},
|
||||
{
|
||||
"emoji": "🇹🇹",
|
||||
"title": "Flag: Trinidad & Tobago"
|
||||
},
|
||||
{
|
||||
"emoji": "🇹🇻",
|
||||
"title": "Flag: Tuvalu"
|
||||
},
|
||||
{
|
||||
"emoji": "🇹🇼",
|
||||
"title": "Flag: Taiwan"
|
||||
},
|
||||
{
|
||||
"emoji": "🇹🇿",
|
||||
"title": "Flag: Tanzania"
|
||||
},
|
||||
{
|
||||
"emoji": "🇺🇦",
|
||||
"title": "Flag: Ukraine"
|
||||
},
|
||||
{
|
||||
"emoji": "🇺🇬",
|
||||
"title": "Flag: Uganda"
|
||||
},
|
||||
{
|
||||
"emoji": "🇺🇲",
|
||||
"title": "Flag: U.S. Outlying Islands"
|
||||
},
|
||||
{
|
||||
"emoji": "🇺🇳",
|
||||
"title": "Flag: United Nations"
|
||||
},
|
||||
{
|
||||
"emoji": "🇺🇸",
|
||||
"title": "Flag: United States"
|
||||
},
|
||||
{
|
||||
"emoji": "🇺🇾",
|
||||
"title": "Flag: Uruguay"
|
||||
},
|
||||
{
|
||||
"emoji": "🇺🇿",
|
||||
"title": "Flag: Uzbekistan"
|
||||
},
|
||||
{
|
||||
"emoji": "🇻🇦",
|
||||
"title": "Flag: Vatican City"
|
||||
},
|
||||
{
|
||||
"emoji": "🇻🇨",
|
||||
"title": "Flag: St. Vincent & Grenadines"
|
||||
},
|
||||
{
|
||||
"emoji": "🇻🇪",
|
||||
"title": "Flag: Venezuela"
|
||||
},
|
||||
{
|
||||
"emoji": "🇻🇬",
|
||||
"title": "Flag: British Virgin Islands"
|
||||
},
|
||||
{
|
||||
"emoji": "🇻🇮",
|
||||
"title": "Flag: U.S. Virgin Islands"
|
||||
},
|
||||
{
|
||||
"emoji": "🇻🇳",
|
||||
"title": "Flag: Vietnam"
|
||||
},
|
||||
{
|
||||
"emoji": "🇻🇺",
|
||||
"title": "Flag: Vanuatu"
|
||||
},
|
||||
{
|
||||
"emoji": "🇼🇫",
|
||||
"title": "Flag: Wallis & Futuna"
|
||||
},
|
||||
{
|
||||
"emoji": "🇼🇸",
|
||||
"title": "Flag: Samoa"
|
||||
},
|
||||
{
|
||||
"emoji": "🇽🇰",
|
||||
"title": "Flag: Kosovo"
|
||||
},
|
||||
{
|
||||
"emoji": "🇾🇪",
|
||||
"title": "Flag: Yemen"
|
||||
},
|
||||
{
|
||||
"emoji": "🇾🇹",
|
||||
"title": "Flag: Mayotte"
|
||||
},
|
||||
{
|
||||
"emoji": "🇿🇦",
|
||||
"title": "Flag: South Africa"
|
||||
},
|
||||
{
|
||||
"emoji": "🇿🇲",
|
||||
"title": "Flag: Zambia"
|
||||
},
|
||||
{
|
||||
"emoji": "🇿🇼",
|
||||
"title": "Flag: Zimbabwe"
|
||||
},
|
||||
{
|
||||
"emoji": "🏴",
|
||||
"title": "Flag: England"
|
||||
},
|
||||
{
|
||||
"emoji": "🏴",
|
||||
"title": "Flag: Scotland"
|
||||
},
|
||||
{
|
||||
"emoji": "🏴",
|
||||
"title": "Flag: Wales"
|
||||
},
|
||||
{
|
||||
"emoji": "🏴",
|
||||
"title": "Flag for Texas (US-TX)"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const categoryFlags = {
|
||||
'People': '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve"> <g> <g> <path d="M437.02,74.98C388.667,26.629,324.38,0,256,0S123.333,26.629,74.98,74.98C26.629,123.333,0,187.62,0,256 s26.629,132.668,74.98,181.02C123.333,485.371,187.62,512,256,512s132.667-26.629,181.02-74.98 C485.371,388.668,512,324.38,512,256S485.371,123.333,437.02,74.98z M256,472c-119.103,0-216-96.897-216-216S136.897,40,256,40 s216,96.897,216,216S375.103,472,256,472z"/> </g> </g> <g> <g> <path d="M368.993,285.776c-0.072,0.214-7.298,21.626-25.02,42.393C321.419,354.599,292.628,368,258.4,368 c-34.475,0-64.195-13.561-88.333-40.303c-18.92-20.962-27.272-42.54-27.33-42.691l-37.475,13.99 c0.42,1.122,10.533,27.792,34.013,54.273C171.022,389.074,212.215,408,258.4,408c46.412,0,86.904-19.076,117.099-55.166 c22.318-26.675,31.165-53.55,31.531-54.681L368.993,285.776z"/> </g> </g> <g> <g> <circle cx="168" cy="180.12" r="32"/> </g> </g> <g> <g> <circle cx="344" cy="180.12" r="32"/> </g> </g> <g> </g> <g> </g> <g> </g> </svg>',
|
||||
'Nature': '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 354.968 354.968" style="enable-background:new 0 0 354.968 354.968;" xml:space="preserve"> <g> <g> <path d="M350.775,341.319c-9.6-28.4-20.8-55.2-34.4-80.8c0.4-0.4,0.8-1.2,1.6-1.6c30.8-34.8,44-83.6,20.4-131.6 c-20.4-41.6-65.6-76.4-124.8-98.8c-57.2-22-127.6-32.4-200.4-27.2c-5.6,0.4-10,5.2-9.6,10.8c0.4,2.8,1.6,5.6,4,7.2 c36.8,31.6,50,79.2,63.6,126.8c8,28,15.6,55.6,28.4,81.2c0,0.4,0.4,0.4,0.4,0.8c30.8,59.6,78,81.2,122.8,78.4 c18.4-1.2,36-6.4,52.4-14.4c9.2-4.8,18-10.4,26-16.8c11.6,23.2,22,47.2,30.4,72.8c1.6,5.2,7.6,8,12.8,6.4 C349.975,352.119,352.775,346.519,350.775,341.319z M271.175,189.319c-34.8-44.4-78-82.4-131.6-112.4c-4.8-2.8-11.2-1.2-13.6,4 c-2.8,4.8-1.2,11.2,4,13.6c50.8,28.8,92.4,64.8,125.6,107.2c13.2,17.2,25.2,35.2,36,54c-8,7.6-16.4,13.6-25.6,18 c-14,7.2-28.8,11.6-44.4,12.4c-37.6,2.4-77.2-16-104-67.6v-0.4c-11.6-24-19.2-50.8-26.8-78c-12.4-43.2-24.4-86.4-53.6-120.4 c61.6-1.6,120.4,8.4,169.2,27.2c54.4,20.8,96,52,114,88.8c18.8,38,9.2,76.8-14.4,105.2 C295.575,222.919,283.975,205.719,271.175,189.319z"/> </g> </g> <g> </g> <g> </g> <g> </g> </svg>',
|
||||
'Food-dring': '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 295 295" xmlns:xlink="http://www.w3.org/1999/xlink" enable-background="new 0 0 295 295"> <g> <path d="M25,226.011v16.511c0,8.836,7.465,16.489,16.302,16.489h214.063c8.837,0,15.636-7.653,15.636-16.489v-16.511H25z"/> <path d="m271.83,153.011c-3.635-66-57.634-117.022-123.496-117.022-65.863,0-119.863,51.021-123.498,117.022h246.994zm-198.497-50.99c-4.557,0-8.25-3.693-8.25-8.25 0-4.557 3.693-8.25 8.25-8.25 4.557,0 8.25,3.693 8.25,8.25 0,4.557-3.693,8.25-8.25,8.25zm42,33c-4.557,0-8.25-3.693-8.25-8.25 0-4.557 3.693-8.25 8.25-8.25 4.557,0 8.25,3.693 8.25,8.25 0,4.557-3.693,8.25-8.25,8.25zm33.248-58c-4.557,0-8.25-3.693-8.25-8.25 0-4.557 3.693-8.25 8.25-8.25 4.557,0 8.25,3.693 8.25,8.25 0,4.557-3.693,8.25-8.25,8.25zm32.752,58c-4.557,0-8.25-3.693-8.25-8.25 0-4.557 3.693-8.25 8.25-8.25 4.557,0 8.25,3.693 8.25,8.25 0,4.557-3.693,8.25-8.25,8.25zm50.25-41.25c0,4.557-3.693,8.25-8.25,8.25-4.557,0-8.25-3.693-8.25-8.25 0-4.557 3.693-8.25 8.25-8.25 4.557,0 8.25,3.694 8.25,8.25z"/> <path d="m275.414,169.011h-0.081-254.825c-11.142,0-20.508,8.778-20.508,19.921v0.414c0,11.143 9.366,20.665 20.508,20.665h254.906c11.142,0 19.586-9.523 19.586-20.665v-0.414c0-11.143-8.444-19.921-19.586-19.921z"/> </g> </svg>',
|
||||
'Activity': '<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path id="XMLID_272_" d="m437.02 74.98c-48.353-48.351-112.64-74.98-181.02-74.98s-132.667 26.629-181.02 74.98c-48.351 48.353-74.98 112.64-74.98 181.02s26.629 132.667 74.98 181.02c48.353 48.351 112.64 74.98 181.02 74.98s132.667-26.629 181.02-74.98c48.351-48.353 74.98-112.64 74.98-181.02s-26.629-132.667-74.98-181.02zm-407.02 181.02c0-57.102 21.297-109.316 56.352-149.142 37.143 45.142 57.438 101.499 57.438 160.409 0 53.21-16.914 105.191-47.908 148.069-40.693-40.891-65.882-97.226-65.882-159.336zm88.491 179.221c35.75-48.412 55.3-107.471 55.3-167.954 0-66.866-23.372-130.794-66.092-181.661 39.718-34.614 91.603-55.606 148.301-55.606 56.585 0 108.376 20.906 148.064 55.396-42.834 50.9-66.269 114.902-66.269 181.872 0 60.556 19.605 119.711 55.448 168.158-38.077 29.193-85.665 46.574-137.243 46.574-51.698 0-99.388-17.461-137.509-46.779zm297.392-19.645c-31.104-42.922-48.088-95.008-48.088-148.309 0-59.026 20.367-115.47 57.638-160.651 35.182 39.857 56.567 92.166 56.567 149.384 0 62.23-25.284 118.665-66.117 159.576z"/></svg>',
|
||||
'Travel-places': '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve"> <g><g><path d="M846.5,153.5C939,246.1,990,369.1,990,500c0,130.9-51,253.9-143.5,346.5C753.9,939,630.9,990,500,990c-130.9,0-253.9-51-346.5-143.5C61,753.9,10,630.9,10,500c0-130.9,51-253.9,143.5-346.5C246.1,61,369.1,10,500,10C630.9,10,753.9,61,846.5,153.5z M803.2,803.2c60.3-60.3,100.5-135.5,117-217.3c-12.9,19-25.2,26-32.9-16.5c-7.9-69.3-71.5-25-111.5-49.6c-42.1,28.4-136.8-55.2-120.7,39.1c24.8,42.5,134-56.9,79.6,33.1c-34.7,62.8-126.9,201.9-114.9,274c1.5,105-107.3,21.9-144.8-12.9c-25.2-69.8-8.6-191.8-74.6-225.9c-71.6-3.1-133-9.6-160.8-89.6c-16.7-57.3,17.8-142.5,79.1-155.7c89.8-56.4,121.9,66.1,206.1,68.4c26.2-27.4,97.4-36.1,103.4-66.8c-55.3-9.8,70.1-46.5-5.3-67.4c-41.6,4.9-68.4,43.1-46.3,75.6C496,410.3,493.5,274.8,416,317.6c-2,67.6-126.5,21.9-43.1,8.2c28.7-12.5-46.8-48.8-6-42.2c20-1.1,87.4-24.7,69.2-40.6c37.5-23.3,69.1,55.8,105.8-1.8c26.5-44.3-11.1-52.5-44.4-30c-18.7-21,33.1-66.3,78.8-85.9c15.2-6.5,29.8-10.1,40.9-9.1c23,26.6,65.6,31.2,67.8-3.2c-57-27.3-119.9-41.7-185-41.7c-93.4,0-182.3,29.7-255.8,84.6c19.8,9.1,31,20.3,11.9,34.7c-14.8,44.1-74.8,103.2-127.5,94.9c-27.4,47.2-45.4,99.2-53.1,153.6c44.1,14.6,54.3,43.5,44.8,53.2c-22.5,19.6-36.3,47.4-43.4,77.8C91.3,658,132.6,739,196.8,803.2c81,81,188.6,125.6,303.2,125.6C614.5,928.8,722.2,884.2,803.2,803.2z"/></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g></g> </svg>',
|
||||
'Objects': '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 461.977 461.977" style="enable-background:new 0 0 461.977 461.977;" xml:space="preserve"> <g> <path d="M398.47,248.268L346.376,18.543C344.136,8.665,333.287,0,323.158,0H138.821c-10.129,0-20.979,8.665-23.219,18.543 L63.507,248.268c-0.902,3.979-0.271,7.582,1.775,10.145c2.047,2.564,5.421,3.975,9.501,3.975h51.822v39.108 c-6.551,3.555-11,10.493-11,18.47c0,11.598,9.402,21,21,21c11.598,0,21-9.402,21-21c0-7.978-4.449-14.916-11-18.47v-39.108h240.587 c4.079,0,7.454-1.412,9.501-3.975C398.742,255.849,399.372,252.247,398.47,248.268z"/> <path d="M318.735,441.977h-77.747V282.388h-20v159.588h-77.747c-5.523,0-10,4.477-10,10c0,5.523,4.477,10,10,10h175.494 c5.522,0,10-4.477,10-10C328.735,446.454,324.257,441.977,318.735,441.977z"/> </g> <g> </g> <g> </g> <g> </g> </svg>',
|
||||
'Symbols': '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 30.487 30.486" style="enable-background:new 0 0 30.487 30.486;" xml:space="preserve"> <g> <path d="M28.866,17.477h-2.521V15.03h-2.56c0.005-2.8-0.304-5.204-0.315-5.308l-0.088-0.67L22.75,8.811 c-0.021-0.008-0.142-0.051-0.317-0.109l2.287-8.519L19,4.836L15.23,0.022V0l-0.009,0.01L15.215,0v0.021l-3.769,4.815L5.725,0.183 l2.299,8.561c-0.157,0.051-0.268,0.09-0.288,0.098L7.104,9.084l-0.088,0.67c-0.013,0.104-0.321,2.508-0.316,5.308h-2.56v2.446H1.62 l0.447,2.514L1.62,22.689h6.474c1.907,2.966,5.186,7.549,7.162,7.797v-0.037c1.979-0.283,5.237-4.838,7.137-7.79h6.474l-0.447-2.67 L28.866,17.477z M21.137,20.355c-0.422,1.375-4.346,6.949-5.907,7.758v0.015c-1.577-0.853-5.461-6.373-5.882-7.739 c-0.002-0.043-0.005-0.095-0.008-0.146l11.804-0.031C21.141,20.264,21.139,20.314,21.137,20.355z M8.972,15.062 c-0.003-1.769,0.129-3.403,0.219-4.298c0.98-0.271,3.072-0.723,6.065-0.78v-0.03c2.979,0.06,5.063,0.51,6.04,0.779 c0.09,0.895,0.223,2.529,0.219,4.298L8.972,15.062z"/> </g> <g> </g> <g> </g> <g> </g> </svg>',
|
||||
'Flags': '<svg viewBox="0 0 60 60" xmlns="http://www.w3.org/2000/svg"><g id="Page-1" fill-rule="evenodd"><g id="037---Waypoint-Flag" fill-rule="nonzero" transform="translate(0 -1)"><path id="Shape" d="m59.0752 28.5054c-3.7664123-1.873859-7.2507049-4.2678838-10.3506-7.1118 1.5923634-6.0211307 2.7737841-12.14349669 3.5361-18.3248.1788-1.44-.623-1.9047-.872-2.0126-.7016942-.26712004-1.4944908-.00419148-1.8975.6293-5.4726 6.5479-12.9687 5.8008-20.9053 5.0054-7.9985-.8-16.2506-1.6116-22.3684 5.4114-.85552122-1.067885-2.26533581-1.5228479-3.5837-1.1565l-.1377.0386c-1.81412367.5095218-2.87378593 2.391025-2.3691 4.2065l12.2089 43.6891c.3541969 1.2645215 1.5052141 2.1399137 2.8184 2.1435.2677318-.0003961.5341685-.0371657.792-.1093l1.0683-.2984h.001c.7485787-.2091577 1.3833789-.7071796 1.7646969-1.3844635.381318-.677284.4779045-1.478326.2685031-2.2268365l-3.7812-13.5327c5.5066-7.0807 13.18-6.3309 21.2988-5.52 8.1094.81 16.4863 1.646 22.64-5.7129l.0029-.0039c.6044387-.7534187.8533533-1.7315007.6826-2.6822-.0899994-.4592259-.3932698-.8481635-.8167-1.0474zm-42.0381 29.7446c-.1201754.2157725-.3219209.3742868-.56.44l-1.0684.2983c-.4949157.1376357-1.0078362-.1513714-1.1465-.646l-12.2095-43.6895c-.20840349-.7523825.23089143-1.5316224.9825-1.7428l.1367-.0381c.12366014-.0348192.25153137-.0524183.38-.0523.63429117.0010181 1.19083557.4229483 1.3631 1.0334l.1083.3876v.0021l6.2529 22.3755 5.8468 20.9238c.0669515.2380103.0360256.4929057-.0859.708zm40.6329-27.2925c-5.4736 6.5459-12.9707 5.7974-20.9043 5.0039-7.9033-.79-16.06-1.605-22.1552 5.1558l-5.463-19.548-2.0643-7.3873c5.5068-7.0794 13.1796-6.3119 21.3045-5.5007 7.7148.7695 15.6787 1.5664 21.7373-4.7095-.7467138 5.70010904-1.859683 11.3462228-3.332 16.9033-.1993066.7185155.0267229 1.4878686.583 1.9844 3.1786296 2.9100325 6.7366511 5.3762694 10.5771 7.3315-.0213812.2768572-.1194065.5422977-.2831.7666z"/></g></g></svg>'
|
||||
};
|
||||
|
||||
const icons = {
|
||||
search: '<svg style="fill: #646772;" version="1.1" width="17" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 487.95 487.95" style="enable-background:new 0 0 487.95 487.95;" xml:space="preserve"> <g> <g> <path d="M481.8,453l-140-140.1c27.6-33.1,44.2-75.4,44.2-121.6C386,85.9,299.5,0.2,193.1,0.2S0,86,0,191.4s86.5,191.1,192.9,191.1 c45.2,0,86.8-15.5,119.8-41.4l140.5,140.5c8.2,8.2,20.4,8.2,28.6,0C490,473.4,490,461.2,481.8,453z M41,191.4 c0-82.8,68.2-150.1,151.9-150.1s151.9,67.3,151.9,150.1s-68.2,150.1-151.9,150.1S41,274.1,41,191.4z"/> </g> </g> <g> </g> <g> </g> </svg>',
|
||||
close: '<svg style="height: 11px !important;" viewBox="0 0 52 52" xmlns="http://www.w3.org/2000/svg"><path d="M28.94,26,51.39,3.55A2.08,2.08,0,0,0,48.45.61L26,23.06,3.55.61A2.08,2.08,0,0,0,.61,3.55L23.06,26,.61,48.45A2.08,2.08,0,0,0,2.08,52a2.05,2.05,0,0,0,1.47-.61L26,28.94,48.45,51.39a2.08,2.08,0,0,0,2.94-2.94Z"/></svg>',
|
||||
move: '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512.006 512.006" xml:space="preserve"> <g> <g> <path d="M508.247,246.756l-72.457-72.465c-5.009-5.009-13.107-5.009-18.116,0c-5.009,5.009-5.009,13.107,0,18.116l50.594,50.594 H268.811V43.748l50.594,50.594c5.009,5.009,13.107,5.009,18.116,0c5.009-5.009,5.009-13.107,0-18.116L265.056,3.761 c-5.001-5.009-13.107-5.009-18.116,0l-72.457,72.457c-5.009,5.009-5.009,13.107,0,18.116c5.001,5.009,13.107,5.009,18.116,0 l50.594-50.594v199.27H43.744l50.594-50.594c5.009-5.009,5.009-13.107,0-18.116c-5.009-5.009-13.107-5.009-18.116,0L3.757,246.756 c-5.009,5.001-5.009,13.107,0,18.116l72.465,72.457c5.009,5.009,13.107,5.009,18.116,0c5.009-5.001,5.009-13.107,0-18.116 l-50.594-50.594h199.458v199.646l-50.594-50.594c-5.009-5.001-13.107-5.001-18.116,0c-5.009,5.009-5.009,13.107,0,18.116 l72.457,72.465c5,5,13.107,5,18.116,0l72.465-72.457c5.009-5.009,5.009-13.107,0-18.116c-5.009-5-13.107-5-18.116,0 l-50.594,50.594V268.627h199.458l-50.594,50.594c-5.009,5.009-5.009,13.107,0,18.116s13.107,5.009,18.116,0l72.465-72.457 C513.257,259.872,513.257,251.765,508.247,246.756z"/> </g> </g> <g> </g> </svg>'
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const functions = {
|
||||
|
||||
styles: () => {
|
||||
|
||||
const styles = `
|
||||
<style>
|
||||
.fg-emoji-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: ${pickerWidth}px;
|
||||
height: ${pickerHeight}px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 3px 20px 0px rgba(0, 0, 0, 0.62);
|
||||
background-color: white;
|
||||
overflow: hidden;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.fg-emoji-container svg {
|
||||
max-width: 100%;
|
||||
box-sizing: border-box;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
.fg-emoji-picker-category-title {
|
||||
display: block;
|
||||
margin: 20px 0 0 0;
|
||||
padding: 0 10px 5px 10px;
|
||||
font-size: 16px;
|
||||
font-family: sans-serif;
|
||||
font-weight: bold;
|
||||
flex: 0 0 calc(100% - 20px);
|
||||
border-bottom: 1px solid #ededed;
|
||||
}
|
||||
|
||||
.fg-emoji-nav {
|
||||
background-color: #646772;
|
||||
}
|
||||
|
||||
.fg-emoji-nav li a svg {
|
||||
transition: all .2s ease;
|
||||
fill: white;
|
||||
}
|
||||
|
||||
.fg-emoji-nav li:hover a svg {
|
||||
fill: black;
|
||||
}
|
||||
|
||||
.fg-emoji-nav ul {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border-bottom: 1px solid #dbdbdb;
|
||||
}
|
||||
|
||||
.fg-emoji-nav ul li {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.fg-emoji-nav ul li a {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
transition: all .2s ease;
|
||||
}
|
||||
|
||||
.fg-emoji-nav ul li a:hover {
|
||||
background-color: #e9ebf1;
|
||||
}
|
||||
|
||||
.fg-emoji-nav ul li.active a {
|
||||
background-color: #e9ebf1;
|
||||
}
|
||||
|
||||
.fg-emoji-nav ul li.emoji-picker-nav-active a {
|
||||
background-color: #e9ebf1;
|
||||
}
|
||||
|
||||
.fg-emoji-nav ul li.emoji-picker-nav-active a svg {
|
||||
fill: #646772;
|
||||
}
|
||||
|
||||
.fg-emoji-picker-move {
|
||||
/* pointer-events: none; */
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.fg-picker-special-buttons a {
|
||||
background-color: ${this.options.specialButtons ? this.options.specialButtons : '#ed5e28'};
|
||||
}
|
||||
|
||||
.fg-picker-special-buttons:last-child a {
|
||||
box-shadow: inset 1px 0px 0px 0 rgba(0, 0, 0, 0.11);
|
||||
}
|
||||
|
||||
.fg-emoji-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
height: 323px;
|
||||
}
|
||||
|
||||
.fg-emoji-picker-category-wrapper {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.fg-emoji-list li {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex: 0 0 calc(100% / 6);
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.fg-emoji-list li a {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 23px;
|
||||
background-color: #ffffff;
|
||||
border-radius: 3px;
|
||||
transition: all .3s ease;
|
||||
}
|
||||
|
||||
.fg-emoji-list li a:hover {
|
||||
background-color: #ebebeb;
|
||||
}
|
||||
|
||||
.fg-emoji-picker-search {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.fg-emoji-picker-search input {
|
||||
border: none;
|
||||
box-shadow: 0 0 0 0;
|
||||
outline: none;
|
||||
width: calc(100% - 30px);
|
||||
display: block;
|
||||
padding: 10px 15px;
|
||||
background-color: #f3f3f3;
|
||||
}
|
||||
|
||||
.fg-emoji-picker-search .fg-emoji-picker-search-icon {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 40px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
</style>
|
||||
`;
|
||||
|
||||
document.head.insertAdjacentHTML('beforeend', styles);
|
||||
},
|
||||
|
||||
|
||||
position: () => {
|
||||
|
||||
const e = window.event;
|
||||
const clickPosX = e.clientX;
|
||||
const clickPosY = e.clientY;
|
||||
const obj = {};
|
||||
|
||||
obj.left = clickPosX;
|
||||
obj.top = clickPosY;
|
||||
|
||||
return obj;
|
||||
|
||||
},
|
||||
|
||||
|
||||
rePositioning: (picker) => {
|
||||
picker.getBoundingClientRect().right > window.screen.availWidth ? picker.style.left = window.screen.availWidth - picker.offsetWidth + 'px' : false;
|
||||
|
||||
if (window.innerHeight > pickerHeight) {
|
||||
picker.getBoundingClientRect().bottom > window.innerHeight ? picker.style.top = window.innerHeight - picker.offsetHeight + 'px' : false;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
render: (e, attr) => {
|
||||
// attr is empty in friendica, no idea why..
|
||||
if (!attr) attr='.emojis'
|
||||
emojiList = undefined;
|
||||
const index = this.options.trigger.findIndex(item => item.selector === attr);
|
||||
this.insertInto = this.options.trigger[index].insertInto;
|
||||
|
||||
const position = functions.position();
|
||||
|
||||
if (!emojiesHTML.length) {
|
||||
|
||||
for (const key in emojiObj) {
|
||||
if (emojiObj.hasOwnProperty.call(emojiObj, key)) {
|
||||
const categoryObj = emojiObj[key];
|
||||
|
||||
|
||||
categoriesHTML += `<li>
|
||||
<a title="${key}" href="#${key}">${categoryFlags[key]}</a>
|
||||
</li>`;
|
||||
|
||||
emojiesHTML += `<div class="fg-emoji-picker-category-wrapper" id="${key}">`;
|
||||
emojiesHTML += `<p class="fg-emoji-picker-category-title">${key}</p>`;
|
||||
categoryObj.forEach(ej => {
|
||||
emojiesHTML += `<li data-title="${ej.title.toLowerCase()}">
|
||||
<a title="${ej.title}" href="#">${ej.emoji}</a>
|
||||
</li>`;
|
||||
});
|
||||
emojiesHTML += '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (document.querySelector('.fg-emoji-container')) {
|
||||
this.lib('.fg-emoji-container').remove();
|
||||
}
|
||||
|
||||
|
||||
const picker = `
|
||||
<div class="fg-emoji-container" style="left: ${position.left}px; top: ${position.top}px;">
|
||||
<nav class="fg-emoji-nav">
|
||||
<ul>
|
||||
${categoriesHTML}
|
||||
|
||||
<li class="fg-picker-special-buttons" id="fg-emoji-picker-move"><a class="fg-emoji-picker-move" href="#">${icons.move}</a></li>
|
||||
${this.options.closeButton ? `<li class="fg-picker-special-buttons"><a id="fg-emoji-picker-close-button" href="#">`+icons.close+`</a></li>` : ''}
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<div class="fg-emoji-picker-search">
|
||||
<input type="text" placeholder="Search" autofocus />
|
||||
|
||||
<span class="fg-emoji-picker-search-icon">${icons.search}</sapn>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<!--<div class="fg-emoji-picker-loader-animation">
|
||||
<div class="spinner">
|
||||
<div class="bounce1"></div>
|
||||
<div class="bounce2"></div>
|
||||
<div class="bounce3"></div>
|
||||
</div>
|
||||
</div>-->
|
||||
|
||||
<ul class="fg-emoji-list">
|
||||
${emojiesHTML}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.insertAdjacentHTML('beforeend', picker);
|
||||
|
||||
functions.rePositioning(document.querySelector('.fg-emoji-container'));
|
||||
|
||||
setTimeout(() => {
|
||||
document.querySelector('.fg-emoji-picker-search input').focus();
|
||||
}, 500)
|
||||
},
|
||||
|
||||
|
||||
closePicker: (e) => {
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
this.lib('.fg-emoji-container').remove();
|
||||
|
||||
moseMove = false;
|
||||
},
|
||||
|
||||
|
||||
checkPickerExist(e) {
|
||||
|
||||
if (document.querySelector('.fg-emoji-container') && !e.target.closest('.fg-emoji-container') && !moseMove) {
|
||||
|
||||
functions.closePicker.call(this, e);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
setCaretPosition: (field, caretPos) => {
|
||||
var elem = field
|
||||
if (elem != null) {
|
||||
if (elem.createTextRange) {
|
||||
var range = elem.createTextRange();
|
||||
range.move('character', caretPos);
|
||||
range.select();
|
||||
} else {
|
||||
if (elem.selectionStart) {
|
||||
elem.focus();
|
||||
elem.setSelectionRange(caretPos, caretPos);
|
||||
} else {
|
||||
elem.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
insert: e => {
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
const emoji = e.target.innerText.trim();
|
||||
const myField = document.querySelectorAll(this.insertInto);
|
||||
const myValue = emoji;
|
||||
|
||||
// Check if selector is an array
|
||||
myField.forEach(myField => {
|
||||
|
||||
if (document.selection) {
|
||||
myField.focus();
|
||||
sel = document.selection.createRange();
|
||||
sel.text = myValue;
|
||||
} else if (myField.selectionStart || myField.selectionStart == "0") {
|
||||
const startPos = myField.selectionStart;
|
||||
const endPos = myField.selectionEnd;
|
||||
myField.value = myField.value.substring(0, startPos) + myValue + myField.value.substring(endPos, myField.value.length);
|
||||
|
||||
functions.setCaretPosition(myField, startPos + 2)
|
||||
|
||||
} else {
|
||||
myField.value += myValue;
|
||||
myField.focus()
|
||||
}
|
||||
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
categoryNav: e => {
|
||||
e.preventDefault();
|
||||
|
||||
const link = e.target.closest('a');
|
||||
|
||||
if (link.getAttribute('id') && link.getAttribute('id') === 'fg-emoji-picker-close-button') return false;
|
||||
if (link.className.includes('fg-emoji-picker-move')) return false;
|
||||
|
||||
const id = link.getAttribute('href');
|
||||
const emojiBody = document.querySelector('.fg-emoji-list');
|
||||
const destination = emojiBody.querySelector(`${id}`);
|
||||
|
||||
this.lib('.fg-emoji-nav li').removeClass('emoji-picker-nav-active');
|
||||
link.closest('li').classList.add('emoji-picker-nav-active');
|
||||
|
||||
destination.scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"})
|
||||
},
|
||||
|
||||
|
||||
search: e => {
|
||||
|
||||
const val = e.target.value.trim();
|
||||
|
||||
if (!emojiList) {
|
||||
emojiList = Array.from(document.querySelectorAll('.fg-emoji-picker-category-wrapper li'));
|
||||
}
|
||||
|
||||
emojiList.filter(emoji => {
|
||||
if (!emoji.getAttribute('data-title').match(val)) {
|
||||
emoji.style.display = 'none'
|
||||
} else {
|
||||
emoji.style.display = ''
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
mouseDown: e => {
|
||||
e.preventDefault();
|
||||
moseMove = true;
|
||||
},
|
||||
|
||||
mouseUp: e => {
|
||||
e.preventDefault();
|
||||
moseMove = false;
|
||||
},
|
||||
|
||||
mouseMove: e => {
|
||||
|
||||
if (moseMove) {
|
||||
e.preventDefault();
|
||||
const el = document.querySelector('.fg-emoji-container');
|
||||
el.style.left = e.clientX - 320 + 'px';
|
||||
el.style.top = e.clientY - 10 + 'px';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
const bindEvents = () => {
|
||||
|
||||
this.lib(document.body).on('click', functions.closePicker, '#fg-emoji-picker-close-button');
|
||||
this.lib(document.body).on('click', functions.checkPickerExist);
|
||||
this.lib(document.body).on('click', functions.render, this.trigger);
|
||||
this.lib(document.body).on('click', functions.insert, '.fg-emoji-list a');
|
||||
this.lib(document.body).on('click', functions.categoryNav, '.fg-emoji-nav a');
|
||||
this.lib(document.body).on('input', functions.search, '.fg-emoji-picker-search input');
|
||||
this.lib(document).on('mousedown', functions.mouseDown, '#fg-emoji-picker-move');
|
||||
this.lib(document).on('mouseup', functions.mouseUp, '#fg-emoji-picker-move');
|
||||
this.lib(document).on('mousemove', functions.mouseMove);
|
||||
};
|
||||
|
||||
|
||||
|
||||
(() => {
|
||||
|
||||
// Start styles
|
||||
functions.styles();
|
||||
|
||||
// Event functions
|
||||
bindEvents.call(this);
|
||||
|
||||
})()
|
||||
}
|
||||
202
view/js/vanillaEmojiPicker/vanillaEmojiPicker.min.js
vendored
Normal file
202
view/js/vanillaEmojiPicker/vanillaEmojiPicker.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: 2023.06-dev\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-04-23 21:21+0000\n"
|
||||
"POT-Creation-Date: 2023-05-04 10:54+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
|
@ -292,7 +292,7 @@ msgid "Insert web link"
|
|||
msgstr ""
|
||||
|
||||
#: mod/message.php:202 mod/message.php:358 mod/photos.php:1291
|
||||
#: src/Content/Conversation.php:389 src/Content/Conversation.php:733
|
||||
#: src/Content/Conversation.php:390 src/Content/Conversation.php:734
|
||||
#: src/Module/Item/Compose.php:204 src/Module/Post/Edit.php:145
|
||||
#: src/Module/Profile/UnkMail.php:154 src/Object/Post.php:550
|
||||
msgid "Please wait"
|
||||
|
|
@ -475,8 +475,8 @@ msgstr ""
|
|||
msgid "Do not show a status post for this upload"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:733 mod/photos.php:1093 src/Content/Conversation.php:391
|
||||
#: src/Module/Calendar/Event/Form.php:253 src/Module/Post/Edit.php:182
|
||||
#: mod/photos.php:733 mod/photos.php:1093 src/Content/Conversation.php:392
|
||||
#: src/Module/Calendar/Event/Form.php:253 src/Module/Post/Edit.php:183
|
||||
msgid "Permissions"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -488,7 +488,7 @@ msgstr ""
|
|||
msgid "Delete Album"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:798 mod/photos.php:899 src/Content/Conversation.php:407
|
||||
#: mod/photos.php:798 mod/photos.php:899 src/Content/Conversation.php:408
|
||||
#: src/Module/Contact/Follow.php:173 src/Module/Contact/Revoke.php:109
|
||||
#: src/Module/Contact/Unfollow.php:126
|
||||
#: src/Module/Media/Attachment/Browser.php:77
|
||||
|
|
@ -606,9 +606,9 @@ msgid "Comment"
|
|||
msgstr ""
|
||||
|
||||
#: mod/photos.php:1139 mod/photos.php:1195 mod/photos.php:1269
|
||||
#: src/Content/Conversation.php:404 src/Module/Calendar/Event/Form.php:248
|
||||
#: src/Content/Conversation.php:405 src/Module/Calendar/Event/Form.php:248
|
||||
#: src/Module/Item/Compose.php:199 src/Module/Post/Edit.php:165
|
||||
#: src/Object/Post.php:1074
|
||||
#: src/Object/Post.php:1075
|
||||
msgid "Preview"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -617,11 +617,11 @@ msgstr ""
|
|||
msgid "Loading..."
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:1226 src/Content/Conversation.php:649 src/Object/Post.php:257
|
||||
#: mod/photos.php:1226 src/Content/Conversation.php:650 src/Object/Post.php:257
|
||||
msgid "Select"
|
||||
msgstr ""
|
||||
|
||||
#: mod/photos.php:1227 src/Content/Conversation.php:650
|
||||
#: mod/photos.php:1227 src/Content/Conversation.php:651
|
||||
#: src/Module/Moderation/Users/Active.php:136
|
||||
#: src/Module/Moderation/Users/Blocked.php:136
|
||||
#: src/Module/Moderation/Users/Index.php:151
|
||||
|
|
@ -1213,7 +1213,7 @@ msgid "Visible to <strong>everybody</strong>"
|
|||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:329 src/Module/Item/Compose.php:198
|
||||
#: src/Object/Post.php:1073
|
||||
#: src/Object/Post.php:1074
|
||||
msgid "Please enter a image/video/audio/webpage URL:"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1277,197 +1277,202 @@ msgstr ""
|
|||
msgid "Quote"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:368 src/Module/Item/Compose.php:194
|
||||
#: src/Module/Post/Edit.php:175 src/Object/Post.php:1069
|
||||
#: src/Content/Conversation.php:368 src/Module/Post/Edit.php:175
|
||||
#: src/Object/Post.php:1069
|
||||
msgid "Add emojis"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:369 src/Module/Item/Compose.php:194
|
||||
#: src/Module/Post/Edit.php:176 src/Object/Post.php:1070
|
||||
msgid "Code"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:369 src/Module/Item/Compose.php:195
|
||||
#: src/Object/Post.php:1070
|
||||
#: src/Content/Conversation.php:370 src/Module/Item/Compose.php:195
|
||||
#: src/Object/Post.php:1071
|
||||
msgid "Image"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:370 src/Module/Item/Compose.php:196
|
||||
#: src/Module/Post/Edit.php:176 src/Object/Post.php:1071
|
||||
#: src/Content/Conversation.php:371 src/Module/Item/Compose.php:196
|
||||
#: src/Module/Post/Edit.php:177 src/Object/Post.php:1072
|
||||
msgid "Link"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:371 src/Module/Item/Compose.php:197
|
||||
#: src/Module/Post/Edit.php:177 src/Object/Post.php:1072
|
||||
#: src/Content/Conversation.php:372 src/Module/Item/Compose.php:197
|
||||
#: src/Module/Post/Edit.php:178 src/Object/Post.php:1073
|
||||
msgid "Link or Media"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:372
|
||||
#: src/Content/Conversation.php:373
|
||||
msgid "Video"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:373 src/Module/Item/Compose.php:200
|
||||
#: src/Content/Conversation.php:374 src/Module/Item/Compose.php:200
|
||||
#: src/Module/Post/Edit.php:141
|
||||
msgid "Set your location"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:374 src/Module/Post/Edit.php:142
|
||||
#: src/Content/Conversation.php:375 src/Module/Post/Edit.php:142
|
||||
msgid "set location"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:375 src/Module/Post/Edit.php:143
|
||||
#: src/Content/Conversation.php:376 src/Module/Post/Edit.php:143
|
||||
msgid "Clear browser location"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:376 src/Module/Post/Edit.php:144
|
||||
#: src/Content/Conversation.php:377 src/Module/Post/Edit.php:144
|
||||
msgid "clear location"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:378 src/Module/Item/Compose.php:205
|
||||
#: src/Content/Conversation.php:379 src/Module/Item/Compose.php:205
|
||||
#: src/Module/Post/Edit.php:157
|
||||
msgid "Set title"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:380 src/Module/Item/Compose.php:206
|
||||
#: src/Content/Conversation.php:381 src/Module/Item/Compose.php:206
|
||||
#: src/Module/Post/Edit.php:159
|
||||
msgid "Categories (comma-separated list)"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:385 src/Module/Item/Compose.php:222
|
||||
#: src/Content/Conversation.php:386 src/Module/Item/Compose.php:222
|
||||
msgid "Scheduled at"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:390 src/Module/Post/Edit.php:146
|
||||
#: src/Content/Conversation.php:391 src/Module/Post/Edit.php:146
|
||||
msgid "Permission settings"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:400 src/Module/Post/Edit.php:155
|
||||
#: src/Content/Conversation.php:401 src/Module/Post/Edit.php:155
|
||||
msgid "Public post"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:414 src/Content/Widget/VCard.php:113
|
||||
#: src/Content/Conversation.php:415 src/Content/Widget/VCard.php:113
|
||||
#: src/Model/Profile.php:469 src/Module/Admin/Logs/View.php:92
|
||||
#: src/Module/Post/Edit.php:180
|
||||
#: src/Module/Post/Edit.php:181
|
||||
msgid "Message"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:415 src/Module/Post/Edit.php:181
|
||||
#: src/Content/Conversation.php:416 src/Module/Post/Edit.php:182
|
||||
#: src/Module/Settings/TwoFactor/Trusted.php:140
|
||||
msgid "Browser"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:417 src/Module/Post/Edit.php:184
|
||||
#: src/Content/Conversation.php:418 src/Module/Post/Edit.php:185
|
||||
msgid "Open Compose page"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:677 src/Object/Post.php:244
|
||||
#: src/Content/Conversation.php:678 src/Object/Post.php:244
|
||||
msgid "Pinned item"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:693 src/Object/Post.php:496
|
||||
#: src/Content/Conversation.php:694 src/Object/Post.php:496
|
||||
#: src/Object/Post.php:497
|
||||
#, php-format
|
||||
msgid "View %s's profile @ %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:706 src/Object/Post.php:484
|
||||
#: src/Content/Conversation.php:707 src/Object/Post.php:484
|
||||
msgid "Categories:"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:707 src/Object/Post.php:485
|
||||
#: src/Content/Conversation.php:708 src/Object/Post.php:485
|
||||
msgid "Filed under:"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:715 src/Object/Post.php:510
|
||||
#: src/Content/Conversation.php:716 src/Object/Post.php:510
|
||||
#, php-format
|
||||
msgid "%s from %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:731
|
||||
#: src/Content/Conversation.php:732
|
||||
msgid "View in context"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:796
|
||||
#: src/Content/Conversation.php:797
|
||||
msgid "remove"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:800
|
||||
#: src/Content/Conversation.php:801
|
||||
msgid "Delete Selected Items"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:865 src/Content/Conversation.php:868
|
||||
#: src/Content/Conversation.php:871 src/Content/Conversation.php:874
|
||||
#: src/Content/Conversation.php:877
|
||||
#: src/Content/Conversation.php:866 src/Content/Conversation.php:869
|
||||
#: src/Content/Conversation.php:872 src/Content/Conversation.php:875
|
||||
#: src/Content/Conversation.php:878
|
||||
#, php-format
|
||||
msgid "You had been addressed (%s)."
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:880
|
||||
#: src/Content/Conversation.php:881
|
||||
#, php-format
|
||||
msgid "You are following %s."
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:883
|
||||
#: src/Content/Conversation.php:884
|
||||
msgid "You subscribed to one or more tags in this post."
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:896
|
||||
#: src/Content/Conversation.php:897
|
||||
#, php-format
|
||||
msgid "%s reshared this."
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:898
|
||||
#: src/Content/Conversation.php:899
|
||||
msgid "Reshared"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:898
|
||||
#: src/Content/Conversation.php:899
|
||||
#, php-format
|
||||
msgid "Reshared by %s <%s>"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:901
|
||||
#: src/Content/Conversation.php:902
|
||||
#, php-format
|
||||
msgid "%s is participating in this thread."
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:904
|
||||
#: src/Content/Conversation.php:905
|
||||
msgid "Stored for general reasons"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:907
|
||||
#: src/Content/Conversation.php:908
|
||||
msgid "Global post"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:910
|
||||
#: src/Content/Conversation.php:911
|
||||
msgid "Sent via an relay server"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:910
|
||||
#: src/Content/Conversation.php:911
|
||||
#, php-format
|
||||
msgid "Sent via the relay server %s <%s>"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:913
|
||||
#: src/Content/Conversation.php:914
|
||||
msgid "Fetched"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:913
|
||||
#: src/Content/Conversation.php:914
|
||||
#, php-format
|
||||
msgid "Fetched because of %s <%s>"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:916
|
||||
#: src/Content/Conversation.php:917
|
||||
msgid "Stored because of a child post to complete this thread."
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:919
|
||||
#: src/Content/Conversation.php:920
|
||||
msgid "Local delivery"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:922
|
||||
#: src/Content/Conversation.php:923
|
||||
msgid "Stored because of your activity (like, comment, star, ...)"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:925
|
||||
#: src/Content/Conversation.php:926
|
||||
msgid "Distributed"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Conversation.php:928
|
||||
#: src/Content/Conversation.php:929
|
||||
msgid "Pushed to us"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1601,57 +1606,57 @@ msgstr ""
|
|||
msgid "show more"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:326 src/Model/Item.php:2922
|
||||
#: src/Content/Item.php:327 src/Model/Item.php:2927
|
||||
msgid "event"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:329 src/Content/Item.php:339
|
||||
#: src/Content/Item.php:330 src/Content/Item.php:340
|
||||
msgid "status"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:335 src/Model/Item.php:2924
|
||||
#: src/Content/Item.php:336 src/Model/Item.php:2929
|
||||
#: src/Module/Post/Tag/Add.php:123
|
||||
msgid "photo"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:349 src/Module/Post/Tag/Add.php:141
|
||||
#: src/Content/Item.php:350 src/Module/Post/Tag/Add.php:141
|
||||
#, php-format
|
||||
msgid "%1$s tagged %2$s's %3$s with %4$s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:419 view/theme/frio/theme.php:262
|
||||
#: src/Content/Item.php:420 view/theme/frio/theme.php:262
|
||||
msgid "Follow Thread"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:420 src/Model/Contact.php:1204
|
||||
#: src/Content/Item.php:421 src/Model/Contact.php:1204
|
||||
msgid "View Status"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:421 src/Content/Item.php:441 src/Model/Contact.php:1148
|
||||
#: src/Content/Item.php:422 src/Content/Item.php:442 src/Model/Contact.php:1148
|
||||
#: src/Model/Contact.php:1196 src/Model/Contact.php:1205
|
||||
#: src/Module/Directory.php:157 src/Module/Settings/Profile/Index.php:233
|
||||
msgid "View Profile"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:422 src/Model/Contact.php:1206
|
||||
#: src/Content/Item.php:423 src/Model/Contact.php:1206
|
||||
msgid "View Photos"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:423 src/Model/Contact.php:1197
|
||||
#: src/Content/Item.php:424 src/Model/Contact.php:1197
|
||||
#: src/Model/Contact.php:1207
|
||||
msgid "Network Posts"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:424 src/Model/Contact.php:1198
|
||||
#: src/Content/Item.php:425 src/Model/Contact.php:1198
|
||||
#: src/Model/Contact.php:1208
|
||||
msgid "View Contact"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:425 src/Model/Contact.php:1209
|
||||
#: src/Content/Item.php:426 src/Model/Contact.php:1209
|
||||
msgid "Send PM"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:426 src/Module/Contact.php:439
|
||||
#: src/Content/Item.php:427 src/Module/Contact.php:439
|
||||
#: src/Module/Contact/Profile.php:477
|
||||
#: src/Module/Moderation/Blocklist/Contact.php:116
|
||||
#: src/Module/Moderation/Users/Active.php:137
|
||||
|
|
@ -1659,7 +1664,7 @@ msgstr ""
|
|||
msgid "Block"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:427 src/Module/Contact.php:440
|
||||
#: src/Content/Item.php:428 src/Module/Contact.php:440
|
||||
#: src/Module/Contact/Profile.php:485
|
||||
#: src/Module/Notifications/Introductions.php:134
|
||||
#: src/Module/Notifications/Introductions.php:206
|
||||
|
|
@ -1667,22 +1672,22 @@ msgstr ""
|
|||
msgid "Ignore"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:428 src/Module/Contact.php:441
|
||||
#: src/Content/Item.php:429 src/Module/Contact.php:441
|
||||
#: src/Module/Contact/Profile.php:493
|
||||
msgid "Collapse"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:432 src/Object/Post.php:465
|
||||
#: src/Content/Item.php:433 src/Object/Post.php:465
|
||||
msgid "Languages"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:438 src/Content/Widget.php:80
|
||||
#: src/Content/Item.php:439 src/Content/Widget.php:80
|
||||
#: src/Model/Contact.php:1199 src/Model/Contact.php:1210
|
||||
#: src/Module/Contact/Follow.php:167 view/theme/vier/theme.php:196
|
||||
msgid "Connect/Follow"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Item.php:863
|
||||
#: src/Content/Item.php:864
|
||||
msgid "Unable to fetch user."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -2015,8 +2020,8 @@ msgid ""
|
|||
"<a href=\"%1$s\" target=\"_blank\" rel=\"noopener noreferrer\">%2$s</a> %3$s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Text/BBCode.php:956 src/Model/Item.php:3607
|
||||
#: src/Model/Item.php:3613 src/Model/Item.php:3614
|
||||
#: src/Content/Text/BBCode.php:956 src/Model/Item.php:3645
|
||||
#: src/Model/Item.php:3651 src/Model/Item.php:3652
|
||||
msgid "Link to source"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -2119,7 +2124,7 @@ msgstr ""
|
|||
msgid "Local Directory"
|
||||
msgstr ""
|
||||
|
||||
#: src/Content/Widget.php:215 src/Model/Group.php:587
|
||||
#: src/Content/Widget.php:215 src/Model/Group.php:596
|
||||
#: src/Module/Contact.php:394 src/Module/Welcome.php:76
|
||||
msgid "Groups"
|
||||
msgstr ""
|
||||
|
|
@ -2975,68 +2980,68 @@ msgstr ""
|
|||
msgid "Forum"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Contact.php:2947
|
||||
#: src/Model/Contact.php:2952
|
||||
msgid "Disallowed profile URL."
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Contact.php:2952 src/Module/Friendica.php:83
|
||||
#: src/Model/Contact.php:2957 src/Module/Friendica.php:83
|
||||
msgid "Blocked domain"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Contact.php:2957
|
||||
#: src/Model/Contact.php:2962
|
||||
msgid "Connect URL missing."
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Contact.php:2966
|
||||
#: src/Model/Contact.php:2971
|
||||
msgid ""
|
||||
"The contact could not be added. Please check the relevant network "
|
||||
"credentials in your Settings -> Social Networks page."
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Contact.php:2984
|
||||
#: src/Model/Contact.php:2989
|
||||
#, php-format
|
||||
msgid "Expected network %s does not match actual network %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Contact.php:3001
|
||||
#: src/Model/Contact.php:3006
|
||||
msgid "The profile address specified does not provide adequate information."
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Contact.php:3003
|
||||
#: src/Model/Contact.php:3008
|
||||
msgid "No compatible communication protocols or feeds were discovered."
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Contact.php:3006
|
||||
#: src/Model/Contact.php:3011
|
||||
msgid "An author or name was not found."
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Contact.php:3009
|
||||
#: src/Model/Contact.php:3014
|
||||
msgid "No browser URL could be matched to this address."
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Contact.php:3012
|
||||
#: src/Model/Contact.php:3017
|
||||
msgid ""
|
||||
"Unable to match @-style Identity Address with a known protocol or email "
|
||||
"contact."
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Contact.php:3013
|
||||
#: src/Model/Contact.php:3018
|
||||
msgid "Use mailto: in front of address to force email check."
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Contact.php:3019
|
||||
#: src/Model/Contact.php:3024
|
||||
msgid ""
|
||||
"The profile address specified belongs to a network which has been disabled "
|
||||
"on this site."
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Contact.php:3024
|
||||
#: src/Model/Contact.php:3029
|
||||
msgid ""
|
||||
"Limited profile. This person will be unable to receive direct/personal "
|
||||
"notifications from you."
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Contact.php:3089
|
||||
#: src/Model/Contact.php:3094
|
||||
msgid "Unable to retrieve contact information."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -3148,40 +3153,40 @@ msgid ""
|
|||
"not what you intended, please create another group with a different name."
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Group.php:503
|
||||
#: src/Model/Group.php:512
|
||||
msgid "Default privacy group for new contacts"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Group.php:535
|
||||
#: src/Model/Group.php:544
|
||||
msgid "Everybody"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Group.php:554
|
||||
#: src/Model/Group.php:563
|
||||
msgid "edit"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Group.php:586
|
||||
#: src/Model/Group.php:595
|
||||
msgid "add"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Group.php:591
|
||||
#: src/Model/Group.php:600
|
||||
msgid "Edit group"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Group.php:592 src/Module/Group.php:192
|
||||
#: src/Model/Group.php:601 src/Module/Group.php:192
|
||||
msgid "Contacts not in any group"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Group.php:594
|
||||
#: src/Model/Group.php:603
|
||||
msgid "Create a new group"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Group.php:595 src/Module/Group.php:177 src/Module/Group.php:200
|
||||
#: src/Model/Group.php:604 src/Module/Group.php:177 src/Module/Group.php:200
|
||||
#: src/Module/Group.php:275
|
||||
msgid "Group Name: "
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Group.php:596
|
||||
#: src/Model/Group.php:605
|
||||
msgid "Edit groups"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -3190,76 +3195,76 @@ msgstr ""
|
|||
msgid "Detected languages in this post:\\n%s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:2926
|
||||
#: src/Model/Item.php:2931
|
||||
msgid "activity"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:2928
|
||||
#: src/Model/Item.php:2933
|
||||
msgid "comment"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:2931 src/Module/Post/Tag/Add.php:123
|
||||
#: src/Model/Item.php:2936 src/Module/Post/Tag/Add.php:123
|
||||
msgid "post"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:3093
|
||||
#: src/Model/Item.php:3105
|
||||
#, php-format
|
||||
msgid "%s is blocked"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:3095
|
||||
#: src/Model/Item.php:3107
|
||||
#, php-format
|
||||
msgid "%s is ignored"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:3097
|
||||
#: src/Model/Item.php:3109
|
||||
#, php-format
|
||||
msgid "Content from %s is collapsed"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:3101
|
||||
#: src/Model/Item.php:3113
|
||||
#, php-format
|
||||
msgid "Content warning: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:3519
|
||||
#: src/Model/Item.php:3557
|
||||
msgid "bytes"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:3550
|
||||
#: src/Model/Item.php:3588
|
||||
#, php-format
|
||||
msgid "%2$s (%3$d%%, %1$d vote)"
|
||||
msgid_plural "%2$s (%3$d%%, %1$d votes)"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: src/Model/Item.php:3552
|
||||
#: src/Model/Item.php:3590
|
||||
#, php-format
|
||||
msgid "%2$s (%1$d vote)"
|
||||
msgid_plural "%2$s (%1$d votes)"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: src/Model/Item.php:3557
|
||||
#: src/Model/Item.php:3595
|
||||
#, php-format
|
||||
msgid "%d voter. Poll end: %s"
|
||||
msgid_plural "%d voters. Poll end: %s"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: src/Model/Item.php:3559
|
||||
#: src/Model/Item.php:3597
|
||||
#, php-format
|
||||
msgid "%d voter."
|
||||
msgid_plural "%d voters."
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: src/Model/Item.php:3561
|
||||
#: src/Model/Item.php:3599
|
||||
#, php-format
|
||||
msgid "Poll end: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/Model/Item.php:3595 src/Model/Item.php:3596
|
||||
#: src/Model/Item.php:3633 src/Model/Item.php:3634
|
||||
msgid "View on separate page"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{{if $image.preview}}
|
||||
<a href="{{$image.attachment.url}}"><img src="{{$image.preview}}" alt="{{$image.attachment.description}}" title="{{$image.attachment.description}}"></a>
|
||||
<a data-fancybox="{{$image.uri_id}}" href="{{$image.attachment.url}}"><img src="{{$image.preview}}" alt="{{$image.attachment.description}}" title="{{$image.attachment.description}}"></a>
|
||||
{{else}}
|
||||
<img src="{{$image.src}}" alt="{{$image.attachment.description}}" title="{{$image.attachment.description}}">
|
||||
{{/if}}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
<link rel="stylesheet" href="view/asset/jgrowl/jquery.jgrowl.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="view/asset/jquery-datetimepicker/build/jquery.datetimepicker.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="view/asset/perfect-scrollbar/dist/css/perfect-scrollbar.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="view/js/fancybox/jquery.fancybox.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
||||
|
||||
{{foreach $stylesheets as $stylesheetUrl => $media}}
|
||||
<link rel="stylesheet" href="{{$stylesheetUrl}}" type="text/css" media="{{$media}}" />
|
||||
|
|
@ -44,6 +45,8 @@
|
|||
<script type="text/javascript" src="view/asset/imagesloaded/imagesloaded.pkgd.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||
<script type="text/javascript" src="view/asset/base64/base64.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||
<script type="text/javascript" src="view/asset/dompurify/dist/purify.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||
<script type="text/javascript" src="view/js/fancybox/jquery.fancybox.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||
<script type="text/javascript" src="view/js/fancybox/fancybox.config.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||
<script type="text/javascript">
|
||||
const updateInterval = {{$update_interval}};
|
||||
const localUser = {{if $local_user}}{{$local_user}}{{else}}false{{/if}};
|
||||
|
|
|
|||
|
|
@ -44,6 +44,9 @@
|
|||
<button type="button" class="btn btn-sm template-icon quote" aria-label="{{$l10n.edquote}}" title="{{$l10n.edquote}}" onclick="insertFormatting('quote',{{$id}});" tabindex="13">
|
||||
<i class="fa fa-quote-left"></i>
|
||||
</button>
|
||||
<button id="button_emojipicker" type="button" class="btn btn-sm template-icon emojis" aria-label="{{$l10n.edemojis}}" title="{{$l10n.edemojis}}" tabindex="14">
|
||||
<i class="fa fa-smile-o"></i>
|
||||
</button>
|
||||
</span>
|
||||
</p>
|
||||
<div id="dropzone-{{$id}}" class="dropzone" style="overflow:scroll">
|
||||
|
|
@ -98,3 +101,16 @@
|
|||
<script>
|
||||
dzFactory.setupDropzone('#dropzone-{{$id}}', 'comment-edit-text-{{$id}}');
|
||||
</script>
|
||||
<script>
|
||||
window.onload = function(){
|
||||
new EmojiPicker({
|
||||
trigger: [
|
||||
{
|
||||
selector: '.emojis',
|
||||
insertInto: '.comment-edit-text'
|
||||
}
|
||||
],
|
||||
closeButton: true,
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -29,33 +29,6 @@ $(document).ready(function () {
|
|||
}
|
||||
});
|
||||
|
||||
// Add Colorbox for viewing Network page images.
|
||||
//var cBoxClasses = new Array();
|
||||
$("body").on("click", ".wall-item-body a img", function () {
|
||||
var aElem = $(this).parent();
|
||||
var imgHref = aElem.attr("href");
|
||||
|
||||
// We need to make sure we only put a Colorbox on links to Friendica images.
|
||||
// We'll try to do this by looking for links of the form
|
||||
// .../photo/ab803d8eg08daf85023adfec08 (with nothing more following), in hopes
|
||||
// that will be unique enough.
|
||||
if (imgHref.match(/\/photo\/[a-fA-F0-9]+(-[0-9]\.[\w]+?)?$/)) {
|
||||
// Add a unique class to all the images of a certain post, to allow scrolling through
|
||||
var cBoxClass = $(this).closest(".wall-item-body").attr("id") + "-lightbox";
|
||||
$(this).addClass(cBoxClass);
|
||||
|
||||
// if( $.inArray(cBoxClass, cBoxClasses) < 0 ) {
|
||||
// cBoxClasses.push(cBoxClass);
|
||||
// }
|
||||
|
||||
aElem.colorbox({
|
||||
maxHeight: "90%",
|
||||
photo: true, // Colorbox doesn't recognize a URL that don't end in .jpg, etc. as a photo.
|
||||
rel: cBoxClass, //$(this).attr("class").match(/wall-item-body-[\d]+-lightbox/)[0].
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Navbar login.
|
||||
$("body").on("click", "#nav-login", function (e) {
|
||||
e.preventDefault();
|
||||
|
|
|
|||
|
|
@ -49,6 +49,10 @@
|
|||
type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="view/theme/frio/font/open_sans/open-sans.css?v={{$smarty.const.FRIENDICA_VERSION}}"
|
||||
type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="view/js/fancybox/jquery.fancybox.min.css?v={{$smarty.const.FRIENDICA_VERSION}}"
|
||||
type="text/css" media="screen" />
|
||||
<link rel="stylesheet" href="view/js/button/frio.css?v={{$smarty.const.FRIENDICA_VERSION}}"
|
||||
type="text/css" media="screen" />
|
||||
|
||||
{{* own css files *}}
|
||||
<link rel="stylesheet" href="view/theme/frio/css/hovercard.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css"
|
||||
|
|
@ -144,6 +148,9 @@
|
|||
<script type="text/javascript" src="vendor/enyo/dropzone/dist/min/dropzone.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||
<script type="text/javascript" src="view/js/dropzone-factory.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||
<script type="text/javascript"> const dzFactory = new DzFactory({{$max_imagesize}});</script>
|
||||
<script type="text/javascript" src="view/js/fancybox/jquery.fancybox.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||
<script type="text/javascript" src="view/js/fancybox/fancybox.config.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||
<script type="text/javascript" src="view/js/vanillaEmojiPicker/vanillaEmojiPicker.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||
|
||||
{{* Include the strings which are needed for some js functions (e.g. translation)
|
||||
They are loaded into the html <head> so that js functions can use them *}}
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@
|
|||
<li role="presentation"><button type="button" class="hidden-xs btn-link icon italic" style="cursor: pointer;" aria-label="{{$editalic}}" title="{{$editalic}}" onclick="insertFormattingToPost('i');"><i class="fa fa-italic"></i></button></li>
|
||||
<li role="presentation"><button type="button" class="hidden-xs btn-link icon bold" style="cursor: pointer;" aria-label="{{$edbold}}" title="{{$edbold}}" onclick="insertFormattingToPost('b');"><i class="fa fa-bold"></i></button></li>
|
||||
<li role="presentation"><button type="button" class="hidden-xs btn-link icon quote" style="cursor: pointer;" aria-label="{{$edquote}}" title="{{$edquote}}" onclick="insertFormattingToPost('quote');"><i class="fa fa-quote-left"></i></button></li>
|
||||
<li role="presentation"><button type="button" class="hidden-xs btn-link icon emojis" style="cursor: pointer;" aria-label="{{$edemojis}}" title="{{$edemojis}}"><i class="fa fa-smile-o"></i></button></li>
|
||||
<li role="presentation"><button type="button" class="btn-link icon" style="cursor: pointer;" aria-label="{{$edurl}}" title="{{$edurl}}" onclick="insertFormattingToPost('url');"><i class="fa fa-link"></i></button></li>
|
||||
<li role="presentation"><button type="button" class="btn-link" id="profile-attach" ondragenter="return linkDropper(event);" ondragover="return linkDropper(event);" ondrop="linkDrop(event);" onclick="jotGetLink();" title="{{$edattach}}"><i class="fa fa-paperclip"></i></button></li>
|
||||
<li role="presentation"><button type="button" class="btn-link" id="profile-location" onclick="jotGetLocation();" title="{{$setloc}}"><i class="fa fa-map-marker" aria-hidden="true"></i></button></li>
|
||||
|
|
@ -182,3 +183,16 @@ can load different content into the jot modal (e.g. the item edit jot)
|
|||
<script>
|
||||
dzFactory.setupDropzone('#jot-text-wrap', 'profile-jot-text');
|
||||
</script>
|
||||
<script>
|
||||
window.onload = function(){
|
||||
new EmojiPicker({
|
||||
trigger: [
|
||||
{
|
||||
selector: '.emojis',
|
||||
insertInto: '.profile-jot-text'
|
||||
}
|
||||
],
|
||||
closeButton: true,
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ body, section, blockquote, blockquote.shared_content, #profile-jot-form,
|
|||
}
|
||||
|
||||
#profile-jot-acl-wrapper, #event-notice, #event-wrapper,
|
||||
#cboxLoadedContent, .contact-photo-menu, #contact-edit-status-wrapper {
|
||||
.contact-photo-menu, #contact-edit-status-wrapper {
|
||||
background-color: #252C33 !important;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -227,8 +227,6 @@ aside.show {
|
|||
#profile-jot-acl-wrapper, #profile-jot-acl-wrapper * { box-sizing: border-box; }
|
||||
#acl-wrapper { width: 100%; float: none; }
|
||||
/* flexbox for ACL window */
|
||||
#cboxLoadedContent,
|
||||
#cboxLoadedContent > div,
|
||||
#acl-wrapper {
|
||||
display: -ms-Flexbox !important;
|
||||
-ms-box-orient: vertical;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue